Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 #ifndef PROGRAM_OPTIONS_VALUE_H_INCLUDED
00023 #define PROGRAM_OPTIONS_VALUE_H_INCLUDED
00024 #ifdef _MSC_VER
00025 #pragma warning (disable : 4786)
00026 #pragma warning (disable : 4503)
00027 #endif
00028 #include <string>
00029 #include <typeinfo>
00030 #include <cstddef>
00031 #if defined(_MSC_VER) && _MSC_VER <= 1200
00032 namespace std { using ::size_t; }
00033 #endif
00034 
00035 namespace ProgramOptions {
00036 
00037 
00038 enum DescriptionLevel {
00039         desc_level_default = 0, 
00040         desc_level_e1      = 1,
00041         desc_level_e2      = 2,
00042         desc_level_e3      = 3,
00043         desc_level_all     = 4,
00044         desc_level_hidden  = 5 
00045 };
00046 
00048 
00053 class Value {
00054 public:
00056         enum State { 
00057                 value_unassigned = 0, 
00058                 value_defaulted  = 1, 
00059                 value_fixed      = 2  
00060         };
00062         enum DescType {
00063                   desc_name    = 1
00064                 , desc_default = 2
00065                 , desc_implicit= 4
00066         };
00067         virtual ~Value();
00068 
00070         State state() const { return static_cast<State>(state_); }
00071         
00075         Value* state(Value::State s) {
00076                 state(true, s);
00077                 return this;
00078         }
00079 
00081 
00085         const char* arg()          const;
00086         Value*      arg(const char* n) { return desc(desc_name, n); }
00087 
00089         Value* alias(char c) { optAlias_ = c; return this; }
00090         char   alias() const { return optAlias_; }
00092 
00096         Value* level(DescriptionLevel lev) {
00097                 unsigned x = (lev * level_shift);
00098                 flags_     = static_cast<byte_t>(x | (flags_&(level_shift-1)));
00099                 return this;
00100         }
00102         DescriptionLevel level() const { return DescriptionLevel(flags_ / level_shift); }
00103 
00105 
00109         bool isNegatable() const { return hasProperty(property_negatable); }
00110         Value* negatable()       { setProperty(property_negatable); return this; }
00111 
00112         
00114 
00123         bool   isImplicit() const { return hasProperty(property_implicit); }
00124         
00126 
00132         bool isFlag() const { return hasProperty(property_flag); }
00133 
00138         Value* flag() { setProperty(property_flag); return this; }
00139 
00140         
00142         bool isComposing() const { return hasProperty(property_composing); }
00147         Value* composing() { setProperty(property_composing); return this; }
00148 
00152         Value* defaultsTo(const char* v){ return desc(desc_default, v); }
00154         const char* defaultsTo()  const { return desc(desc_default); }  
00161         Value* implicit(const char* str) { return desc(desc_implicit, str); }
00163         const char* implicit() const;
00164 
00166 
00177         bool parse(const std::string& name, const std::string& value, State st = value_fixed);
00178 protected:
00179         typedef unsigned char byte_t;
00180         enum Property {
00181                   property_implicit    = 1 
00182                 , property_flag        = 3 
00183           , property_composing   = 4 
00184                 , property_negatable   = 8 
00185                 , property_location    =16 
00186                 , not_a_property       =32
00187         };
00188         Value(byte_t flagSet, State initial = value_unassigned);
00189         void setProperty(Property f)     { flags_ |= byte_t(f); }
00190         void clearProperty(Property f)   { flags_ &= ~byte_t(f);}
00191         bool hasProperty(Property f)const{ return (flags_ & byte_t(f)) == f; }
00192         bool state(bool b, State s) { if (b) { state_ = static_cast<byte_t>(s); } return b; }
00193         virtual bool doParse(const std::string& name, const std::string& value) = 0;
00194         const char* desc(DescType t) const;
00195         Value*      desc(DescType t,  const char* d);
00196 private:
00197         enum { desc_pack    = 8, level_shift = not_a_property, levels = 255/level_shift };
00198         byte_t state_;       
00199         byte_t flags_;       
00200         byte_t descFlag_;    
00201         byte_t optAlias_;    
00202         union ValueDesc {    
00203                 const char*  value;
00204                 const char** pack; 
00205         }      desc_;         
00206 };
00207 }
00208 #endif