Mercurial > hg > vamp-build-and-test
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 |