source: NonGTP/Boost/boost/program_options/value_semantic.hpp @ 857

Revision 857, 10.3 KB checked in by igarcia, 18 years ago (diff)
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
18#include <string>
19#include <vector>
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    template<>
78    class BOOST_PROGRAM_OPTIONS_DECL
79    value_semantic_codecvt_helper<char> : public value_semantic {
80    private: // base overrides
81        void parse(boost::any& value_store,
82                   const std::vector<std::string>& new_tokens,
83                   bool utf8) const;
84    protected: // interface for derived classes.
85        virtual void xparse(boost::any& value_store,
86                            const std::vector<std::string>& new_tokens)
87            const = 0;
88    };
89
90    template<>
91    class BOOST_PROGRAM_OPTIONS_DECL
92    value_semantic_codecvt_helper<wchar_t> : public value_semantic {
93    private: // base overrides
94        void parse(boost::any& value_store,
95                   const std::vector<std::string>& new_tokens,
96                   bool utf8) const;
97    protected: // interface for derived classes.
98#if !defined(BOOST_NO_STD_WSTRING)
99        virtual void xparse(boost::any& value_store,
100                            const std::vector<std::wstring>& new_tokens)
101            const = 0;
102#endif
103    };
104    /** Class which specifies a simple handling of a value: the value will
105        have string type and only one token is allowed. */   
106    class BOOST_PROGRAM_OPTIONS_DECL
107    untyped_value : public value_semantic_codecvt_helper<char>  {
108    public:
109        untyped_value(bool zero_tokens = false)
110        : m_zero_tokens(zero_tokens)
111        {}
112
113        std::string name() const;
114
115        unsigned min_tokens() const;
116        unsigned max_tokens() const;
117
118        bool is_composing() const { return false; }
119       
120        /** If 'value_store' is already initialized, or new_tokens
121            has more than one elements, throws. Otherwise, assigns
122            the first string from 'new_tokens' to 'value_store', without
123            any modifications.
124         */
125        void xparse(boost::any& value_store,
126                    const std::vector<std::string>& new_tokens) const;
127
128        /** Does nothing. */
129        bool apply_default(boost::any&) const { return false; }
130
131        /** Does nothing. */
132        void notify(const boost::any&) const {}       
133    private:
134        bool m_zero_tokens;
135    };
136
137    /** Class which handles value of a specific type. */
138    template<class T, class charT = char>
139    class typed_value : public value_semantic_codecvt_helper<charT>  {
140    public:
141        /** Ctor. The 'store_to' parameter tells where to store
142            the value when it's known. The parameter can be NULL. */
143        typed_value(T* store_to)
144        : m_store_to(store_to), m_composing(false),
145          m_multitoken(false), m_zero_tokens(false)
146        {}
147
148        /** Specifies default value, which will be used
149            if none is explicitly specified. The type 'T' should
150            provide operator<< for ostream.
151        */
152        typed_value* default_value(const T& v)
153        {
154            m_default_value = boost::any(v);
155            m_default_value_as_text = boost::lexical_cast<std::string>(v);
156            return this;
157        }
158
159        /** Specifies default value, which will be used
160            if none is explicitly specified. Unlike the above overload,
161            the type 'T' need not provide operator<< for ostream,
162            but textual representation of default value must be provided
163            by the user.
164        */
165        typed_value* default_value(const T& v, const std::string& textual)
166        {
167            m_default_value = boost::any(v);
168            m_default_value_as_text = textual;
169            return this;
170        }
171
172        /** Specifies a function to be called when the final value
173            is determined. */
174        typed_value* notifier(function1<void, const T&> f)
175        {
176            m_notifier = f;
177            return this;
178        }
179
180        /** Specifies that the value is composing. See the 'is_composing'
181            method for explanation.
182        */
183        typed_value* composing()
184        {
185            m_composing = true;
186            return this;
187        }
188
189        /** Specifies that the value can span multiple tokens. */
190        typed_value* multitoken()
191        {
192            m_multitoken = true;
193            return this;
194        }
195
196        typed_value* zero_tokens()
197        {
198            m_zero_tokens = true;
199            return this;
200        }
201           
202
203    public: // value semantic overrides
204
205        std::string name() const;
206
207        bool is_composing() const { return m_composing; }
208
209        unsigned min_tokens() const
210        {
211            if (m_zero_tokens) {
212                return 0;
213            } else {
214                return 1;
215            }
216        }
217
218        unsigned max_tokens() const {
219            if (m_multitoken) {
220                return 32000;
221            } else if (m_zero_tokens) {
222                return 0;
223            } else {
224                return 1;
225            }
226        }
227
228
229        /** Creates an instance of the 'validator' class and calls
230            its operator() to perform athe ctual conversion. */
231        void xparse(boost::any& value_store,
232                    const std::vector< std::basic_string<charT> >& new_tokens)
233            const;
234
235        /** If default value was specified via previous call to
236            'default_value', stores that value into 'value_store'.
237            Returns true if default value was stored.
238        */
239        virtual bool apply_default(boost::any& value_store) const
240        {
241            if (m_default_value.empty()) {
242                return false;
243            } else {
244                value_store = m_default_value;
245                return true;
246            }
247        }
248
249        /** If an address of variable to store value was specified
250            when creating *this, stores the value there. Otherwise,
251            does nothing. */
252        void notify(const boost::any& value_store) const;
253       
254
255    private:
256        T* m_store_to;
257       
258        // Default value is stored as boost::any and not
259        // as boost::optional to avoid unnecessary instantiations.
260        boost::any m_default_value;
261        std::string m_default_value_as_text;
262        bool m_composing, m_implicit, m_multitoken, m_zero_tokens;
263        boost::function1<void, const T&> m_notifier;
264    };
265
266
267    /** Creates a typed_value<T> instance. This function is the primary
268        method to create value_semantic instance for a specific type, which
269        can later be passed to 'option_description' constructor.
270        The second overload is used when it's additionally desired to store the
271        value of option into program variable.
272    */
273    template<class T>
274    typed_value<T>*
275    value();
276
277    /** @overload
278    */
279    template<class T>
280    typed_value<T>*
281    value(T* v);
282
283    /** Creates a typed_value<T> instance. This function is the primary
284        method to create value_semantic instance for a specific type, which
285        can later be passed to 'option_description' constructor.
286    */
287    template<class T>
288    typed_value<T, wchar_t>*
289    wvalue();
290
291    /** @overload   
292    */
293    template<class T>
294    typed_value<T, wchar_t>*
295    wvalue(T* v);
296
297    /** Works the same way as the 'value<bool>' function, but the created
298        value_semantic won't accept any explicit value. So, if the option
299        is present on the command line, the value will be 'true'.
300    */
301    BOOST_PROGRAM_OPTIONS_DECL typed_value<bool>*
302    bool_switch();
303
304    /** @overload
305    */
306    BOOST_PROGRAM_OPTIONS_DECL typed_value<bool>*   
307    bool_switch(bool* v);
308
309}}
310
311#include "boost/program_options/detail/value_semantic.hpp"
312
313#endif
314
Note: See TracBrowser for help on using the repository browser.