I'm trying to get boost::program_options to read a ini file with multiple sections:
[slave]
address=localhost
port=1111
[slave]
address=192.168.0.1
port=2222
Is there any solution?
Thanks in advance!
I'm trying to get boost::program_options to read a ini file with multiple sections:
[slave]
address=localhost
port=1111
[slave]
address=192.168.0.1
port=2222
Is there any solution?
Thanks in advance!
There are a few solutions to this problem. While it may initially appear that this should be an easy task, it is often fairly involved. This is because sections are roughly equivalent to namespaces; sections are not equivalent to objects.
The above configuration has a single
slave
namespace, that contains twoaddress
values and twoport
values. There are not twoslave
objects that each have anaddress
andport
. Due to this distinction, associating values, or pairing, must be done in the application code. This presenting the following options:Implied Pairing
With this approach, the configuration file can remain as-is. The simplicity of this approach depends on:
Without modifying the configuration, the following code:
Produces this output:
Basic Explicit Pairing
Multiple values can be occasionally be represented within a single field in a meaningful way. One common representation of both
address
andport
isaddress:port
. With this pairing, the resulting configuration file would like:This simplicity of this approach depends upon:
The updated code:
Produces the same output:
And the notable code modifications are as follows:
options_description
'soptions
need to be readingslaves.slave
as astd::vector< std::string >
.make_slave
will take a singlestd::string
argument, from which it will extractaddress
andport
.std::transform
call to only iterate over one range.Advanced Explicit Pairing
Often, multiple fields cannot be represented meaningfully as a single key-less value, or an object has optional fields. For these cases, an additional level of syntax and parsing needs to occur. While applications can introduce their own syntax and parsers, I suggest leveraging Boost.ProgramOption's command line syntax (
--key value
and--key=value
) and parsers. The resulting configuration file could look like:The updated code:
Produces the same output as the previous approaches:
And the notable code modifications are as follows:
copy_if
since it was an overlooked algorithm in C++03.option_builder
unary functor to help provide idiomatic reuse for applying transformations.make_slave
now takes aboost::program_options::variables_map
from which it will construct aslave
object.This approach can also easily be extended to support the following variations:
Supporting multiple command-lines for a single value. For example, a configuration could support two slaves, with one of the slaves having a secondary configuration in case the first fails. This requires performing an initial tokenization on the
,
delimiter.Declaring the options for
slave_desc
astyped_value
with variables provided to thestore_to
argument. These same variables can then be bound withboost::ref
viaboost::bind
to themake_slave
factory function. While this decouplesmake_slave
from Boost.ProgramOptions types, it may become difficult to maintain for types with many fields.Alternatives Approaches
Alternative approaches still need explicit pairing to be done via placing multiple values into a single value. However, transformations can occur during the parsing phase by inheriting from either
boost::program_options::typed_value
orboost::program_options::untyped_value
.typed_value
, override theparse
function. One consequence of usingtyped_value
is that the template parameter must meet all the requirements fortyped_value
. For example, iftyped_value< slave >
was used, then it would require makingslave
default constructable, and defining bothistream
extraction (>>
) andostream
insertion (<<
) operators forslave
.untyped_value
, override both theparse
andnotify
functions. This approach does not impose type requirements liketyped_value
, but it does require that the derived class maintain its ownstore_to
variable.Suggestions