Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/program_options/value_semantic.hpp @ 29

Last change on this file since 29 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 11.5 KB
Line 
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
21namespace 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        /** 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.
51        */
52        virtual void parse(boost::any& value_store, 
53                           const std::vector<std::string>& new_tokens,
54                           bool utf8) const 
55            = 0;
56
57        /** Called to assign default value to 'value_store'. Returns
58            true if default value is assigned, and false if no default
59            value exists. */
60        virtual bool apply_default(boost::any& value_store) const = 0;
61                                   
62        /** Called when final value of an option is determined.
63        */
64        virtual void notify(const boost::any& value_store) const = 0;
65       
66        virtual ~value_semantic() {}
67    };
68
69    /** Helper class which perform necessary character conversions in the
70        'parse' method and forwards the data further.
71    */
72    template<class charT>
73    class value_semantic_codecvt_helper {
74        // Nothing here. Specializations to follow.
75    };
76
77    /** Helper conversion class for values that accept ascii
78        strings as input.
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.
83    */
84    template<>
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,
90                   bool utf8) const;
91    protected: // interface for derived classes.
92        virtual void xparse(boost::any& value_store, 
93                            const std::vector<std::string>& new_tokens) 
94            const = 0;
95    };
96
97    /** Helper conversion class for values that accept ascii
98        strings as input.
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
102        pass it unmodified.
103    */
104    template<>
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,
110                   bool utf8) const;
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) 
115            const = 0;
116#endif
117    };
118
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>  {
123    public:
124        untyped_value(bool zero_tokens = false)
125        : m_zero_tokens(zero_tokens)
126        {}
127
128        std::string name() const;
129
130        unsigned min_tokens() const;
131        unsigned max_tokens() const;
132
133        bool is_composing() const { return false; }
134       
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
138            any modifications.
139         */
140        void xparse(boost::any& value_store,
141                    const std::vector<std::string>& new_tokens) const;
142
143        /** Does nothing. */
144        bool apply_default(boost::any&) const { return false; }
145
146        /** Does nothing. */
147        void notify(const boost::any&) const {}       
148    private:
149        bool m_zero_tokens;
150    };
151
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.
157    */
158    class typed_value_base 
159    {
160    public:
161        // Returns the type of the value described by this
162        // object.
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() {}
167    };
168
169
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
174    {
175    public:
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)
181        {} 
182
183        /** Specifies default value, which will be used
184            if none is explicitly specified. The type 'T' should
185            provide operator<< for ostream.
186        */
187        typed_value* default_value(const T& v)
188        {
189            m_default_value = boost::any(v);
190            m_default_value_as_text = boost::lexical_cast<std::string>(v);
191            return this;
192        }
193
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
198            by the user.
199        */
200        typed_value* default_value(const T& v, const std::string& textual)
201        {
202            m_default_value = boost::any(v);
203            m_default_value_as_text = textual;
204            return this;
205        }
206
207        /** Specifies a function to be called when the final value
208            is determined. */
209        typed_value* notifier(function1<void, const T&> f)
210        {
211            m_notifier = f;
212            return this;
213        }
214
215        /** Specifies that the value is composing. See the 'is_composing'
216            method for explanation.
217        */
218        typed_value* composing()
219        {
220            m_composing = true;
221            return this;
222        }
223
224        /** Specifies that the value can span multiple tokens. */
225        typed_value* multitoken()
226        {
227            m_multitoken = true;
228            return this;
229        }
230
231        typed_value* zero_tokens() 
232        {
233            m_zero_tokens = true;
234            return this;
235        }
236           
237
238    public: // value semantic overrides
239
240        std::string name() const;
241
242        bool is_composing() const { return m_composing; }
243
244        unsigned min_tokens() const
245        {
246            if (m_zero_tokens) {
247                return 0;
248            } else {
249                return 1;
250            }
251        }
252
253        unsigned max_tokens() const {
254            if (m_multitoken) {
255                return 32000;
256            } else if (m_zero_tokens) {
257                return 0;
258            } else {
259                return 1;
260            }
261        }
262
263
264        /** Creates an instance of the 'validator' class and calls
265            its operator() to perform the actual conversion. */
266        void xparse(boost::any& value_store, 
267                    const std::vector< std::basic_string<charT> >& new_tokens) 
268            const;
269
270        /** If default value was specified via previous call to
271            'default_value', stores that value into 'value_store'.
272            Returns true if default value was stored.
273        */
274        virtual bool apply_default(boost::any& value_store) const
275        {
276            if (m_default_value.empty()) {
277                return false;
278            } else {
279                value_store = m_default_value;
280                return true;
281            }
282        }
283
284        /** If an address of variable to store value was specified
285            when creating *this, stores the value there. Otherwise,
286            does nothing. */
287        void notify(const boost::any& value_store) const;
288
289    public: // typed_value_base overrides
290       
291        const std::type_info& value_type() const
292        {
293            return typeid(T);
294        }
295       
296
297    private:
298        T* m_store_to;
299       
300        // Default value is stored as boost::any and not
301        // as boost::optional to avoid unnecessary instantiations.
302        boost::any m_default_value;
303        std::string m_default_value_as_text;
304        bool m_composing, m_implicit, m_multitoken, m_zero_tokens;
305        boost::function1<void, const T&> m_notifier;
306    };
307
308
309    /** Creates a typed_value<T> instance. This function is the primary
310        method to create value_semantic instance for a specific type, which
311        can later be passed to 'option_description' constructor.
312        The second overload is used when it's additionally desired to store the
313        value of option into program variable.
314    */
315    template<class T>
316    typed_value<T>*
317    value();
318
319    /** @overload
320    */
321    template<class T>
322    typed_value<T>*
323    value(T* v);
324
325    /** Creates a typed_value<T> instance. This function is the primary
326        method to create value_semantic instance for a specific type, which
327        can later be passed to 'option_description' constructor.
328    */
329    template<class T>
330    typed_value<T, wchar_t>*
331    wvalue();
332
333    /** @overload   
334    */
335    template<class T>
336    typed_value<T, wchar_t>*
337    wvalue(T* v);
338
339    /** Works the same way as the 'value<bool>' function, but the created
340        value_semantic won't accept any explicit value. So, if the option
341        is present on the command line, the value will be 'true'.
342    */
343    BOOST_PROGRAM_OPTIONS_DECL typed_value<bool>*
344    bool_switch();
345
346    /** @overload
347    */
348    BOOST_PROGRAM_OPTIONS_DECL typed_value<bool>*   
349    bool_switch(bool* v);
350
351}}
352
353#include "boost/program_options/detail/value_semantic.hpp"
354
355#endif
356
Note: See TracBrowser for help on using the repository browser.