]> AND Private Git Repository - canny.git/blob - stc/exp/ml_stc_linux_make_v1.0/include/boost/program_options/value_semantic.hpp
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
d1004108617cf0cb6e3a28c71b0904cc1393a1c2
[canny.git] / stc / exp / ml_stc_linux_make_v1.0 / include / boost / program_options / value_semantic.hpp
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
5 \r
6 #ifndef BOOST_VALUE_SEMANTIC_HPP_VP_2004_02_24\r
7 #define BOOST_VALUE_SEMANTIC_HPP_VP_2004_02_24\r
8 \r
9 #include <boost/program_options/config.hpp>\r
10 #include <boost/program_options/errors.hpp>\r
11 \r
12 #include <boost/any.hpp>\r
13 #include <boost/function/function1.hpp>\r
14 #include <boost/lexical_cast.hpp>\r
15 \r
16 \r
17 #include <string>\r
18 #include <vector>\r
19 #include <typeinfo>\r
20 \r
21 namespace boost { namespace program_options {\r
22 \r
23     /** Class which specifies how the option's value is to be parsed\r
24         and converted into C++ types.\r
25     */\r
26     class BOOST_PROGRAM_OPTIONS_DECL value_semantic {\r
27     public:\r
28         /** Returns the name of the option. The name is only meaningful\r
29             for automatic help message.\r
30          */\r
31         virtual std::string name() const = 0;\r
32 \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
36 \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
40 \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
44         */\r
45         virtual bool is_composing() const = 0;\r
46 \r
47         /** Returns true if value must be given. Non-optional value\r
48 \r
49         */\r
50         virtual bool is_required() const = 0;\r
51         \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
56         */\r
57         virtual void parse(boost::any& value_store, \r
58                            const std::vector<std::string>& new_tokens,\r
59                            bool utf8) const \r
60             = 0;\r
61 \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
64             value exists. */\r
65         virtual bool apply_default(boost::any& value_store) const = 0;\r
66                                    \r
67         /** Called when final value of an option is determined. \r
68         */\r
69         virtual void notify(const boost::any& value_store) const = 0;\r
70         \r
71         virtual ~value_semantic() {}\r
72     };\r
73 \r
74     /** Helper class which perform necessary character conversions in the \r
75         'parse' method and forwards the data further.\r
76     */\r
77     template<class charT>\r
78     class value_semantic_codecvt_helper {\r
79         // Nothing here. Specializations to follow.\r
80     };\r
81 \r
82     /** Helper conversion class for values that accept ascii\r
83         strings as input.\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
88     */\r
89     template<>\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
95                    bool utf8) const;\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
99             const = 0;\r
100     };\r
101 \r
102     /** Helper conversion class for values that accept ascii\r
103         strings as input.\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
108     */\r
109     template<>\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
115                    bool utf8) const;\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
120             const = 0;\r
121 #endif\r
122     };\r
123 \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
128     public:\r
129         untyped_value(bool zero_tokens = false)\r
130         : m_zero_tokens(zero_tokens)\r
131         {}\r
132 \r
133         std::string name() const;\r
134 \r
135         unsigned min_tokens() const;\r
136         unsigned max_tokens() const;\r
137 \r
138         bool is_composing() const { return false; }\r
139 \r
140         bool is_required() const { return false; }\r
141         \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
145             any modifications.\r
146          */\r
147         void xparse(boost::any& value_store,\r
148                     const std::vector<std::string>& new_tokens) const;\r
149 \r
150         /** Does nothing. */\r
151         bool apply_default(boost::any&) const { return false; }\r
152 \r
153         /** Does nothing. */\r
154         void notify(const boost::any&) const {}        \r
155     private:\r
156         bool m_zero_tokens;\r
157     };\r
158 \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
164     */\r
165     class typed_value_base \r
166     {\r
167     public:\r
168         // Returns the type of the value described by this\r
169         // object.\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
174     };\r
175 \r
176 \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
181     {\r
182     public:\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
188           m_required(false)\r
189         {} \r
190 \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
194         */\r
195         typed_value* default_value(const T& v)\r
196         {\r
197             m_default_value = boost::any(v);\r
198             m_default_value_as_text = boost::lexical_cast<std::string>(v);\r
199             return this;\r
200         }\r
201 \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
206             by the user.\r
207         */\r
208         typed_value* default_value(const T& v, const std::string& textual)\r
209         {\r
210             m_default_value = boost::any(v);\r
211             m_default_value_as_text = textual;\r
212             return this;\r
213         }\r
214 \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
221         */\r
222         typed_value* implicit_value(const T &v)\r
223         {\r
224             m_implicit_value = boost::any(v);\r
225             m_implicit_value_as_text =\r
226                 boost::lexical_cast<std::string>(v);\r
227             return this;\r
228         }\r
229 \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
239         */\r
240         typed_value* implicit_value(const T &v, const std::string& textual)\r
241         {\r
242             m_implicit_value = boost::any(v);\r
243             m_implicit_value_as_text = textual;\r
244             return this;\r
245         }\r
246 \r
247         /** Specifies a function to be called when the final value\r
248             is determined. */\r
249         typed_value* notifier(function1<void, const T&> f)\r
250         {\r
251             m_notifier = f;\r
252             return this;\r
253         }\r
254 \r
255         /** Specifies that the value is composing. See the 'is_composing' \r
256             method for explanation. \r
257         */\r
258         typed_value* composing()\r
259         {\r
260             m_composing = true;\r
261             return this;\r
262         }\r
263 \r
264         /** Specifies that the value can span multiple tokens. */\r
265         typed_value* multitoken()\r
266         {\r
267             m_multitoken = true;\r
268             return this;\r
269         }\r
270 \r
271         typed_value* zero_tokens() \r
272         {\r
273             m_zero_tokens = true;\r
274             return this;\r
275         }\r
276             \r
277         /** Specifies that the value must occur. */\r
278         typed_value* required()\r
279         {\r
280             m_required = true;\r
281             return this;\r
282         }\r
283 \r
284     public: // value semantic overrides\r
285 \r
286         std::string name() const;\r
287 \r
288         bool is_composing() const { return m_composing; }\r
289 \r
290         unsigned min_tokens() const\r
291         {\r
292             if (m_zero_tokens || !m_implicit_value.empty()) {\r
293                 return 0;\r
294             } else {\r
295                 return 1;\r
296             }\r
297         }\r
298 \r
299         unsigned max_tokens() const {\r
300             if (m_multitoken) {\r
301                 return 32000;\r
302             } else if (m_zero_tokens) {\r
303                 return 0;\r
304             } else {\r
305                 return 1;\r
306             }\r
307         }\r
308 \r
309         bool is_required() const { return m_required; }\r
310 \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
315             const;\r
316 \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
320         */\r
321         virtual bool apply_default(boost::any& value_store) const\r
322         {\r
323             if (m_default_value.empty()) {\r
324                 return false;\r
325             } else {\r
326                 value_store = m_default_value;\r
327                 return true;\r
328             }\r
329         }\r
330 \r
331         /** If an address of variable to store value was specified\r
332             when creating *this, stores the value there. Otherwise,\r
333             does nothing. */\r
334         void notify(const boost::any& value_store) const;\r
335 \r
336     public: // typed_value_base overrides\r
337         \r
338         const std::type_info& value_type() const\r
339         {\r
340             return typeid(T);\r
341         }\r
342         \r
343 \r
344     private:\r
345         T* m_store_to;\r
346         \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
355     };\r
356 \r
357 \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
363     */\r
364     template<class T>\r
365     typed_value<T>*\r
366     value();\r
367 \r
368     /** @overload \r
369     */\r
370     template<class T>\r
371     typed_value<T>*\r
372     value(T* v);\r
373 \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
377     */\r
378     template<class T>\r
379     typed_value<T, wchar_t>*\r
380     wvalue();\r
381 \r
382     /** @overload   \r
383     */\r
384     template<class T>\r
385     typed_value<T, wchar_t>*\r
386     wvalue(T* v);\r
387 \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
391     */\r
392     BOOST_PROGRAM_OPTIONS_DECL typed_value<bool>*\r
393     bool_switch();\r
394 \r
395     /** @overload\r
396     */\r
397     BOOST_PROGRAM_OPTIONS_DECL typed_value<bool>*    \r
398     bool_switch(bool* v);\r
399 \r
400 }}\r
401 \r
402 #include "boost/program_options/detail/value_semantic.hpp"\r
403 \r
404 #endif\r
405 \r