Chris@16: // Copyright Vladimir Prus 2002-2004. Chris@16: // Distributed under the Boost Software License, Version 1.0. Chris@16: // (See accompanying file LICENSE_1_0.txt Chris@16: // or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: Chris@16: #ifndef BOOST_VARIABLES_MAP_VP_2003_05_19 Chris@16: #define BOOST_VARIABLES_MAP_VP_2003_05_19 Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #if defined(BOOST_MSVC) Chris@16: # pragma warning (push) Chris@16: # 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 Chris@16: #endif Chris@16: Chris@16: namespace boost { namespace program_options { Chris@16: Chris@16: template Chris@16: class basic_parsed_options; Chris@16: Chris@16: class value_semantic; Chris@16: class variables_map; Chris@16: Chris@16: // forward declaration Chris@16: Chris@16: /** Stores in 'm' all options that are defined in 'options'. Chris@16: If 'm' already has a non-defaulted value of an option, that value Chris@16: is not changed, even if 'options' specify some value. Chris@16: */ Chris@16: BOOST_PROGRAM_OPTIONS_DECL Chris@16: void store(const basic_parsed_options& options, variables_map& m, Chris@16: bool utf8 = false); Chris@16: Chris@16: /** Stores in 'm' all options that are defined in 'options'. Chris@16: If 'm' already has a non-defaulted value of an option, that value Chris@16: is not changed, even if 'options' specify some value. Chris@16: This is wide character variant. Chris@16: */ Chris@16: BOOST_PROGRAM_OPTIONS_DECL Chris@16: void store(const basic_parsed_options& options, Chris@16: variables_map& m); Chris@16: Chris@16: Chris@16: /** Runs all 'notify' function for options in 'm'. */ Chris@16: BOOST_PROGRAM_OPTIONS_DECL void notify(variables_map& m); Chris@16: Chris@16: /** Class holding value of option. Contains details about how the Chris@16: value is set and allows to conveniently obtain the value. Chris@16: */ Chris@16: class BOOST_PROGRAM_OPTIONS_DECL variable_value { Chris@16: public: Chris@16: variable_value() : m_defaulted(false) {} Chris@16: variable_value(const boost::any& xv, bool xdefaulted) Chris@16: : v(xv), m_defaulted(xdefaulted) Chris@16: {} Chris@16: Chris@16: /** If stored value if of type T, returns that value. Otherwise, Chris@16: throws boost::bad_any_cast exception. */ Chris@16: template Chris@16: const T& as() const { Chris@16: return boost::any_cast(v); Chris@16: } Chris@16: /** @overload */ Chris@16: template Chris@16: T& as() { Chris@16: return boost::any_cast(v); Chris@16: } Chris@16: Chris@16: /// Returns true if no value is stored. Chris@16: bool empty() const; Chris@16: /** Returns true if the value was not explicitly Chris@16: given, but has default value. */ Chris@16: bool defaulted() const; Chris@16: /** Returns the contained value. */ Chris@16: const boost::any& value() const; Chris@16: Chris@16: /** Returns the contained value. */ Chris@16: boost::any& value(); Chris@16: private: Chris@16: boost::any v; Chris@16: bool m_defaulted; Chris@16: // Internal reference to value semantic. We need to run Chris@16: // notifications when *final* values of options are known, and Chris@16: // they are known only after all sources are stored. By that Chris@16: // time options_description for the first source might not Chris@16: // be easily accessible, so we need to store semantic here. Chris@16: shared_ptr m_value_semantic; Chris@16: Chris@16: friend BOOST_PROGRAM_OPTIONS_DECL Chris@16: void store(const basic_parsed_options& options, Chris@16: variables_map& m, bool); Chris@16: Chris@101: friend class BOOST_PROGRAM_OPTIONS_DECL variables_map; Chris@16: }; Chris@16: Chris@16: /** Implements string->string mapping with convenient value casting Chris@16: facilities. */ Chris@16: class BOOST_PROGRAM_OPTIONS_DECL abstract_variables_map { Chris@16: public: Chris@16: abstract_variables_map(); Chris@16: abstract_variables_map(const abstract_variables_map* next); Chris@16: Chris@16: virtual ~abstract_variables_map() {} Chris@16: Chris@16: /** Obtains the value of variable 'name', from *this and Chris@16: possibly from the chain of variable maps. Chris@16: Chris@16: - if there's no value in *this. Chris@16: - if there's next variable map, returns value from it Chris@16: - otherwise, returns empty value Chris@16: Chris@16: - if there's defaulted value Chris@16: - if there's next varaible map, which has a non-defauled Chris@16: value, return that Chris@16: - otherwise, return value from *this Chris@16: Chris@16: - if there's a non-defauled value, returns it. Chris@16: */ Chris@16: const variable_value& operator[](const std::string& name) const; Chris@16: Chris@16: /** Sets next variable map, which will be used to find Chris@16: variables not found in *this. */ Chris@16: void next(abstract_variables_map* next); Chris@16: Chris@16: private: Chris@16: /** Returns value of variable 'name' stored in *this, or Chris@16: empty value otherwise. */ Chris@16: virtual const variable_value& get(const std::string& name) const = 0; Chris@16: Chris@16: const abstract_variables_map* m_next; Chris@16: }; Chris@16: Chris@16: /** Concrete variables map which store variables in real map. Chris@16: Chris@16: This class is derived from std::map, Chris@16: so you can use all map operators to examine its content. Chris@16: */ Chris@16: class BOOST_PROGRAM_OPTIONS_DECL variables_map : public abstract_variables_map, Chris@16: public std::map Chris@16: { Chris@16: public: Chris@16: variables_map(); Chris@16: variables_map(const abstract_variables_map* next); Chris@16: Chris@16: // Resolve conflict between inherited operators. Chris@16: const variable_value& operator[](const std::string& name) const Chris@16: { return abstract_variables_map::operator[](name); } Chris@16: Chris@16: // Override to clear some extra fields. Chris@16: void clear(); Chris@16: Chris@16: void notify(); Chris@16: Chris@16: private: Chris@16: /** Implementation of abstract_variables_map::get Chris@16: which does 'find' in *this. */ Chris@16: const variable_value& get(const std::string& name) const; Chris@16: Chris@16: /** Names of option with 'final' values -- which should not Chris@16: be changed by subsequence assignments. */ Chris@16: std::set m_final; Chris@16: Chris@16: friend BOOST_PROGRAM_OPTIONS_DECL Chris@16: void store(const basic_parsed_options& options, Chris@16: variables_map& xm, Chris@16: bool utf8); Chris@16: Chris@16: /** Names of required options, filled by parser which has Chris@16: access to options_description. Chris@16: The map values are the "canonical" names for each corresponding option. Chris@16: This is useful in creating diagnostic messages when the option is absent. */ Chris@16: std::map m_required; Chris@16: }; Chris@16: Chris@16: Chris@16: /* Chris@16: * Templates/inlines Chris@16: */ Chris@16: Chris@16: inline bool Chris@16: variable_value::empty() const Chris@16: { Chris@16: return v.empty(); Chris@16: } Chris@16: Chris@16: inline bool Chris@16: variable_value::defaulted() const Chris@16: { Chris@16: return m_defaulted; Chris@16: } Chris@16: Chris@16: inline Chris@16: const boost::any& Chris@16: variable_value::value() const Chris@16: { Chris@16: return v; Chris@16: } Chris@16: Chris@16: inline Chris@16: boost::any& Chris@16: variable_value::value() Chris@16: { Chris@16: return v; Chris@16: } Chris@16: Chris@16: }} Chris@16: Chris@16: #if defined(BOOST_MSVC) Chris@16: # pragma warning (pop) Chris@16: #endif Chris@16: Chris@16: #endif