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)
6 #ifndef BOOST_VALUE_SEMANTIC_HPP_VP_2004_02_24
7 #define BOOST_VALUE_SEMANTIC_HPP_VP_2004_02_24
9 #include <boost/program_options/config.hpp>
10 #include <boost/program_options/errors.hpp>
12 #include <boost/any.hpp>
13 #include <boost/function/function1.hpp>
14 #include <boost/lexical_cast.hpp>
21 namespace boost
{ namespace program_options
{
23 /** Class which specifies how the option's value is to be parsed
24 and converted into C++ types.
26 class BOOST_PROGRAM_OPTIONS_DECL value_semantic
{
28 /** Returns the name of the option. The name is only meaningful
29 for automatic help message.
31 virtual std::string
name() const = 0;
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;
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;
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.
45 virtual bool is_composing() const = 0;
47 /** Parses a group of tokens that specify a value of option.
48 Stores the result in 'value_store', using whatever representation
49 is desired. May be be called several times if value of the same
50 option is specified more than once.
52 virtual void parse(boost::any
& value_store
,
53 const std::vector
<std::string
>& new_tokens
,
57 /** Called to assign default value to 'value_store'. Returns
58 true if default value is assigned, and false if no default
60 virtual bool apply_default(boost::any
& value_store
) const = 0;
62 /** Called when final value of an option is determined.
64 virtual void notify(const boost::any
& value_store
) const = 0;
66 virtual ~value_semantic() {}
69 /** Helper class which perform necessary character conversions in the
70 'parse' method and forwards the data further.
73 class value_semantic_codecvt_helper
{
74 // Nothing here. Specializations to follow.
77 /** Helper conversion class for values that accept ascii
79 Overrides the 'parse' method and defines new 'xparse'
80 method taking std::string. Depending on whether input
81 to parse is ascii or UTF8, will pass it to xparse unmodified,
82 or with UTF8->ascii conversion.
85 class BOOST_PROGRAM_OPTIONS_DECL
86 value_semantic_codecvt_helper
<char> : public value_semantic
{
87 private: // base overrides
88 void parse(boost::any
& value_store
,
89 const std::vector
<std::string
>& new_tokens
,
91 protected: // interface for derived classes.
92 virtual void xparse(boost::any
& value_store
,
93 const std::vector
<std::string
>& new_tokens
)
97 /** Helper conversion class for values that accept ascii
99 Overrides the 'parse' method and defines new 'xparse'
100 method taking std::wstring. Depending on whether input
101 to parse is ascii or UTF8, will recode input to Unicode, or
105 class BOOST_PROGRAM_OPTIONS_DECL
106 value_semantic_codecvt_helper
<wchar_t> : public value_semantic
{
107 private: // base overrides
108 void parse(boost::any
& value_store
,
109 const std::vector
<std::string
>& new_tokens
,
111 protected: // interface for derived classes.
112 #if !defined(BOOST_NO_STD_WSTRING)
113 virtual void xparse(boost::any
& value_store
,
114 const std::vector
<std::wstring
>& new_tokens
)
119 /** Class which specifies a simple handling of a value: the value will
120 have string type and only one token is allowed. */
121 class BOOST_PROGRAM_OPTIONS_DECL
122 untyped_value
: public value_semantic_codecvt_helper
<char> {
124 untyped_value(bool zero_tokens
= false)
125 : m_zero_tokens(zero_tokens
)
128 std::string
name() const;
130 unsigned min_tokens() const;
131 unsigned max_tokens() const;
133 bool is_composing() const { return false; }
135 /** If 'value_store' is already initialized, or new_tokens
136 has more than one elements, throws. Otherwise, assigns
137 the first string from 'new_tokens' to 'value_store', without
140 void xparse(boost::any
& value_store
,
141 const std::vector
<std::string
>& new_tokens
) const;
144 bool apply_default(boost::any
&) const { return false; }
147 void notify(const boost::any
&) const {}
152 /** Base class for all option that have a fixed type, and are
153 willing to announce this type to the outside world.
154 Any 'value_semantics' for which you want to find out the
155 type can be dynamic_cast-ed to typed_value_base. If conversion
156 succeeds, the 'type' method can be called.
158 class typed_value_base
161 // Returns the type of the value described by this
163 virtual const std::type_info
& value_type() const = 0;
164 // Not really needed, since deletion from this
165 // class is silly, but just in case.
166 virtual ~typed_value_base() {}
170 /** Class which handles value of a specific type. */
171 template<class T
, class charT
= char>
172 class typed_value
: public value_semantic_codecvt_helper
<charT
>,
173 public typed_value_base
176 /** Ctor. The 'store_to' parameter tells where to store
177 the value when it's known. The parameter can be NULL. */
178 typed_value(T
* store_to
)
179 : m_store_to(store_to
), m_composing(false),
180 m_multitoken(false), m_zero_tokens(false)
183 /** Specifies default value, which will be used
184 if none is explicitly specified. The type 'T' should
185 provide operator<< for ostream.
187 typed_value
* default_value(const T
& v
)
189 m_default_value
= boost::any(v
);
190 m_default_value_as_text
= boost::lexical_cast
<std::string
>(v
);
194 /** Specifies default value, which will be used
195 if none is explicitly specified. Unlike the above overload,
196 the type 'T' need not provide operator<< for ostream,
197 but textual representation of default value must be provided
200 typed_value
* default_value(const T
& v
, const std::string
& textual
)
202 m_default_value
= boost::any(v
);
203 m_default_value_as_text
= textual
;
207 /** Specifies an implicit value, which will be used
208 if the option is given, but without an adjacent value.
209 Using this implies that an explicit value is optional, but if
210 given, must be strictly adjacent to the option, i.e.: '-ovalue'
211 or '--option=value'. Giving '-o' or '--option' will cause the
212 implicit value to be applied.
214 typed_value
* implicit_value(const T
&v
)
216 m_implicit_value
= boost::any(v
);
217 m_implicit_value_as_text
=
218 boost::lexical_cast
<std::string
>(v
);
222 /** Specifies an implicit value, which will be used
223 if the option is given, but without an adjacent value.
224 Using this implies that an explicit value is optional, but if
225 given, must be strictly adjacent to the option, i.e.: '-ovalue'
226 or '--option=value'. Giving '-o' or '--option' will cause the
227 implicit value to be applied.
228 Unlike the above overload, the type 'T' need not provide
229 operator<< for ostream, but textual representation of default
230 value must be provided by the user.
232 typed_value
* implicit_value(const T
&v
, const std::string
& textual
)
234 m_implicit_value
= boost::any(v
);
235 m_implicit_value_as_text
= textual
;
239 /** Specifies a function to be called when the final value
241 typed_value
* notifier(function1
<void, const T
&> f
)
247 /** Specifies that the value is composing. See the 'is_composing'
248 method for explanation.
250 typed_value
* composing()
256 /** Specifies that the value can span multiple tokens. */
257 typed_value
* multitoken()
263 typed_value
* zero_tokens()
265 m_zero_tokens
= true;
270 public: // value semantic overrides
272 std::string
name() const;
274 bool is_composing() const { return m_composing
; }
276 unsigned min_tokens() const
278 if (m_zero_tokens
|| !m_implicit_value
.empty()) {
285 unsigned max_tokens() const {
288 } else if (m_zero_tokens
) {
296 /** Creates an instance of the 'validator' class and calls
297 its operator() to perform the actual conversion. */
298 void xparse(boost::any
& value_store
,
299 const std::vector
< std::basic_string
<charT
> >& new_tokens
)
302 /** If default value was specified via previous call to
303 'default_value', stores that value into 'value_store'.
304 Returns true if default value was stored.
306 virtual bool apply_default(boost::any
& value_store
) const
308 if (m_default_value
.empty()) {
311 value_store
= m_default_value
;
316 /** If an address of variable to store value was specified
317 when creating *this, stores the value there. Otherwise,
319 void notify(const boost::any
& value_store
) const;
321 public: // typed_value_base overrides
323 const std::type_info
& value_type() const
332 // Default value is stored as boost::any and not
333 // as boost::optional to avoid unnecessary instantiations.
334 boost::any m_default_value
;
335 std::string m_default_value_as_text
;
336 boost::any m_implicit_value
;
337 std::string m_implicit_value_as_text
;
338 bool m_composing
, m_implicit
, m_multitoken
, m_zero_tokens
;
339 boost::function1
<void, const T
&> m_notifier
;
343 /** Creates a typed_value<T> instance. This function is the primary
344 method to create value_semantic instance for a specific type, which
345 can later be passed to 'option_description' constructor.
346 The second overload is used when it's additionally desired to store the
347 value of option into program variable.
359 /** Creates a typed_value<T> instance. This function is the primary
360 method to create value_semantic instance for a specific type, which
361 can later be passed to 'option_description' constructor.
364 typed_value
<T
, wchar_t>*
370 typed_value
<T
, wchar_t>*
373 /** Works the same way as the 'value<bool>' function, but the created
374 value_semantic won't accept any explicit value. So, if the option
375 is present on the command line, the value will be 'true'.
377 BOOST_PROGRAM_OPTIONS_DECL typed_value
<bool>*
382 BOOST_PROGRAM_OPTIONS_DECL typed_value
<bool>*
383 bool_switch(bool* v
);
387 #include "boost/program_options/detail/value_semantic.hpp"