Boost logo

Boost Users :

From: Giuseppe Vacanti (gvacanti_at_[hidden])
Date: 2005-11-10 11:38:55


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 <boost/program_options.hpp>
#include <boost/filesystem/path.hpp>

#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_ptr<po::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;
    
  }

}


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net