Actual source code: ALE_args.hh

petsc-3.3-p7 2013-05-11
  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
 79: 
 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