Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:50:15

0001 // Copyright Vladimir Prus 2004.
0002 // Distributed under the Boost Software License, Version 1.0.
0003 // (See accompanying file LICENSE_1_0.txt
0004 // or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 #ifndef BOOST_VALUE_SEMANTIC_HPP_VP_2004_02_24
0007 #define BOOST_VALUE_SEMANTIC_HPP_VP_2004_02_24
0008 
0009 #include <boost/program_options/config.hpp>
0010 #include <boost/program_options/errors.hpp>
0011 
0012 #include <boost/any.hpp>
0013 #include <boost/function/function1.hpp>
0014 #include <boost/lexical_cast.hpp>
0015 
0016 #include <string>
0017 #include <vector>
0018 #include <typeinfo>
0019 #include <limits>
0020 
0021 namespace boost { namespace program_options {
0022 
0023     /** Class which specifies how the option's value is to be parsed
0024         and converted into C++ types.
0025     */
0026     class BOOST_PROGRAM_OPTIONS_DECL value_semantic {
0027     public:
0028         /** Returns the name of the option. The name is only meaningful
0029             for automatic help message.
0030          */
0031         virtual std::string name() const = 0;
0032 
0033         /** The minimum number of tokens for this option that
0034             should be present on the command line. */
0035         virtual unsigned min_tokens() const = 0;
0036 
0037         /** The maximum number of tokens for this option that
0038             should be present on the command line. */
0039         virtual unsigned max_tokens() const = 0;
0040 
0041         /** Returns true if values from different sources should be composed.
0042             Otherwise, value from the first source is used and values from
0043             other sources are discarded.
0044         */
0045         virtual bool is_composing() const = 0;
0046 
0047         /** Returns true if value must be given. Non-optional value
0048 
0049         */
0050         virtual bool is_required() const = 0;
0051         
0052         /** Parses a group of tokens that specify a value of option.
0053             Stores the result in 'value_store', using whatever representation
0054             is desired. May be be called several times if value of the same
0055             option is specified more than once.
0056         */
0057         virtual void parse(boost::any& value_store, 
0058                            const std::vector<std::string>& new_tokens,
0059                            bool utf8) const 
0060             = 0;
0061 
0062         /** Called to assign default value to 'value_store'. Returns
0063             true if default value is assigned, and false if no default
0064             value exists. */
0065         virtual bool apply_default(boost::any& value_store) const = 0;
0066                                    
0067         /** Called when final value of an option is determined. 
0068         */
0069         virtual void notify(const boost::any& value_store) const = 0;
0070         
0071         virtual ~value_semantic() {}
0072     };
0073 
0074     /** Helper class which perform necessary character conversions in the 
0075         'parse' method and forwards the data further.
0076     */
0077     template<class charT>
0078     class value_semantic_codecvt_helper {
0079         // Nothing here. Specializations to follow.
0080     };
0081 
0082     /** Helper conversion class for values that accept ascii
0083         strings as input.
0084         Overrides the 'parse' method and defines new 'xparse'
0085         method taking std::string. Depending on whether input
0086         to parse is ascii or UTF8, will pass it to xparse unmodified,
0087         or with UTF8->ascii conversion.
0088     */
0089     template<>
0090     class BOOST_PROGRAM_OPTIONS_DECL 
0091     value_semantic_codecvt_helper<char> : public value_semantic {
0092     private: // base overrides
0093         void parse(boost::any& value_store, 
0094                    const std::vector<std::string>& new_tokens,
0095                    bool utf8) const;
0096     protected: // interface for derived classes.
0097         virtual void xparse(boost::any& value_store, 
0098                             const std::vector<std::string>& new_tokens) 
0099             const = 0;
0100     };
0101 
0102     /** Helper conversion class for values that accept ascii
0103         strings as input.
0104         Overrides the 'parse' method and defines new 'xparse'
0105         method taking std::wstring. Depending on whether input
0106         to parse is ascii or UTF8, will recode input to Unicode, or
0107         pass it unmodified.
0108     */
0109     template<>
0110     class BOOST_PROGRAM_OPTIONS_DECL
0111     value_semantic_codecvt_helper<wchar_t> : public value_semantic {
0112     private: // base overrides
0113         void parse(boost::any& value_store, 
0114                    const std::vector<std::string>& new_tokens,
0115                    bool utf8) const;
0116     protected: // interface for derived classes.
0117 #if !defined(BOOST_NO_STD_WSTRING)
0118         virtual void xparse(boost::any& value_store, 
0119                             const std::vector<std::wstring>& new_tokens) 
0120             const = 0;
0121 #endif
0122     };
0123 
0124     /** Class which specifies a simple handling of a value: the value will
0125         have string type and only one token is allowed. */    
0126     class BOOST_PROGRAM_OPTIONS_DECL 
0127     untyped_value : public value_semantic_codecvt_helper<char>  {
0128     public:
0129         untyped_value(bool zero_tokens = false)
0130         : m_zero_tokens(zero_tokens)
0131         {}
0132 
0133         std::string name() const;
0134 
0135         unsigned min_tokens() const;
0136         unsigned max_tokens() const;
0137 
0138         bool is_composing() const { return false; }
0139 
0140         bool is_required() const { return false; }
0141         
0142         /** If 'value_store' is already initialized, or new_tokens
0143             has more than one elements, throws. Otherwise, assigns
0144             the first string from 'new_tokens' to 'value_store', without
0145             any modifications.
0146          */
0147         void xparse(boost::any& value_store,
0148                     const std::vector<std::string>& new_tokens) const;
0149 
0150         /** Does nothing. */
0151         bool apply_default(boost::any&) const { return false; }
0152 
0153         /** Does nothing. */
0154         void notify(const boost::any&) const {}        
0155     private:
0156         bool m_zero_tokens;
0157     };
0158 
0159 #ifndef BOOST_NO_RTTI
0160     /** Base class for all option that have a fixed type, and are
0161         willing to announce this type to the outside world.
0162         Any 'value_semantics' for which you want to find out the
0163         type can be dynamic_cast-ed to typed_value_base. If conversion
0164         succeeds, the 'type' method can be called.
0165     */
0166     class typed_value_base 
0167     {
0168     public:
0169         // Returns the type of the value described by this
0170         // object.
0171         virtual const std::type_info& value_type() const = 0;
0172         // Not really needed, since deletion from this
0173         // class is silly, but just in case.
0174         virtual ~typed_value_base() {}
0175     };
0176 #endif
0177 
0178 
0179     /** Class which handles value of a specific type. */
0180     template<class T, class charT = char>
0181     class typed_value : public value_semantic_codecvt_helper<charT>
0182 #ifndef BOOST_NO_RTTI
0183                       , public typed_value_base
0184 #endif
0185     {
0186     public:
0187         /** Ctor. The 'store_to' parameter tells where to store
0188             the value when it's known. The parameter can be NULL. */
0189         typed_value(T* store_to) 
0190         : m_store_to(store_to), m_composing(false),
0191           m_implicit(false), m_multitoken(false),
0192           m_zero_tokens(false), m_required(false)
0193         {} 
0194 
0195         /** Specifies default value, which will be used
0196             if none is explicitly specified. The type 'T' should
0197             provide operator<< for ostream.
0198         */
0199         typed_value* default_value(const T& v)
0200         {
0201             m_default_value = boost::any(v);
0202             m_default_value_as_text = boost::lexical_cast<std::string>(v);
0203             return this;
0204         }
0205 
0206         /** Specifies default value, which will be used
0207             if none is explicitly specified. Unlike the above overload,
0208             the type 'T' need not provide operator<< for ostream,
0209             but textual representation of default value must be provided
0210             by the user.
0211         */
0212         typed_value* default_value(const T& v, const std::string& textual)
0213         {
0214             m_default_value = boost::any(v);
0215             m_default_value_as_text = textual;
0216             return this;
0217         }
0218 
0219         /** Specifies an implicit value, which will be used
0220             if the option is given, but without an adjacent value.
0221             Using this implies that an explicit value is optional,
0222         */
0223         typed_value* implicit_value(const T &v)
0224         {
0225             m_implicit_value = boost::any(v);
0226             m_implicit_value_as_text =
0227                 boost::lexical_cast<std::string>(v);
0228             return this;
0229         }
0230 
0231         /** Specifies the name used to to the value in help message.  */
0232         typed_value* value_name(const std::string& name)
0233         {
0234             m_value_name = name;
0235             return this;
0236         }
0237 
0238         /** Specifies an implicit value, which will be used
0239             if the option is given, but without an adjacent value.
0240             Using this implies that an explicit value is optional, but if
0241             given, must be strictly adjacent to the option, i.e.: '-ovalue'
0242             or '--option=value'.  Giving '-o' or '--option' will cause the
0243             implicit value to be applied.
0244             Unlike the above overload, the type 'T' need not provide
0245             operator<< for ostream, but textual representation of default
0246             value must be provided by the user.
0247         */
0248         typed_value* implicit_value(const T &v, const std::string& textual)
0249         {
0250             m_implicit_value = boost::any(v);
0251             m_implicit_value_as_text = textual;
0252             return this;
0253         }
0254 
0255         /** Specifies a function to be called when the final value
0256             is determined. */
0257         typed_value* notifier(function1<void, const T&> f)
0258         {
0259             m_notifier = f;
0260             return this;
0261         }
0262 
0263         /** Specifies that the value is composing. See the 'is_composing' 
0264             method for explanation. 
0265         */
0266         typed_value* composing()
0267         {
0268             m_composing = true;
0269             return this;
0270         }
0271 
0272         /** Specifies that the value can span multiple tokens. 
0273         */
0274         typed_value* multitoken()
0275         {
0276             m_multitoken = true;
0277             return this;
0278         }
0279 
0280         /** Specifies that no tokens may be provided as the value of
0281             this option, which means that only presense of the option
0282             is significant. For such option to be useful, either the
0283             'validate' function should be specialized, or the 
0284             'implicit_value' method should be also used. In most
0285             cases, you can use the 'bool_switch' function instead of
0286             using this method. */
0287         typed_value* zero_tokens() 
0288         {
0289             m_zero_tokens = true;
0290             return this;
0291         }
0292             
0293         /** Specifies that the value must occur. */
0294         typed_value* required()
0295         {
0296             m_required = true;
0297             return this;
0298         }
0299 
0300     public: // value semantic overrides
0301 
0302         std::string name() const;
0303 
0304         bool is_composing() const { return m_composing; }
0305 
0306         unsigned min_tokens() const
0307         {
0308             if (m_zero_tokens || !m_implicit_value.empty()) {
0309                 return 0;
0310             } else {
0311                 return 1;
0312             }
0313         }
0314 
0315         unsigned max_tokens() const {
0316             if (m_multitoken) {
0317                 return std::numeric_limits<unsigned>::max BOOST_PREVENT_MACRO_SUBSTITUTION();
0318             } else if (m_zero_tokens) {
0319                 return 0;
0320             } else {
0321                 return 1;
0322             }
0323         }
0324 
0325         bool is_required() const { return m_required; }
0326 
0327         /** Creates an instance of the 'validator' class and calls
0328             its operator() to perform the actual conversion. */
0329         void xparse(boost::any& value_store, 
0330                     const std::vector< std::basic_string<charT> >& new_tokens) 
0331             const;
0332 
0333         /** If default value was specified via previous call to 
0334             'default_value', stores that value into 'value_store'.
0335             Returns true if default value was stored.
0336         */
0337         virtual bool apply_default(boost::any& value_store) const
0338         {
0339             if (m_default_value.empty()) {
0340                 return false;
0341             } else {
0342                 value_store = m_default_value;
0343                 return true;
0344             }
0345         }
0346 
0347         /** If an address of variable to store value was specified
0348             when creating *this, stores the value there. Otherwise,
0349             does nothing. */
0350         void notify(const boost::any& value_store) const;
0351 
0352     public: // typed_value_base overrides
0353         
0354 #ifndef BOOST_NO_RTTI
0355         const std::type_info& value_type() const
0356         {
0357             return typeid(T);
0358         }
0359 #endif
0360         
0361 
0362     private:
0363         T* m_store_to;
0364         
0365         // Default value is stored as boost::any and not
0366         // as boost::optional to avoid unnecessary instantiations.
0367         std::string m_value_name;
0368         boost::any m_default_value;
0369         std::string m_default_value_as_text;
0370         boost::any m_implicit_value;
0371         std::string m_implicit_value_as_text;
0372         bool m_composing, m_implicit, m_multitoken, m_zero_tokens, m_required;
0373         boost::function1<void, const T&> m_notifier;
0374     };
0375 
0376 
0377     /** Creates a typed_value<T> instance. This function is the primary
0378         method to create value_semantic instance for a specific type, which
0379         can later be passed to 'option_description' constructor.
0380         The second overload is used when it's additionally desired to store the 
0381         value of option into program variable.
0382     */
0383     template<class T>
0384     typed_value<T>*
0385     value();
0386 
0387     /** @overload 
0388     */
0389     template<class T>
0390     typed_value<T>*
0391     value(T* v);
0392 
0393     /** Creates a typed_value<T> instance. This function is the primary
0394         method to create value_semantic instance for a specific type, which
0395         can later be passed to 'option_description' constructor.
0396     */
0397     template<class T>
0398     typed_value<T, wchar_t>*
0399     wvalue();
0400 
0401     /** @overload   
0402     */
0403     template<class T>
0404     typed_value<T, wchar_t>*
0405     wvalue(T* v);
0406 
0407     /** Works the same way as the 'value<bool>' function, but the created
0408         value_semantic won't accept any explicit value. So, if the option 
0409         is present on the command line, the value will be 'true'.
0410     */
0411     BOOST_PROGRAM_OPTIONS_DECL typed_value<bool>*
0412     bool_switch();
0413 
0414     /** @overload
0415     */
0416     BOOST_PROGRAM_OPTIONS_DECL typed_value<bool>*    
0417     bool_switch(bool* v);
0418 
0419 }}
0420 
0421 #include "boost/program_options/detail/value_semantic.hpp"
0422 
0423 #endif
0424