Hello,
I'm using program_options, and I want to be able to learn what the option type
is by manipulating an options_description object. As I illustrate in the example
below (boost 1.33), I can do this if the option has been given a default value.
Could anyone suggest a wasy to this for options without a default?
The story behind this question is that I would like to be able to build a simple
GUI parameter dialog based on the options_description, and I want to map
different types to different widgets.
Thanks, Giuseppe
#include
#include
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <iterator>
template<typename T> bool type_is (const boost::any & v) {
return v.type() == typeid(T);
}
struct MyType {
MyType() : x(0) {}
MyType(double d) : x(d) {}
double x;
};
std::ostream & operator<<(std::ostream & os, const MyType & mt) {
os << mt.x;
return os;
}
std::istream & operator>>(std::istream & is, MyType & mt) {
is >> mt.x;
return is;
}
using namespace std;
namespace po = boost::program_options;
int main(int ac, char * av[]) {
typedef vector<string> type;
po::options_description desc1("Allowed options 1");
desc1.add_options()
("switch", po::value<bool>(), " a boolean switch")
("numbers", po::value<type>(), "a list of numbers")
("number", po::value<double>()->default_value(42), "the number")
;
po::options_description desc2("Allowed options 2");
desc2.add_options()
("mytype", po::value<MyType>()->default_value(MyType(123.4)), "my type")
;
po::options_description cmdlinedesc;
cmdlinedesc.add(desc1).add(desc2);
po::variables_map vm;
po::store(po::parse_command_line(ac, av, cmdlinedesc), vm);
po::notify(vm);
typedef std::vector< boost::shared_ptrpo::option_description > VOD;
const VOD & pk = cmdlinedesc.options();
for(VOD::const_iterator K = pk.begin(); K != pk.end(); ++K){
cout << " [ " << (*K)->long_name() << " - " << (*K)->description() << " ] ";
boost::shared_ptr< const po::value_semantic > sem = (*K)->semantic();
boost::any default_store;
bool has_default = sem->apply_default(default_store);
if(has_default)
cout << " has default ";
if(type_is<double>(default_store))
cout << " = (double) " << boost::any_cast<double>(default_store);
if(type_is<bool>(default_store))
cout << " = (bool) " << boost::any_cast<bool>(default_store);
if(type_is<MyType>(default_store)){
MyType x = boost::any_cast<MyType>(default_store);
cout << " = (MyType) " << x;
}
cout << endl;
}
}