Flow 1.0.0
Flow project: Public API.
Namespaces | Classes | Enumerations | Functions
flow::cfg Namespace Reference

Flow module that facilitates configuring modules, such as applications and APIs, via statically and/or dynamically parsed sets of name/value pairs from config sources like files and command lines. More...

Namespaces

namespace  fs
 Short-hand for namespace boost::filesystem.
 
namespace  opts
 Short-hand for namespace boost::program_options.
 

Classes

class  Config_manager
 Manages a config setup, intended for a single daemon process, by maintaining 1 or more set(s) of static config and dynamic config, each, via that number of Option_set<>-ready raw value struct types supplied by the user as template arguments. More...
 
class  Dynamic_cfg_context
 Class which facilitates managing access to a dynamic configuration. More...
 
struct  Final_validator_func
 Utility/traits type to concisely work with final-validation functions when calling methods like Config_manager::apply_static(). More...
 
struct  Null_value_set
 Empty struct suitable as a *_value_set template arg for Config_manager, when a slot requires a Value_set, but you have no config to actually parse there. More...
 
class  Option_set
 The core config-parsing facility, which builds parsing/comparison/output capabilities on top of a given simple config-holding object, of the type Value_set, a template argument to this class template. More...
 
class  Option_set_base
 Un-templated base for Option_set. More...
 
class  Static_config_manager
 A Config_manager-related adapter-style class that manages a simple config setup involving a single (though arbitrarily complex) Option_set<>-ready raw value struct config store type Value_set, meant to be used only in static fashion. More...
 

Enumerations

enum class  Final_validator_outcome { S_ACCEPT , S_SKIP , S_FAIL }
 Result enumeration for a Final_validator_func::Type function which is used by a Config_manager user when parsing a config source (ex: file). More...
 

Functions

template<typename Value_set >
std::ostream & operator<< (std::ostream &os, const Option_set< Value_set > &val)
 Serializes (briefly) an Option_set to a standard output stream. More...
 
std::string value_set_member_id_to_opt_name (util::String_view member_id)
 Utility, used by FLOW_CFG_OPTION_SET_DECLARE_OPTION() internally but made available as a public API in case it is useful, that converts a string containing a conventionally formatted data member name into the corresponding auto-determined config option name. More...
 
template<typename Key >
std::string value_set_member_id_to_opt_name_keyed (util::String_view member_id, const Key &key)
 Similar to value_set_member_id_to_opt_name() but used by FLOW_CFG_OPTION_SET_DECLARE_OPTION_KEYED() internally (also made available as a public API in case it is useful), that does the job of value_set_member_id_to_opt_name() in addition to substituting the last [...] fragment with a dot separator, followed by the ostream encoding of key. More...
 
template<typename Value >
void value_to_ostream (std::ostream &os, const Value &val)
 Serializes a value of type Value to the given ostream suitably for output in Option_set-related output to user such as in help messages. More...
 
template<typename Rep , typename Period >
void value_to_ostream (std::ostream &os, const boost::chrono::duration< Rep, Period > &val)
 Overload that serializes a value of chrono-based duration including Fine_duration – which is recommended to use for Option_set-configured time durations – to the given ostream suitably for output in Option_set-related output to user such as in help messages. More...
 
template<typename Element >
void value_to_ostream (std::ostream &os, const std::vector< Element > &val)
 Overload that serializes a list value (with Element type itself similarly serializable) to the given ostream suitably for output in Option_set-related output to user such as in help messages. More...
 
Option_set< Null_value_set >::Declare_options_func null_declare_opts_func ()
 Returns a value usable as declare_opts_func_moved Config_manager ctor arg for a Null_value_set value set. More...
 
Final_validator_func< Null_value_set >::Type null_final_validator_func ()
 Returns a value usable as final_validator_func arg to Config_manager::apply_static() and others – for a Null_value_set value set. More...
 
