be0a4b64e36184a84e546bb97df3058fe3bfe24f
[platform/upstream/boost.git] / boost / program_options / variables_map.hpp
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:
60         variable_value() : m_defaulted(false) {}
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>
68        const T& as() const {
69            return boost::any_cast<const T&>(v);
70        }
71        /** @overload */
72        template<class T>
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 BOOST_PROGRAM_OPTIONS_DECL class 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
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 varaible map, which has a non-defauled
122                   value, return that
123                 - otherwise, return value from *this
124
125             - if there's a non-defauled 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.
154         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
189     variable_value::empty() const
190     {
191         return v.empty();
192     }
193
194     inline bool
195     variable_value::defaulted() const
196     {
197         return m_defaulted;
198     }
199
200     inline
201     const boost::any&
202     variable_value::value() const
203     {
204         return v;
205     }
206
207     inline
208     boost::any&
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