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 | namespace boost { namespace program_options {
|
---|
20 |
|
---|
21 | template<class charT>
|
---|
22 | class basic_parsed_options;
|
---|
23 |
|
---|
24 | class value_semantic;
|
---|
25 | class variables_map;
|
---|
26 |
|
---|
27 | /** Class holding value of option. Contains details about how the
|
---|
28 | value is set and allows to conveniently obtain the value.
|
---|
29 | */
|
---|
30 | class BOOST_PROGRAM_OPTIONS_DECL variable_value {
|
---|
31 | public:
|
---|
32 | variable_value() : m_defaulted(false) {}
|
---|
33 | variable_value(const boost::any& v, bool defaulted)
|
---|
34 | : v(v), m_defaulted(defaulted)
|
---|
35 | {}
|
---|
36 |
|
---|
37 | /** If stored value if of type T, returns that value. Otherwise,
|
---|
38 | throws boost::bad_any_cast exception. */
|
---|
39 | template<class T> const T& as() const;
|
---|
40 |
|
---|
41 | /** @overload */
|
---|
42 | template<class T> T& as();
|
---|
43 |
|
---|
44 | /// Returns true if no value is stored.
|
---|
45 | bool empty() const;
|
---|
46 | /** Returns true if the value was not explicitly
|
---|
47 | given, but has default value. */
|
---|
48 | bool defaulted() const;
|
---|
49 | /** Returns the contained value. */
|
---|
50 | const boost::any& value() const;
|
---|
51 |
|
---|
52 | /** Returns the contained value. */
|
---|
53 | boost::any& value();
|
---|
54 | private:
|
---|
55 | boost::any v;
|
---|
56 | bool m_defaulted;
|
---|
57 | // Internal reference to value semantic. We need to run
|
---|
58 | // notifications when *final* values of options are known, and
|
---|
59 | // they are known only after all sources are stored. By that
|
---|
60 | // time options_description for the first source might not
|
---|
61 | // be easily accessible, so we need to store semantic here.
|
---|
62 | shared_ptr<const value_semantic> m_value_semantic;
|
---|
63 |
|
---|
64 | friend void BOOST_PROGRAM_OPTIONS_DECL
|
---|
65 | store(const basic_parsed_options<char>& options,
|
---|
66 | variables_map& m, bool);
|
---|
67 | friend void BOOST_PROGRAM_OPTIONS_DECL notify(variables_map& m);
|
---|
68 | };
|
---|
69 |
|
---|
70 | /** Implements string->string mapping with convenient value casting
|
---|
71 | facilities. */
|
---|
72 | class BOOST_PROGRAM_OPTIONS_DECL abstract_variables_map {
|
---|
73 | public:
|
---|
74 | abstract_variables_map();
|
---|
75 | abstract_variables_map(const abstract_variables_map* next);
|
---|
76 |
|
---|
77 | virtual ~abstract_variables_map() {}
|
---|
78 |
|
---|
79 | /** Obtains the value of variable 'name', from *this and
|
---|
80 | possibly from the chain of variable maps.
|
---|
81 |
|
---|
82 | - if there's no value in *this.
|
---|
83 | - if there's next variable map, returns value from it
|
---|
84 | - otherwise, returns empty value
|
---|
85 |
|
---|
86 | - if there's defaulted value
|
---|
87 | - if there's next varaible map, which has a non-defauled
|
---|
88 | value, return that
|
---|
89 | - otherwise, return value from *this
|
---|
90 |
|
---|
91 | - if there's a non-defauled value, returns it.
|
---|
92 | */
|
---|
93 | const variable_value& operator[](const std::string& name) const;
|
---|
94 |
|
---|
95 | /** Sets next variable map, which will be used to find
|
---|
96 | variables not found in *this. */
|
---|
97 | void next(abstract_variables_map* next);
|
---|
98 |
|
---|
99 | private:
|
---|
100 | /** Returns value of variable 'name' stored in *this, or
|
---|
101 | empty value otherwise. */
|
---|
102 | virtual const variable_value& get(const std::string& name) const = 0;
|
---|
103 |
|
---|
104 | const abstract_variables_map* m_next;
|
---|
105 | };
|
---|
106 |
|
---|
107 | /** Concrete variables map which store variables in real map. */
|
---|
108 | class BOOST_PROGRAM_OPTIONS_DECL variables_map : public abstract_variables_map,
|
---|
109 | public std::map<std::string, variable_value>
|
---|
110 | {
|
---|
111 | public:
|
---|
112 | variables_map();
|
---|
113 | variables_map(const abstract_variables_map* next);
|
---|
114 |
|
---|
115 | // Resolve conflict between inherited operators.
|
---|
116 | const variable_value& operator[](const std::string& name) const
|
---|
117 | { return abstract_variables_map::operator[](name); }
|
---|
118 |
|
---|
119 | private:
|
---|
120 | /** Implementation of abstract_variables_map::get
|
---|
121 | which does 'find' in *this. */
|
---|
122 | const variable_value& get(const std::string& name) const;
|
---|
123 |
|
---|
124 | /** Names of option with 'final' values -- which should not
|
---|
125 | be changed by subsequence assignments. */
|
---|
126 | std::set<std::string> m_final;
|
---|
127 |
|
---|
128 | friend void store(const basic_parsed_options<char>& options,
|
---|
129 | variables_map& xm,
|
---|
130 | bool utf8);
|
---|
131 | };
|
---|
132 |
|
---|
133 | /** Stores in 'm' all options that are defined in 'options'.
|
---|
134 | If 'm' already has a non-defaulted value of an option, that value
|
---|
135 | is not changed, even if 'options' specify some value.
|
---|
136 | */
|
---|
137 | BOOST_PROGRAM_OPTIONS_DECL void store(const basic_parsed_options<char>& options, variables_map& m,
|
---|
138 | bool utf8 = false);
|
---|
139 |
|
---|
140 | /** Stores in 'm' all options that are defined in 'options'.
|
---|
141 | If 'm' already has a non-defaulted value of an option, that value
|
---|
142 | is not changed, even if 'options' specify some value.
|
---|
143 | This is wide character variant.
|
---|
144 | */
|
---|
145 | BOOST_PROGRAM_OPTIONS_DECL void store(const basic_parsed_options<wchar_t>& options,
|
---|
146 | variables_map& m);
|
---|
147 |
|
---|
148 |
|
---|
149 | /** Runs all 'notify' function for options in 'm'. */
|
---|
150 | BOOST_PROGRAM_OPTIONS_DECL void notify(variables_map& m);
|
---|
151 |
|
---|
152 |
|
---|
153 | /*
|
---|
154 | * Templates/inlines
|
---|
155 | */
|
---|
156 |
|
---|
157 | inline bool
|
---|
158 | variable_value::empty() const
|
---|
159 | {
|
---|
160 | return v.empty();
|
---|
161 | }
|
---|
162 |
|
---|
163 | inline bool
|
---|
164 | variable_value::defaulted() const
|
---|
165 | {
|
---|
166 | return m_defaulted;
|
---|
167 | }
|
---|
168 |
|
---|
169 | inline
|
---|
170 | const boost::any&
|
---|
171 | variable_value::value() const
|
---|
172 | {
|
---|
173 | return v;
|
---|
174 | }
|
---|
175 |
|
---|
176 | inline
|
---|
177 | boost::any&
|
---|
178 | variable_value::value()
|
---|
179 | {
|
---|
180 | return v;
|
---|
181 | }
|
---|
182 |
|
---|
183 |
|
---|
184 | template<class T>
|
---|
185 | const T&
|
---|
186 | variable_value::as() const {
|
---|
187 | return boost::any_cast<const T&>(v);
|
---|
188 | }
|
---|
189 |
|
---|
190 | template<class T>
|
---|
191 | T&
|
---|
192 | variable_value::as() {
|
---|
193 | return boost::any_cast<T&>(v);
|
---|
194 | }
|
---|
195 | }}
|
---|
196 |
|
---|
197 | #endif
|
---|