template<typename... S_d_value_set>
std::ostream & operator<< (std::ostream &os, const Config_manager< S_d_value_set... > &val)
 Serializes (briefly) a Config_manager to a standard output stream. More...
 
template<typename Value_set >
std::ostream & operator<< (std::ostream &os, const Static_config_manager< Value_set > &val)
 Serializes (briefly) a Static_config_manager to a standard output stream. More...
 

Detailed Description

Flow module that facilitates configuring modules, such as applications and APIs, via statically and/or dynamically parsed sets of name/value pairs from config sources like files and command lines.

(It is also possible to use a subset of the provided features to simplify option-related tasks even without parsing them from a file/etc.)

Main concepts: your Value_sets and flow::cfg::Option_set

"Configuration" has lots of possible meanings, and flow::cfg certainly doesn't cover any huge range of what could be called configuration. Instead it is focused on a fairly common basic object type: a straightforward struct of essentially scalar values. (Composition/nested structs are also supported, but don't worry about it yet.) Such structs are often passed around larger programs and used to configure various modules. It is typically a given that each type V for a data member in such a struct:

It is also reasonable that each member has some default value, set in the struct no-args ctor, so that the full set of values in a default-cted instance of the struct represents a reasonable overall config for the corresponding module.

It is also often desirable to print dumps of the current contents of such a struct. In that case we add the requirement on each type V:

Often (though not always) one needs to parse into the member of this struct, from a stream/file or perhaps command line (one or more config sources). If this is indeed required then add the requirement on each V:

Sometimes such a struct is essentially static, meaning once the values are filled out (manually, or from a config source), they shouldn't change. More rarely they are dynamic, meaning values can change from time to time, particularly on outside events like a SIGHUP triggering reading values from a file. In the latter case it is typical to wrap them in shared_ptrs; then a piece of code can save a copy of such a handle to an immutable instance of the struct, wherein it can rely on a consistent set of config, even while dynamic config updates will cause more such instances to be generated over time. Hence add this requirement on the struct itself:

Call the struct type satisfying the above requirements Value_set. All facilities dealing with such value sets are templates parameterized on Value_set. Generally speaking it is straightforward to satisfy these requirements; for example they hold for ~all built-in scalar types, plus chrono::duration, std::string, and many more oft-used types; and deriving from Shared_ptr_alias_holder is just a line or two.

Maintaining a Value_set like that is straighforward, but the things one wants to do with with an entire Value_set – as opposed to individual members in it – tend to be laborious, anti-consistent, and error-prone to do. To wit:

Just about the only thing that is easy is simply accessing the values in a Value_set. Indeed, this is the one "feature" built-into Value_set that we want to leave available at all costs; it is concise, compile-time-checked, and fast (all of which is less true or untrue of, say, a map<string, boost::any> and similar solutions).

The main value of flow::cfg, as of this writing, is the Option_set class template. Option_set<Value_set> adds concise ways of doing all of the above in a streamlined way. Even if you need not actually parse your Value_set from a file, it still lets you concisely output, compare, validate the Value_sets themselves.

Therefore see Option_set doc header. Do realize that it is expected to be common-place to have multiple Value_set types – and therefore separate Option_set<> instances for each. A server program, for example, might start with just a Static_value_set for initial, immutable config; and later add a Dynamic_value_set for settings that can change since startup. Flow itself has flow::net_flow, wherein (e.g.) net_flow::Peer_socket has a set of socket options, some static and some dynamically changeable once a connection is open; hence it might have a struct for dynamic socket options and another for static.

Config_manager

An Option_set is designed to be used in flexible combination with other Option_sets. The variations on how one might use them are equally as unpredictable and varied as how one might use Value_set-type structs.

Config_manager is an optional feature built on a couple of Option_sets, one for dynamic and one for static config. It exists to provide a simple but often-sufficient config manager for use by a server process. Create one of these, fill out your process's overall static and dynamic config structs, and you should be able to have a working config system with minimal boiler-plate, based on a static config file and command line; and a separate dynamic config file (with the optional ability to set initial dynamic setting values from the static config sources).

