Actual source code: ALE_args.hh
petsc-3.4.2 2013-07-02

      1: #ifndef included_ALE_args_hh
      2: #define included_ALE_args_hh
      3: // This should be included indirectly -- only by including ALE.hh

      5: #include <vector>
      6: #include <string>
      7: #include <boost/program_options.hpp>

     11: namespace ALE {
     12:   //
     13:   struct AnyArg {
     14:     typedef ::boost::program_options::value_semantic value_semantic;
     15:     typedef value_semantic*                          value_semantic_ptr;
     16:     // cast operator
     17:     virtual operator value_semantic_ptr() const = 0;
     18:     virtual ~AnyArg(){};
     19:   };
     20:   //
     21:   // Arg<T> is the type of object that can be added to ArgDB and
     22:   // ultimately holds an argument of type T.
     23:   //
     24:   template<typename T>
     25:   struct Arg : public AnyArg {
     26:     typedef typename AnyArg::value_semantic value_semantic;
     27:     typedef value_semantic*                 value_semantic_ptr;
     28:   protected:
     29:     ::boost::program_options::typed_value<T>* _dtor;
     30:   public:
     31:     Arg(T* storage = NULL) : _dtor(new ::boost::program_options::typed_value<T>(storage)){};
     32:     virtual ~Arg() {} // we do not delete _dtor since it's destroyed
     33:     //when the ::boost::program_options::options_description container is destroyed
     34:     //
     35:     // cast operator
     36:     virtual operator value_semantic_ptr() const {
     37:       return this->_dtor;
     38:     };
     39:     // forwarding methods
     40:     Arg& DEFAULT(const T& v) {
     41:       this->_dtor->default_value(v);
     42:       return *this;
     43:     };
     44:     Arg& IS_MULTIPLACED() {// may be defined in multiple places on the command line
     45:       this->_dtor->composing();
     46:       return *this;
     47:     };
     48:     Arg& IS_A_FLAG() { // no value expected
     49:       this->_dtor->zero_token();
     50:       return *this;
     51:     };
     52:     Arg& IS_A_LIST() {// multiple tokens per value
     53:       this->_dtor->multi_token();
     54:       return *this;
     55:     };
     56:   };// struct Arg
     57:   //
     58:   // The return type of ArgDB dereference:
     59:   //   ArgValue val = argDB["arg"];
     60:   // ArgValue val can be cast to the type compatible with Arg<T>,
     61:   // if the following description of "arg" was used:
     62:   //   argDB("arg", "arg help", Arg<T>);
     63:   //
     64:   struct ArgValue : ::boost::program_options::variable_value {
     65:     typedef ::boost::program_options::variable_value super;
     66:   public:
     67:     ArgValue(const super& val) : super(val) {};
     68:     // cast
     69:     template<typename T>
     70:     operator const T&() {
     71:       return super::as<T>();
     72:     }
     73:     //
     74:     template<typename T>
     75:     operator T& () {
     76:       return super::as<T>();
     77:     }
     78:   };// struct ArgValue

     80:     //
     81:   class ArgDB : public ::boost::program_options::variables_map {
     82:   protected:
     83:     typedef ::boost::program_options::variables_map super;
     84:     string _name;
     85:     ALE::Obj< ::boost::program_options::options_description> _descs;
     86:   public:
     87:     // Basic
     88:     ArgDB(const string& name)                        :
     89:       _name(name), _descs(new ::boost::program_options::options_description(name))
     90:     {};
     91:     //
     92:     ArgDB(const ArgDB& argDB, int argc, char **argv) :
     93:       _name(argDB.name()),_descs(new ::boost::program_options::options_description(_name))
     94:     {
     95:       (*this)(argDB);
     96:       this->parse(argc,argv);
     97:     };
     98:     // Printing
     99:     friend std::ostream& operator<<(std::ostream& os, const ArgDB& argDB) {
    100:       os << *(argDB._descs) << "\n";
    101:       return os;
    102:     }
    103:     // Main
    104:     //
    105:     ArgDB& operator()(const ArgDB& argDB) {
    106:       this->_descs->add(*(argDB._descs));
    107:       return *this;
    108:     };
    109:     //
    110:     ArgDB& operator()(const string& name, const string& helpLine) {
    111:       this->_descs->add_options()(name.c_str(), helpLine.c_str());
    112:       return *this;
    113:     };
    114:     ArgDB& operator()(const string& name, const string& helpLine, const AnyArg& descriptor) {
    115:       this->_descs->add_options()(name.c_str(), descriptor, helpLine.c_str());
    116:       return *this;
    117:     };
    118:     ArgDB& operator()(const string& name, const AnyArg& descriptor) {
    119:       this->_descs->add_options()(name.c_str(), descriptor);
    120:       return *this;
    121:     };
    122:     //
    123:     ArgDB& parse(int argc, char **argv) {
    124:       ::boost::program_options::basic_command_line_parser<char> parser(argc, argv);
    125: #if BOOST_VERSION >= 103300   // works beginning from Boost V1.33.0
    126:       parser.allow_unregistered().options(*(this->_descs));
    127: #endif
    128:       ::boost::program_options::store(parser.run(), *this);
    129:       return *this;
    130:     };
    131:     //
    132:     ArgValue operator[](const string& str) const {return super::operator[](str);};
    133:     //
    134:     // Aux
    135:     //
    136:     const string& name() const {return this->_name;};
    137:     //
    138:     ArgDB& rename(const string& name) {
    139:       this->_name = name;
    140:       Obj< ::boost::program_options::options_description> tmp = this->_descs;
    141:       this->_descs = new ::boost::program_options::options_description(name);
    142:       this->_descs->add(tmp);
    143:       return *this;
    144:     };
    145:   };// class ArgDB

    147: } // namespace ALE

    150: #endif