Flow 1.0.0
Flow project: Public API.
|
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... | |
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.)
Value_set
s 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 struct
s are also supported, but don't worry about it yet.) Such struct
s 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
:
==
in a reasonable way.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:
ostream
output <<
operator.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:
istream
input >>
operator.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_ptr
s; 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:
Ptr
and Const_ptr
aliases (to shared_ptr<>
).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:
ostream<<
logic);==
(tediously list ==
checks for each member);if
statements and even more tedious stream output.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_set
s 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.
An Option_set is designed to be used in flexible combination with other Option_set
s. The variations on how one might use them are equally as unpredictable and varied as how one might use Value_set
-type struct
s.
Config_manager is an optional feature built on a couple of Option_set
s, 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 struct
s, 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.
|
strong |
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.
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.
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.
std::ostream & operator<< | ( | std::ostream & | os, |
const Config_manager< S_d_value_set... > & | val | ||
) |
Serializes (briefly) a Config_manager to a standard output stream.
S_d_value_set | See Config_manager doc header. |
os | Stream to which to serialize. |
val | Value to serialize. |
os
. std::ostream & flow::cfg::operator<< | ( | std::ostream & | os, |
const Option_set< Value_set > & | val | ||
) |
Serializes (briefly) an Option_set to a standard output stream.
Value_set | See Option_set doc header. |
os | Stream to which to serialize. |
val | Value to serialize. |
os
. 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.
Value_set | See Static_config_manager doc header. |
os | Stream to which to serialize. |
val | Value to serialize. |
os
. 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.
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).
member_id | Identifier, perhaps obtained via the preprocessor #feature from an argument to a functional macro. |
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
.
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
.
Key | An ostream<< able type. Common: size_t and std::string . |
member_id | Identifier, perhaps obtained via the preprocessor # feature from an argument to a functional macro. |
key | The value to splice in when replacing the key fragment inside [] (after the inserted . ). |
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"
).
Rep | See chrono::duration . |
Period | See chrono::duration . |
os | Stream to which to serialize. |
val | Value to serialize. |
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.
Element | Any 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). |
os | Stream to which to serialize. |
val | Value to serialize. |
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.
Value = chrono::duration
overload. Value | Type of val . For this generic implementation ostream << Value operator must exist. |
os | Stream to which to serialize. |
val | Value to serialize. |