If Config_manager is insufficient, one can build their own system on top of Option_set.

See also
Option_set class template, the main feature of flow::cfg.

Enumeration Type Documentation

◆ Final_validator_outcome

Result enumeration for a Final_validator_func::Type function which is used by a Config_manager user when parsing a config source (ex: file).

In short such a function can consider the file as one to skip entirely, as okay to accept, or as erroneous.

Enumerator
S_ACCEPT 

The holistically-checked cumulative Value_set has no problems and shall be accepted into the candidate Value_set; if this is the final config-source (ex: file), that candidate shall be canonicalized.

apply_*() shall return true (success).

S_SKIP 

The holistically-checked cumulative Value_set has contents such that the validator function decided that the current apply_*() shall have no effect, meaning the Value_set candidate shall remain unchanged from just-before that current apply_*(); if this is the final config-source (ex: file), that unchanged candidate shall be canonicalized.

apply_*() shall return true (success).

S_SKIP shall also have this effect on all subsequently scanned Value_sets in the same apply_static(), apply_dynamic(), or apply_static_and_dynamic() call; that is to say one SKIPped Value_set causes all subsequent ones to behave as-if they too were SKIPped.

S_FAIL 

The holistically-checked cumulative Value_set has invalid contents; the candidate shall be rejected, and apply_*() shall return false (failure).

Function Documentation

◆ null_declare_opts_func()

Option_set< Null_value_set >::Declare_options_func flow::cfg::null_declare_opts_func ( )

Returns a value usable as declare_opts_func_moved Config_manager ctor arg for a Null_value_set value set.

Naturally it does nothing.

Returns
See above.

◆ null_final_validator_func()

Final_validator_func< Null_value_set >::Type flow::cfg::null_final_validator_func ( )

Returns a value usable as final_validator_func arg to Config_manager::apply_static() and others – for a Null_value_set value set.

Returns
See above.

◆ operator<<() [1/3]

template<typename... S_d_value_set>
std::ostream & operator<< ( std::ostream &  os,
const Config_manager< S_d_value_set... > &  val 
)

Serializes (briefly) a Config_manager to a standard output stream.

Template Parameters
S_d_value_setSee Config_manager doc header.
Parameters
osStream to which to serialize.
valValue to serialize.
Returns
os.

◆ operator<<() [2/3]

template<typename Value_set >
std::ostream & flow::cfg::operator<< ( std::ostream &  os,
const Option_set< Value_set > &  val 
)

Serializes (briefly) an Option_set to a standard output stream.

Template Parameters
Value_setSee Option_set doc header.
Parameters
osStream to which to serialize.
valValue to serialize.
Returns
os.

◆ operator<<() [3/3]

template<typename Value_set >
std::ostream & flow::cfg::operator<< ( std::ostream &  os,
const Static_config_manager< Value_set > &  val 
)

Serializes (briefly) a Static_config_manager to a standard output stream.

Template Parameters
Value_setSee Static_config_manager doc header.
Parameters
osStream to which to serialize.
valValue to serialize.
Returns
os.

◆ value_set_member_id_to_opt_name()

std::string flow::cfg::value_set_member_id_to_opt_name ( util::String_view  member_id)

Utility, used by FLOW_CFG_OPTION_SET_DECLARE_OPTION() internally but made available as a public API in case it is useful, that converts a string containing a conventionally formatted data member name into the corresponding auto-determined config option name.

Note
An example for convenience, accurate as of the time of this writing: m_cool_object.m_cool_sub_object->m_badass_sub_guy.m_cool_option_name transforms to cool-object.cool-sub-object.badass-sub-guy.cool-option-name.

