1 // Copyright Vladimir Prus 2004.
\r
2 // Distributed under the Boost Software License, Version 1.0.
\r
3 // (See accompanying file LICENSE_1_0.txt
\r
4 // or copy at http://www.boost.org/LICENSE_1_0.txt)
\r
6 #ifndef BOOST_VALUE_SEMANTIC_HPP_VP_2004_02_24
\r
7 #define BOOST_VALUE_SEMANTIC_HPP_VP_2004_02_24
\r
9 #include <boost/program_options/config.hpp>
\r
10 #include <boost/program_options/errors.hpp>
\r
12 #include <boost/any.hpp>
\r
13 #include <boost/function/function1.hpp>
\r
14 #include <boost/lexical_cast.hpp>
\r
21 namespace boost { namespace program_options {
\r
23 /** Class which specifies how the option's value is to be parsed
\r
24 and converted into C++ types.
\r
26 class BOOST_PROGRAM_OPTIONS_DECL value_semantic {
\r
28 /** Returns the name of the option. The name is only meaningful
\r
29 for automatic help message.
\r
31 virtual std::string name() const = 0;
\r
33 /** The minimum number of tokens for this option that
\r
34 should be present on the command line. */
\r
35 virtual unsigned min_tokens() const = 0;
\r
37 /** The maximum number of tokens for this option that
\r
38 should be present on the command line. */
\r
39 virtual unsigned max_tokens() const = 0;
\r
41 /** Returns true if values from different sources should be composed.
\r
42 Otherwise, value from the first source is used and values from
\r
43 other sources are discarded.
\r
45 virtual bool is_composing() const = 0;
\r
47 /** Returns true if value must be given. Non-optional value
\r
50 virtual bool is_required() const = 0;
\r
52 /** Parses a group of tokens that specify a value of option.
\r
53 Stores the result in 'value_store', using whatever representation
\r
54 is desired. May be be called several times if value of the same
\r
55 option is specified more than once.
\r
57 virtual void parse(boost::any& value_store,
\r
58 const std::vector<std::string>& new_tokens,
\r
62 /** Called to assign default value to 'value_store'. Returns
\r
63 true if default value is assigned, and false if no default
\r
65 virtual bool apply_default(boost::any& value_store) const = 0;
\r
67 /** Called when final value of an option is determined.
\r
69 virtual void notify(const boost::any& value_store) const = 0;
\r
71 virtual ~value_semantic() {}
\r
74 /** Helper class which perform necessary character conversions in the
\r
75 'parse' method and forwards the data further.
\r
77 template<class charT>
\r
78 class value_semantic_codecvt_helper {
\r
79 // Nothing here. Specializations to follow.
\r
82 /** Helper conversion class for values that accept ascii
\r
84 Overrides the 'parse' method and defines new 'xparse'
\r
85 method taking std::string. Depending on whether input
\r
86 to parse is ascii or UTF8, will pass it to xparse unmodified,
\r
87 or with UTF8->ascii conversion.
\r
90 class BOOST_PROGRAM_OPTIONS_DECL
\r
91 value_semantic_codecvt_helper<char> : public value_semantic {
\r
92 private: // base overrides
\r
93 void parse(boost::any& value_store,
\r
94 const std::vector<std::string>& new_tokens,
\r
96 protected: // interface for derived classes.
\r
97 virtual void xparse(boost::any& value_store,
\r
98 const std::vector<std::string>& new_tokens)
\r
102 /** Helper conversion class for values that accept ascii
\r
104 Overrides the 'parse' method and defines new 'xparse'
\r
105 method taking std::wstring. Depending on whether input
\r
106 to parse is ascii or UTF8, will recode input to Unicode, or
\r
107 pass it unmodified.
\r
110 class BOOST_PROGRAM_OPTIONS_DECL
\r
111 value_semantic_codecvt_helper<wchar_t> : public value_semantic {
\r
112 private: // base overrides
\r
113 void parse(boost::any& value_store,
\r
114 const std::vector<std::string>& new_tokens,
\r
116 protected: // interface for derived classes.
\r
117 #if !defined(BOOST_NO_STD_WSTRING)
\r
118 virtual void xparse(boost::any& value_store,
\r
119 const std::vector<std::wstring>& new_tokens)
\r
124 /** Class which specifies a simple handling of a value: the value will
\r
125 have string type and only one token is allowed. */
\r
126 class BOOST_PROGRAM_OPTIONS_DECL
\r
127 untyped_value : public value_semantic_codecvt_helper<char> {
\r
129 untyped_value(bool zero_tokens = false)
\r
130 : m_zero_tokens(zero_tokens)
\r
133 std::string name() const;
\r
135 unsigned min_tokens() const;
\r
136 unsigned max_tokens() const;
\r
138 bool is_composing() const { return false; }
\r
140 bool is_required() const { return false; }
\r
142 /** If 'value_store' is already initialized, or new_tokens
\r
143 has more than one elements, throws. Otherwise, assigns
\r
144 the first string from 'new_tokens' to 'value_store', without
\r
147 void xparse(boost::any& value_store,
\r
148 const std::vector<std::string>& new_tokens) const;
\r
150 /** Does nothing. */
\r
151 bool apply_default(boost::any&) const { return false; }
\r
153 /** Does nothing. */
\r
154 void notify(const boost::any&) const {}
\r
156 bool m_zero_tokens;
\r
159 /** Base class for all option that have a fixed type, and are
\r
160 willing to announce this type to the outside world.
\r
161 Any 'value_semantics' for which you want to find out the
\r
162 type can be dynamic_cast-ed to typed_value_base. If conversion
\r
163 succeeds, the 'type' method can be called.
\r
165 class typed_value_base
\r
168 // Returns the type of the value described by this
\r
170 virtual const std::type_info& value_type() const = 0;
\r
171 // Not really needed, since deletion from this
\r
172 // class is silly, but just in case.
\r
173 virtual ~typed_value_base() {}
\r
177 /** Class which handles value of a specific type. */
\r
178 template<class T, class charT = char>
\r
179 class typed_value : public value_semantic_codecvt_helper<charT>,
\r
180 public typed_value_base
\r
183 /** Ctor. The 'store_to' parameter tells where to store
\r
184 the value when it's known. The parameter can be NULL. */
\r
185 typed_value(T* store_to)
\r
186 : m_store_to(store_to), m_composing(false),
\r
187 m_multitoken(false), m_zero_tokens(false),
\r
191 /** Specifies default value, which will be used
\r
192 if none is explicitly specified. The type 'T' should
\r
193 provide operator<< for ostream.
\r
195 typed_value* default_value(const T& v)
\r
197 m_default_value = boost::any(v);
\r
198 m_default_value_as_text = boost::lexical_cast<std::string>(v);
\r
202 /** Specifies default value, which will be used
\r
203 if none is explicitly specified. Unlike the above overload,
\r
204 the type 'T' need not provide operator<< for ostream,
\r
205 but textual representation of default value must be provided
\r
208 typed_value* default_value(const T& v, const std::string& textual)
\r
210 m_default_value = boost::any(v);
\r
211 m_default_value_as_text = textual;
\r
215 /** Specifies an implicit value, which will be used
\r
216 if the option is given, but without an adjacent value.
\r
217 Using this implies that an explicit value is optional, but if
\r
218 given, must be strictly adjacent to the option, i.e.: '-ovalue'
\r
219 or '--option=value'. Giving '-o' or '--option' will cause the
\r
220 implicit value to be applied.
\r
222 typed_value* implicit_value(const T &v)
\r
224 m_implicit_value = boost::any(v);
\r
225 m_implicit_value_as_text =
\r
226 boost::lexical_cast<std::string>(v);
\r
230 /** Specifies an implicit value, which will be used
\r
231 if the option is given, but without an adjacent value.
\r
232 Using this implies that an explicit value is optional, but if
\r
233 given, must be strictly adjacent to the option, i.e.: '-ovalue'
\r
234 or '--option=value'. Giving '-o' or '--option' will cause the
\r
235 implicit value to be applied.
\r
236 Unlike the above overload, the type 'T' need not provide
\r
237 operator<< for ostream, but textual representation of default
\r
238 value must be provided by the user.
\r
240 typed_value* implicit_value(const T &v, const std::string& textual)
\r
242 m_implicit_value = boost::any(v);
\r
243 m_implicit_value_as_text = textual;
\r
247 /** Specifies a function to be called when the final value
\r
249 typed_value* notifier(function1<void, const T&> f)
\r
255 /** Specifies that the value is composing. See the 'is_composing'
\r
256 method for explanation.
\r
258 typed_value* composing()
\r
260 m_composing = true;
\r
264 /** Specifies that the value can span multiple tokens. */
\r
265 typed_value* multitoken()
\r
267 m_multitoken = true;
\r
271 typed_value* zero_tokens()
\r
273 m_zero_tokens = true;
\r
277 /** Specifies that the value must occur. */
\r
278 typed_value* required()
\r
284 public: // value semantic overrides
\r
286 std::string name() const;
\r
288 bool is_composing() const { return m_composing; }
\r
290 unsigned min_tokens() const
\r
292 if (m_zero_tokens || !m_implicit_value.empty()) {
\r
299 unsigned max_tokens() const {
\r
300 if (m_multitoken) {
\r
302 } else if (m_zero_tokens) {
\r
309 bool is_required() const { return m_required; }
\r
311 /** Creates an instance of the 'validator' class and calls
\r
312 its operator() to perform the actual conversion. */
\r
313 void xparse(boost::any& value_store,
\r
314 const std::vector< std::basic_string<charT> >& new_tokens)
\r
317 /** If default value was specified via previous call to
\r
318 'default_value', stores that value into 'value_store'.
\r
319 Returns true if default value was stored.
\r
321 virtual bool apply_default(boost::any& value_store) const
\r
323 if (m_default_value.empty()) {
\r
326 value_store = m_default_value;
\r
331 /** If an address of variable to store value was specified
\r
332 when creating *this, stores the value there. Otherwise,
\r
334 void notify(const boost::any& value_store) const;
\r
336 public: // typed_value_base overrides
\r
338 const std::type_info& value_type() const
\r
347 // Default value is stored as boost::any and not
\r
348 // as boost::optional to avoid unnecessary instantiations.
\r
349 boost::any m_default_value;
\r
350 std::string m_default_value_as_text;
\r
351 boost::any m_implicit_value;
\r
352 std::string m_implicit_value_as_text;
\r
353 bool m_composing, m_implicit, m_multitoken, m_zero_tokens, m_required;
\r
354 boost::function1<void, const T&> m_notifier;
\r
358 /** Creates a typed_value<T> instance. This function is the primary
\r
359 method to create value_semantic instance for a specific type, which
\r
360 can later be passed to 'option_description' constructor.
\r
361 The second overload is used when it's additionally desired to store the
\r
362 value of option into program variable.
\r
374 /** Creates a typed_value<T> instance. This function is the primary
\r
375 method to create value_semantic instance for a specific type, which
\r
376 can later be passed to 'option_description' constructor.
\r
379 typed_value<T, wchar_t>*
\r
385 typed_value<T, wchar_t>*
\r
388 /** Works the same way as the 'value<bool>' function, but the created
\r
389 value_semantic won't accept any explicit value. So, if the option
\r
390 is present on the command line, the value will be 'true'.
\r
392 BOOST_PROGRAM_OPTIONS_DECL typed_value<bool>*
\r
397 BOOST_PROGRAM_OPTIONS_DECL typed_value<bool>*
\r
398 bool_switch(bool* v);
\r
402 #include "boost/program_options/detail/value_semantic.hpp"
\r