program_options: iterate variable_map
Hello! I'm looking for a way to "iterate" through a variable_map after the command line options were stored, in order to print out all the options, or all with newly values. I know that you can test if a specific options was read with the "count()" method, but this is cumbersome. Is there a possiblity to do that? Regards, Stephan.
Stephan Stiglmayr wrote:
Hello!
I'm looking for a way to "iterate" through a variable_map after the command line options were stored, in order to print out all the options, or all with newly values.
Me too!!
I know that you can test if a specific options was read with the "count()" method, but this is cumbersome.
Yes!!!
Is there a possiblity to do that?
I wrote a wrapper class that adds options to a list as they are added to program_options, then you can print the list. This is a hack.
Regards, Stephan.
On Wed, 5 Apr 2006, Andrew Schweitzer wrote:
Stephan Stiglmayr wrote:
I'm looking for a way to "iterate" through a variable_map after the command line options were stored, in order to print out all the options, or all with newly values.
[...]
I know that you can test if a specific options was read with the "count()" method, but this is cumbersome. [...] Is there a possiblity to do that?
I wrote a wrapper class that adds options to a list as they are added to program_options, then you can print the list. This is a hack.
Also, another 'hack' is that, looking in the code, you can notice that variables_map inherits from std::map as well (though it's not documented as such). You can thus use standard STL iterators, e.g. for ( variables_map::iterator i = vm.begin() ; i != vm.end() ; ++ i ) { //... } The type of values iterated over are pairs of std::string and boost::program_options::variable_value. -- François Duranleau LIGUM, Université de Montréal "You only think you understand. But people cannot perfectly understand each other. The self is an ambiguous thing." - Kaji, in _Neon Genesis Evangelion_
François Duranleau wrote:
On Wed, 5 Apr 2006, Andrew Schweitzer wrote:
Also, another 'hack' is that, looking in the code, you can notice that variables_map inherits from std::map as well (though it's not documented as such). You can thus use standard STL iterators, e.g.
for ( variables_map::iterator i = vm.begin() ; i != vm.end() ; ++ i ) { //... }
The type of values iterated over are pairs of std::string and boost::program_options::variable_value.
I tried that... but the map is filled with "any" values. You can dump the argument names, but I don't see a way to dump their values in a for-loop. Is there a way?
------------------------------------------------------------------------
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
On Sat, 22 Apr 2006, Andrew Schweitzer wrote:
François Duranleau wrote:
for ( variables_map::iterator i = vm.begin() ; i != vm.end() ; ++ i ) { //... }
I tried that... but the map is filled with "any" values. You can dump the argument names, but I don't see a way to dump their values in a for-loop. Is there a way?
Use .as<> based on typeid? e.g. for ( variables_map::iterator i = vm.begin() ; i != vm.end() ; ++ i ) { const variable_value& v = i->second ; if ( ! v.empty() ) { const ::std::type_info& type = v.value().type() ; if ( type == typeid( ::std::string ) ) { const ::std::string& val = v.as< ::std::string >() ; // ... } else if ( type == typeid( int ) ) { int val = v.as< int >() ; // ... } // etc. } } Or you could create a map of actions to do with a given type, e.g. struct type_info_compare { bool operator () ( const ::std::type_info* lhs , const ::std::type_info* rhs ) const { return lhs->before( * rhs ) ; } } ; ::std::map< const ::std::type_info* , ::boost::function< void ( const variable_value& ) > , type_info_compare > action_map ; The map you could be built with something like this (a simple output example): template < typename T > struct output_value { void operator () ( const variable_value& v ) const { ::std::cout << v.as< T >() << ::std::endl ; } } ; //... action_map[ & typeid( ::std::string ) ] = output_value< ::std::string >() ; action_map[ & typeid( int ) ] = output_value< int >() ; // etc. And then: for ( variables_map::iterator i = vm.begin() ; i != vm.end() ; ++ i ) { const variable_value& v = i->second ; if ( ! v.empty() ) { ::std::cout << i->first << "=" ; action_map[ & v.value().type() ]( v ) ; } } This makes the iteration cleaner, but you need to build the map, which, depending on what you want to do, may be easier/cleaner or not than a big sequence of if/else as my first example in the for loop. Most probably there are even better solutions than that. Anybody else has an idea? -- François Duranleau LIGUM, Université de Montréal "Le manque de culture générale est une source de grands désastres. [...] On constate de façon continue de véritables désastres qui ne sont causés que par une méconnaissance absolue du passé et de l'histoire." - Bertrand Tavernier
Fran?ois Duranleau wrote:
I wrote a wrapper class that adds options to a list as they are added to program_options, then you can print the list. This is a hack.
Also, another 'hack' is that, looking in the code, you can notice that variables_map inherits from std::map as well (though it's not documented as such). You can thus use standard STL iterators, e.g.
for ( variables_map::iterator i = vm.begin() ; i != vm.end() ; ++ i ) { //... }
The type of values iterated over are pairs of std::string and boost::program_options::variable_value.
I have no idea why BoostBook decided to hide that inheritance, but it was designed that way, so that you can iterate variables_map. I've added comment to that effect to varaibles_map class docs. - Volodya
Vladimir Prus wrote:
Fran?ois Duranleau wrote:
variables_map inherits from std::map as well (though it's not documented as such).
The type of values iterated over are pairs of std::string and boost::program_options::variable_value.
I have no idea why BoostBook decided to hide that inheritance, but it was designed that way, so that you can iterate variables_map. I've added comment to that effect to varaibles_map class docs.
- Volodya
Is there a way to extract the "original" string from variable_value? By this I mean the one taken from command line or ini file before conversion to int, float etc...? I suppose for vectors this would be impossible - you would need a vector of "original" strings. But this would at least cut the cases down. Is it possible to as a variable it holds a single or multiple values? Thanks, Andy
Andrew Schweitzer wrote:
Vladimir Prus wrote:
Fran?ois Duranleau wrote:
variables_map inherits from std::map as well (though it's not documented as such).
The type of values iterated over are pairs of std::string and boost::program_options::variable_value.
I have no idea why BoostBook decided to hide that inheritance, but it was designed that way, so that you can iterate variables_map. I've added comment to that effect to varaibles_map class docs.
- Volodya
Is there a way to extract the "original" string from variable_value? By this I mean the one taken from command line or ini file before conversion to int, float etc...? I suppose for vectors this would be impossible - you would need a vector of "original" strings. But this would at least cut the cases down. Is it possible to as a variable it holds a single or multiple values?
No, it's not possible, partly due to issues with vectors, and partly because I did not though this will be requested. The best you can now is: parsed_options opts = parse_command_line(......); store(opts, vm); And then iterate over opts.options. Each element has type 'option' which in turn has member 'original_tokens'. - Volodya
Vladimir Prus wrote:
Andrew Schweitzer wrote:
The best you can now is:
parsed_options opts = parse_command_line(......); store(opts, vm);
And then iterate over opts.options. Each element has type 'option' which in turn has member 'original_tokens'.
- Volodya
Thanks! That works pretty well. Here's the code I tried: typedef std::vector< basic_option<char> > vec_opt; cout << "Parsed command line options (from parsed_options):" << endl; for(vec_opt::iterator l_itrOpt = l_parsed.options.begin(); l_itrOpt != l_parsed.options.end(); ++l_itrOpt) { basic_option<char>& l_option = *l_itrOpt; cout << "\t" << l_option.string_key << ": "; typedef std::vector< std::basic_string<char> > vec_string; for(vec_string::iterator l_itrString = l_option.value.begin(); l_itrString != l_option.value.end(); ++l_itrString) { cout << *l_itrString; } cout << endl; }
participants (4)
-
Andrew Schweitzer
-
François Duranleau
-
Stephan Stiglmayr
-
Vladimir Prus