1 // Copyright Vladimir Prus 2002-2004. 2 // Distributed under the Boost Software License, Version 1.0. 3 // (See accompanying file LICENSE_1_0.txt 4 // or copy at http://www.boost.org/LICENSE_1_0.txt) 5 6 7 #ifndef BOOST_VARIABLES_MAP_VP_2003_05_19 8 #define BOOST_VARIABLES_MAP_VP_2003_05_19 9 10 #include <boost/program_options/config.hpp> 11 12 #include <boost/any.hpp> 13 #include <boost/shared_ptr.hpp> 14 15 #include <string> 16 #include <map> 17 #include <set> 18 19 #if defined(BOOST_MSVC) 20 # pragma warning (push) 21 # pragma warning (disable:4251) // 'boost::program_options::variable_value::v' : class 'boost::any' needs to have dll-interface to be used by clients of class 'boost::program_options::variable_value 22 #endif 23 24 namespace boost { namespace program_options { 25 26 template<class charT> 27 class basic_parsed_options; 28 29 class value_semantic; 30 class variables_map; 31 32 // forward declaration 33 34 /** Stores in 'm' all options that are defined in 'options'. 35 If 'm' already has a non-defaulted value of an option, that value 36 is not changed, even if 'options' specify some value. 37 */ 38 BOOST_PROGRAM_OPTIONS_DECL 39 void store(const basic_parsed_options<char>& options, variables_map& m, 40 bool utf8 = false); 41 42 /** Stores in 'm' all options that are defined in 'options'. 43 If 'm' already has a non-defaulted value of an option, that value 44 is not changed, even if 'options' specify some value. 45 This is wide character variant. 46 */ 47 BOOST_PROGRAM_OPTIONS_DECL 48 void store(const basic_parsed_options<wchar_t>& options, 49 variables_map& m); 50 51 52 /** Runs all 'notify' function for options in 'm'. */ 53 BOOST_PROGRAM_OPTIONS_DECL void notify(variables_map& m); 54 55 /** Class holding value of option. Contains details about how the 56 value is set and allows to conveniently obtain the value. 57 */ 58 class BOOST_PROGRAM_OPTIONS_DECL variable_value { 59 public: variable_value()60 variable_value() : m_defaulted(false) {} variable_value(const boost::any & xv,bool xdefaulted)61 variable_value(const boost::any& xv, bool xdefaulted) 62 : v(xv), m_defaulted(xdefaulted) 63 {} 64 65 /** If stored value if of type T, returns that value. Otherwise, 66 throws boost::bad_any_cast exception. */ 67 template<class T> as() const68 const T& as() const { 69 return boost::any_cast<const T&>(v); 70 } 71 /** @overload */ 72 template<class T> as()73 T& as() { 74 return boost::any_cast<T&>(v); 75 } 76 77 /// Returns true if no value is stored. 78 bool empty() const; 79 /** Returns true if the value was not explicitly 80 given, but has default value. */ 81 bool defaulted() const; 82 /** Returns the contained value. */ 83 const boost::any& value() const; 84 85 /** Returns the contained value. */ 86 boost::any& value(); 87 private: 88 boost::any v; 89 bool m_defaulted; 90 // Internal reference to value semantic. We need to run 91 // notifications when *final* values of options are known, and 92 // they are known only after all sources are stored. By that 93 // time options_description for the first source might not 94 // be easily accessible, so we need to store semantic here. 95 shared_ptr<const value_semantic> m_value_semantic; 96 97 friend BOOST_PROGRAM_OPTIONS_DECL 98 void store(const basic_parsed_options<char>& options, 99 variables_map& m, bool); 100 101 friend class BOOST_PROGRAM_OPTIONS_DECL variables_map; 102 }; 103 104 /** Implements string->string mapping with convenient value casting 105 facilities. */ 106 class BOOST_PROGRAM_OPTIONS_DECL abstract_variables_map { 107 public: 108 abstract_variables_map(); 109 abstract_variables_map(const abstract_variables_map* next); 110 ~abstract_variables_map()111 virtual ~abstract_variables_map() {} 112 113 /** Obtains the value of variable 'name', from *this and 114 possibly from the chain of variable maps. 115 116 - if there's no value in *this. 117 - if there's next variable map, returns value from it 118 - otherwise, returns empty value 119 120 - if there's defaulted value 121 - if there's next variable map, which has a non-defaulted 122 value, return that 123 - otherwise, return value from *this 124 125 - if there's a non-defaulted value, returns it. 126 */ 127 const variable_value& operator[](const std::string& name) const; 128 129 /** Sets next variable map, which will be used to find 130 variables not found in *this. */ 131 void next(abstract_variables_map* next); 132 133 private: 134 /** Returns value of variable 'name' stored in *this, or 135 empty value otherwise. */ 136 virtual const variable_value& get(const std::string& name) const = 0; 137 138 const abstract_variables_map* m_next; 139 }; 140 141 /** Concrete variables map which store variables in real map. 142 143 This class is derived from std::map<std::string, variable_value>, 144 so you can use all map operators to examine its content. 145 */ 146 class BOOST_PROGRAM_OPTIONS_DECL variables_map : public abstract_variables_map, 147 public std::map<std::string, variable_value> 148 { 149 public: 150 variables_map(); 151 variables_map(const abstract_variables_map* next); 152 153 // Resolve conflict between inherited operators. operator [](const std::string & name) const154 const variable_value& operator[](const std::string& name) const 155 { return abstract_variables_map::operator[](name); } 156 157 // Override to clear some extra fields. 158 void clear(); 159 160 void notify(); 161 162 private: 163 /** Implementation of abstract_variables_map::get 164 which does 'find' in *this. */ 165 const variable_value& get(const std::string& name) const; 166 167 /** Names of option with 'final' values \-- which should not 168 be changed by subsequence assignments. */ 169 std::set<std::string> m_final; 170 171 friend BOOST_PROGRAM_OPTIONS_DECL 172 void store(const basic_parsed_options<char>& options, 173 variables_map& xm, 174 bool utf8); 175 176 /** Names of required options, filled by parser which has 177 access to options_description. 178 The map values are the "canonical" names for each corresponding option. 179 This is useful in creating diagnostic messages when the option is absent. */ 180 std::map<std::string, std::string> m_required; 181 }; 182 183 184 /* 185 * Templates/inlines 186 */ 187 188 inline bool empty() const189 variable_value::empty() const 190 { 191 return v.empty(); 192 } 193 194 inline bool defaulted() const195 variable_value::defaulted() const 196 { 197 return m_defaulted; 198 } 199 200 inline 201 const boost::any& value() const202 variable_value::value() const 203 { 204 return v; 205 } 206 207 inline 208 boost::any& value()209 variable_value::value() 210 { 211 return v; 212 } 213 214 }} 215 216 #if defined(BOOST_MSVC) 217 # pragma warning (pop) 218 #endif 219 220 #endif 221