comparison DEPENDENCIES/generic/include/boost/program_options/value_semantic.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children
comparison
equal deleted inserted replaced
15:663ca0da4350 16:2665513ce2d3
1 // Copyright Vladimir Prus 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 #ifndef BOOST_VALUE_SEMANTIC_HPP_VP_2004_02_24
7 #define BOOST_VALUE_SEMANTIC_HPP_VP_2004_02_24
8
9 #include <boost/program_options/config.hpp>
10 #include <boost/program_options/errors.hpp>
11
12 #include <boost/any.hpp>
13 #include <boost/function/function1.hpp>
14 #include <boost/lexical_cast.hpp>
15
16
17 #include <string>
18 #include <vector>
19 #include <typeinfo>
20
21 namespace boost { namespace program_options {
22
23 /** Class which specifies how the option's value is to be parsed
24 and converted into C++ types.
25 */
26 class BOOST_PROGRAM_OPTIONS_DECL value_semantic {
27 public:
28 /** Returns the name of the option. The name is only meaningful
29 for automatic help message.
30 */
31 virtual std::string name() const = 0;
32
33 /** The minimum number of tokens for this option that
34 should be present on the command line. */
35 virtual unsigned min_tokens() const = 0;
36
37 /** The maximum number of tokens for this option that
38 should be present on the command line. */
39 virtual unsigned max_tokens() const = 0;
40
41 /** Returns true if values from different sources should be composed.
42 Otherwise, value from the first source is used and values from
43 other sources are discarded.
44 */
45 virtual bool is_composing() const = 0;
46
47 /** Returns true if value must be given. Non-optional value
48
49 */
50 virtual bool is_required() const = 0;
51
52 /** Parses a group of tokens that specify a value of option.
53 Stores the result in 'value_store', using whatever representation
54 is desired. May be be called several times if value of the same
55 option is specified more than once.
56 */
57 virtual void parse(boost::any& value_store,
58 const std::vector<std::string>& new_tokens,
59 bool utf8) const
60 = 0;
61
62 /** Called to assign default value to 'value_store'. Returns
63 true if default value is assigned, and false if no default
64 value exists. */
65 virtual bool apply_default(boost::any& value_store) const = 0;
66
67 /** Called when final value of an option is determined.
68 */
69 virtual void notify(const boost::any& value_store) const = 0;
70
71 virtual ~value_semantic() {}
72 };
73
74 /** Helper class which perform necessary character conversions in the
75 'parse' method and forwards the data further.
76 */
77 template<class charT>
78 class value_semantic_codecvt_helper {
79 // Nothing here. Specializations to follow.
80 };
81
82 /** Helper conversion class for values that accept ascii
83 strings as input.
84 Overrides the 'parse' method and defines new 'xparse'
85 method taking std::string. Depending on whether input
86 to parse is ascii or UTF8, will pass it to xparse unmodified,
87 or with UTF8->ascii conversion.
88 */
89 template<>
90 class BOOST_PROGRAM_OPTIONS_DECL
91 value_semantic_codecvt_helper<char> : public value_semantic {
92 private: // base overrides
93 void parse(boost::any& value_store,
94 const std::vector<std::string>& new_tokens,
95 bool utf8) const;
96 protected: // interface for derived classes.
97 virtual void xparse(boost::any& value_store,
98 const std::vector<std::string>& new_tokens)
99 const = 0;
100 };
101
102 /** Helper conversion class for values that accept ascii
103 strings as input.
104 Overrides the 'parse' method and defines new 'xparse'
105 method taking std::wstring. Depending on whether input
106 to parse is ascii or UTF8, will recode input to Unicode, or
107 pass it unmodified.
108 */
109 template<>
110 class BOOST_PROGRAM_OPTIONS_DECL
111 value_semantic_codecvt_helper<wchar_t> : public value_semantic {
112 private: // base overrides
113 void parse(boost::any& value_store,
114 const std::vector<std::string>& new_tokens,
115 bool utf8) const;
116 protected: // interface for derived classes.
117 #if !defined(BOOST_NO_STD_WSTRING)
118 virtual void xparse(boost::any& value_store,
119 const std::vector<std::wstring>& new_tokens)
120 const = 0;
121 #endif
122 };
123
124 /** Class which specifies a simple handling of a value: the value will
125 have string type and only one token is allowed. */
126 class BOOST_PROGRAM_OPTIONS_DECL
127 untyped_value : public value_semantic_codecvt_helper<char> {
128 public:
129 untyped_value(bool zero_tokens = false)
130 : m_zero_tokens(zero_tokens)
131 {}
132
133 std::string name() const;
134
135 unsigned min_tokens() const;
136 unsigned max_tokens() const;
137
138 bool is_composing() const { return false; }
139
140 bool is_required() const { return false; }
141
142 /** If 'value_store' is already initialized, or new_tokens
143 has more than one elements, throws. Otherwise, assigns
144 the first string from 'new_tokens' to 'value_store', without
145 any modifications.
146 */
147 void xparse(boost::any& value_store,
148 const std::vector<std::string>& new_tokens) const;
149
150 /** Does nothing. */
151 bool apply_default(boost::any&) const { return false; }
152
153 /** Does nothing. */
154 void notify(const boost::any&) const {}
155 private:
156 bool m_zero_tokens;
157 };
158
159 /** Base class for all option that have a fixed type, and are
160 willing to announce this type to the outside world.
161 Any 'value_semantics' for which you want to find out the
162 type can be dynamic_cast-ed to typed_value_base. If conversion
163 succeeds, the 'type' method can be called.
164 */
165 class typed_value_base
166 {
167 public:
168 // Returns the type of the value described by this
169 // object.
170 virtual const std::type_info& value_type() const = 0;
171 // Not really needed, since deletion from this
172 // class is silly, but just in case.
173 virtual ~typed_value_base() {}
174 };
175
176
177 /** Class which handles value of a specific type. */
178 template<class T, class charT = char>
179 class typed_value : public value_semantic_codecvt_helper<charT>,
180 public typed_value_base
181 {
182 public:
183 /** Ctor. The 'store_to' parameter tells where to store
184 the value when it's known. The parameter can be NULL. */
185 typed_value(T* store_to)
186 : m_store_to(store_to), m_composing(false),
187 m_multitoken(false), m_zero_tokens(false),
188 m_required(false)
189 {}
190
191 /** Specifies default value, which will be used
192 if none is explicitly specified. The type 'T' should
193 provide operator<< for ostream.
194 */
195 typed_value* default_value(const T& v)
196 {
197 m_default_value = boost::any(v);
198 m_default_value_as_text = boost::lexical_cast<std::string>(v);
199 return this;
200 }
201
202 /** Specifies default value, which will be used
203 if none is explicitly specified. Unlike the above overload,
204 the type 'T' need not provide operator<< for ostream,
205 but textual representation of default value must be provided
206 by the user.
207 */
208 typed_value* default_value(const T& v, const std::string& textual)
209 {
210 m_default_value = boost::any(v);
211 m_default_value_as_text = textual;
212 return this;
213 }
214
215 /** Specifies an implicit value, which will be used
216 if the option is given, but without an adjacent value.
217 Using this implies that an explicit value is optional, but if
218 given, must be strictly adjacent to the option, i.e.: '-ovalue'
219 or '--option=value'. Giving '-o' or '--option' will cause the
220 implicit value to be applied.
221 */
222 typed_value* implicit_value(const T &v)
223 {
224 m_implicit_value = boost::any(v);
225 m_implicit_value_as_text =
226 boost::lexical_cast<std::string>(v);
227 return this;
228 }
229
230 /** Specifies the name used to to the value in help message. */
231 typed_value* value_name(const std::string& name)
232 {
233 m_value_name = name;
234 return this;
235 }
236
237 /** Specifies an implicit value, which will be used
238 if the option is given, but without an adjacent value.
239 Using this implies that an explicit value is optional, but if
240 given, must be strictly adjacent to the option, i.e.: '-ovalue'
241 or '--option=value'. Giving '-o' or '--option' will cause the
242 implicit value to be applied.
243 Unlike the above overload, the type 'T' need not provide
244 operator<< for ostream, but textual representation of default
245 value must be provided by the user.
246 */
247 typed_value* implicit_value(const T &v, const std::string& textual)
248 {
249 m_implicit_value = boost::any(v);
250 m_implicit_value_as_text = textual;
251 return this;
252 }
253
254 /** Specifies a function to be called when the final value
255 is determined. */
256 typed_value* notifier(function1<void, const T&> f)
257 {
258 m_notifier = f;
259 return this;
260 }
261
262 /** Specifies that the value is composing. See the 'is_composing'
263 method for explanation.
264 */
265 typed_value* composing()
266 {
267 m_composing = true;
268 return this;
269 }
270
271 /** Specifies that the value can span multiple tokens.
272 */
273 typed_value* multitoken()
274 {
275 m_multitoken = true;
276 return this;
277 }
278
279 /** Specifies that no tokens may be provided as the value of
280 this option, which means that only presense of the option
281 is significant. For such option to be useful, either the
282 'validate' function should be specialized, or the
283 'implicit_value' method should be also used. In most
284 cases, you can use the 'bool_switch' function instead of
285 using this method. */
286 typed_value* zero_tokens()
287 {
288 m_zero_tokens = true;
289 return this;
290 }
291
292 /** Specifies that the value must occur. */
293 typed_value* required()
294 {
295 m_required = true;
296 return this;
297 }
298
299 public: // value semantic overrides
300
301 std::string name() const;
302
303 bool is_composing() const { return m_composing; }
304
305 unsigned min_tokens() const
306 {
307 if (m_zero_tokens || !m_implicit_value.empty()) {
308 return 0;
309 } else {
310 return 1;
311 }
312 }
313
314 unsigned max_tokens() const {
315 if (m_multitoken) {
316 return 32000;
317 } else if (m_zero_tokens) {
318 return 0;
319 } else {
320 return 1;
321 }
322 }
323
324 bool is_required() const { return m_required; }
325
326 /** Creates an instance of the 'validator' class and calls
327 its operator() to perform the actual conversion. */
328 void xparse(boost::any& value_store,
329 const std::vector< std::basic_string<charT> >& new_tokens)
330 const;
331
332 /** If default value was specified via previous call to
333 'default_value', stores that value into 'value_store'.
334 Returns true if default value was stored.
335 */
336 virtual bool apply_default(boost::any& value_store) const
337 {
338 if (m_default_value.empty()) {
339 return false;
340 } else {
341 value_store = m_default_value;
342 return true;
343 }
344 }
345
346 /** If an address of variable to store value was specified
347 when creating *this, stores the value there. Otherwise,
348 does nothing. */
349 void notify(const boost::any& value_store) const;
350
351 public: // typed_value_base overrides
352
353 const std::type_info& value_type() const
354 {
355 return typeid(T);
356 }
357
358
359 private:
360 T* m_store_to;
361
362 // Default value is stored as boost::any and not
363 // as boost::optional to avoid unnecessary instantiations.
364 std::string m_value_name;
365 boost::any m_default_value;
366 std::string m_default_value_as_text;
367 boost::any m_implicit_value;
368 std::string m_implicit_value_as_text;
369 bool m_composing, m_implicit, m_multitoken, m_zero_tokens, m_required;
370 boost::function1<void, const T&> m_notifier;
371 };
372
373
374 /** Creates a typed_value<T> instance. This function is the primary
375 method to create value_semantic instance for a specific type, which
376 can later be passed to 'option_description' constructor.
377 The second overload is used when it's additionally desired to store the
378 value of option into program variable.
379 */
380 template<class T>
381 typed_value<T>*
382 value();
383
384 /** @overload
385 */
386 template<class T>
387 typed_value<T>*
388 value(T* v);
389
390 /** Creates a typed_value<T> instance. This function is the primary
391 method to create value_semantic instance for a specific type, which
392 can later be passed to 'option_description' constructor.
393 */
394 template<class T>
395 typed_value<T, wchar_t>*
396 wvalue();
397
398 /** @overload
399 */
400 template<class T>
401 typed_value<T, wchar_t>*
402 wvalue(T* v);
403
404 /** Works the same way as the 'value<bool>' function, but the created
405 value_semantic won't accept any explicit value. So, if the option
406 is present on the command line, the value will be 'true'.
407 */
408 BOOST_PROGRAM_OPTIONS_DECL typed_value<bool>*
409 bool_switch();
410
411 /** @overload
412 */
413 BOOST_PROGRAM_OPTIONS_DECL typed_value<bool>*
414 bool_switch(bool* v);
415
416 }}
417
418 #include "boost/program_options/detail/value_semantic.hpp"
419
420 #endif
421