| Flow 1.0.2
    Flow project: Public API. | 
We may add some ADL-based overloads into this namespace outside flow.  
More...
| Functions | |
| void | validate (boost::any &target, const std::vector< std::string > &user_values, path *, int) | 
| ADL-based overload of boost.program_options validate()to allow for emptyboost::filesystem::pathvalues in flow::cfg config parsing as well as any other boost.program_options parsing in the application.  More... | |
We may add some ADL-based overloads into this namespace outside flow. 
| void boost::filesystem::validate | ( | boost::any & | target, | 
| const std::vector< std::string > & | user_values, | ||
| path * | , | ||
| int | |||
| ) | 
ADL-based overload of boost.program_options validate() to allow for empty boost::filesystem::path values in flow::cfg config parsing as well as any other boost.program_options parsing in the application. 
Likely there's no need to call this directly: it is invoked by boost.program_options when parsing paths.
More precisely: This has ~two effects:
Option_set) will successfully parse an empty (or all-spaces) value for a setting of type boost::filesystem::path, resulting in a path equal to a default-constructed path().path will now also allow an empty value (on command line, in file, etc.) in the same application.Allowing empty paths in flow::cfg is required for usability. It was a common use case to allow for a blank special value for path settings. However trying to in fact provide an empty value in a flow::cfg file (e.g., simply log-file=) resulted in an "Invalid argument" error message and refusal of flow::cfg::Option_set::parse_config_file() to successfully parse.
(The following discussion is about implementation details and would normally be omitted from this public-facing API doc header. However, in this slightly unusual (for Flow) situation the solution happens to subtly affect code outside of flow::cfg. Therefore it is appropriate to discuss these internals here.)
The reason for this problem: flow::cfg uses boost.program_options for config source (especially file) parsing. By default, when parsing a string into the proper type T (here T being path), boost.program_options uses istream >> T overload. Turns out that reading a blank from a stream into path causes the istream bad-bit to set, meaning lexical_cast throws bad_lexical_cast; boost.program_options then manifests this as an arg parse error. (If T were std::string, by contrast, no such problem would occur: istream >> string will happily accept a blank string.)
boost.program_options clearly suggests the proper way to custom-parse types at https://www.boost.org/doc/libs/1_78_0/doc/html/program_options/howto.html#id-1.3.32.6.7 – namely, define a validate() overload in the same namespace as type T, with a T-typed arg. ADL (argument-dependent lookup) will then use that overload – instead of the default one, which simply invokes lexical_cast (i.e., istream>>) – and reports an error if that throws. This is the same technique used to conveniently select hash_value() for unordered_*; swap() for STL containers; etc.
This solves the problem. However, somewhat unusually, this imposes the same more-permissive semantics on all other uses of boost.program_options in any application linking Flow (which includes this overload). This is arguably not-great; ideally we'd affect flow::cfg and nothing else. That said (1) there's no apparent alternative in boost.program_options; and more to the point (2) this feels like either an improvement or neutral. If an empty path must be disallowed, this can be done via notifier() (or just a manual check). So, all in all, this seemed fine.
| target | targetshall be loaded with thepathon success. Otherwise we shall throw, per required boost.program_options semantics. | 
| user_values | The (trimmed) raw strings from the user for this occurrence of the setting. In our case there must be only one, since a pathhas only one value. |