The format for the contents of member_id shall be as follows: It shall consist of one or more identifiers following the Flow coding guide, each starting with m_, concatenated with C++ object separator sequences, each sequence chosen to be either . (object dereference) or -> (pointer dereference). m_ for each identifier is optional for this function – though the coding guide requires it as of this writing anyway.

Note that boost.program_options allows config files (when used as config sources, e.g, Option_set::parse_config_file()) to declare a [config-section] which results in each option-name listed in that section to be treated as-if named config-section.option-name. This has synergy with nested objects within a config value set being separated by dots also (or -> if desired for orthogonal reasons, such as if a smart pointer is used).

Parameters
member_idIdentifier, perhaps obtained via the preprocessor #feature from an argument to a functional macro.
Returns
See above.

◆ value_set_member_id_to_opt_name_keyed()

template<typename Key >
std::string flow::cfg::value_set_member_id_to_opt_name_keyed ( util::String_view  member_id,
const Key &  key 
)

Similar to value_set_member_id_to_opt_name() but used by FLOW_CFG_OPTION_SET_DECLARE_OPTION_KEYED() internally (also made available as a public API in case it is useful), that does the job of value_set_member_id_to_opt_name() in addition to substituting the last [...] fragment with a dot separator, followed by the ostream encoding of key.

Note
An example for convenience, accurate as of the time of this writing: m_cool_object.m_cool_sub_object->m_badass_sub_guy[cool_key].m_cool_option_name, with cool_key == 3, transforms to cool-object.cool-sub-object.badass-sub-guy.3.cool-option-name.

Behavior is undefined if the [...] part doesn't exist or is preceded or succeeded by nothing. In reality for things to work as expected that part should also be followed by a C++ object separator as in value_set_member_id_to_opt_name() doc header; so, e.g., m_blah[idx]->m_blah or m_blah[idx].m_blah.

Template Parameters
KeyAn ostream<<able type. Common: size_t and std::string.
Parameters
member_idIdentifier, perhaps obtained via the preprocessor # feature from an argument to a functional macro.
keyThe value to splice in when replacing the key fragment inside [] (after the inserted .).
Returns
See above.

◆ value_to_ostream() [1/3]

template<typename Rep , typename Period >
void flow::cfg::value_to_ostream ( std::ostream &  os,
const boost::chrono::duration< Rep, Period > &  val 
)

Overload that serializes a value of chrono-based duration including Fine_duration – which is recommended to use for Option_set-configured time durations – to the given ostream suitably for output in Option_set-related output to user such as in help messages.

As of this writing it improves upon the default ostream<< behavior by converting to coarser units without losing precision (e.g., not "9000000000 ns" but "9 s").

Template Parameters
RepSee chrono::duration.
PeriodSee chrono::duration.
Parameters
osStream to which to serialize.
valValue to serialize.

◆ value_to_ostream() [2/3]

template<typename Element >
void flow::cfg::value_to_ostream ( std::ostream &  os,
const std::vector< Element > &  val 
)

Overload that serializes a list value (with Element type itself similarly serializable) to the given ostream suitably for output in Option_set-related output to user such as in help messages.

Template Parameters
ElementAny type for which value_to_ostream(Element_type) is available; but as of this writing it cannot itself be std::vector<> (no lists of lists).
Parameters
osStream to which to serialize.
valValue to serialize.

◆ value_to_ostream() [3/3]

template<typename Value >
void flow::cfg::value_to_ostream ( std::ostream &  os,
const Value &  val 
)

Serializes a value of type Value to the given ostream suitably for output in Option_set-related output to user such as in help messages.

The generic version simply forwards to ostream<< operator; but specializations/overloads can massage/customize the output more suitably for usability. The user may provide their own specializations or overload on top of any already provided.

See also
E.g.: the Value = chrono::duration overload.
Template Parameters
ValueType of val. For this generic implementation ostream << Value operator must exist.
Parameters
osStream to which to serialize.
valValue to serialize.