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 // This file defines template functions that are declared in
0007 // ../value_semantic.hpp.
0008 
0009 #include <boost/throw_exception.hpp>
0010 
0011 // forward declaration
0012 namespace boost { template<class T> class optional; }
0013 
0014 namespace boost { namespace program_options { 
0015 
0016     extern BOOST_PROGRAM_OPTIONS_DECL std::string arg;
0017     
0018     template<class T, class charT>
0019     std::string
0020     typed_value<T, charT>::name() const
0021     {
0022         std::string const& var = (m_value_name.empty() ? arg : m_value_name);
0023         if (!m_implicit_value.empty() && !m_implicit_value_as_text.empty()) {
0024             std::string msg = "[=" + var + "(=" + m_implicit_value_as_text + ")]";
0025             if (!m_default_value.empty() && !m_default_value_as_text.empty())
0026                 msg += " (=" + m_default_value_as_text + ")";
0027             return msg;
0028         }
0029         else if (!m_default_value.empty() && !m_default_value_as_text.empty()) {
0030             return var + " (=" + m_default_value_as_text + ")";
0031         } else {
0032             return var;
0033         }
0034     }
0035 
0036     template<class T, class charT>
0037     void 
0038     typed_value<T, charT>::notify(const boost::any& value_store) const
0039     {
0040         const T* value = boost::any_cast<T>(&value_store);
0041         if (m_store_to) {
0042             *m_store_to = *value;
0043         }
0044         if (m_notifier) {
0045             m_notifier(*value);
0046         }
0047     }
0048 
0049     namespace validators {
0050         /* If v.size() > 1, throw validation_error. 
0051            If v.size() == 1, return v.front()
0052            Otherwise, returns a reference to a statically allocated
0053            empty string if 'allow_empty' and throws validation_error
0054            otherwise. */
0055         template<class charT>
0056         const std::basic_string<charT>& get_single_string(
0057             const std::vector<std::basic_string<charT> >& v, 
0058             bool allow_empty = false)
0059         {
0060             static std::basic_string<charT> empty;
0061             if (v.size() > 1)
0062                 boost::throw_exception(validation_error(validation_error::multiple_values_not_allowed));
0063             else if (v.size() == 1)
0064                 return v.front();
0065             else if (!allow_empty)
0066                 boost::throw_exception(validation_error(validation_error::at_least_one_value_required));
0067             return empty;
0068         }
0069 
0070         /* Throws multiple_occurrences if 'value' is not empty. */
0071         BOOST_PROGRAM_OPTIONS_DECL void 
0072         check_first_occurrence(const boost::any& value);
0073     }
0074 
0075     using namespace validators;
0076 
0077     /** Validates 's' and updates 'v'.
0078         @pre 'v' is either empty or in the state assigned by the previous
0079         invocation of 'validate'.
0080         The target type is specified via a parameter which has the type of 
0081         pointer to the desired type. This is workaround for compilers without
0082         partial template ordering, just like the last 'long/int' parameter.
0083     */
0084     template<class T, class charT>
0085     void validate(boost::any& v, 
0086                   const std::vector< std::basic_string<charT> >& xs, 
0087                   T*, long)
0088     {
0089         validators::check_first_occurrence(v);
0090         std::basic_string<charT> s(validators::get_single_string(xs));
0091         try {
0092             v = any(lexical_cast<T>(s));
0093         }
0094         catch(const bad_lexical_cast&) {
0095             boost::throw_exception(invalid_option_value(s));
0096         }
0097     }
0098 
0099     BOOST_PROGRAM_OPTIONS_DECL void validate(boost::any& v, 
0100                        const std::vector<std::string>& xs, 
0101                        bool*,
0102                        int);
0103 
0104 #if !defined(BOOST_NO_STD_WSTRING)
0105     BOOST_PROGRAM_OPTIONS_DECL void validate(boost::any& v, 
0106                        const std::vector<std::wstring>& xs, 
0107                        bool*,
0108                        int);
0109 #endif
0110     // For some reason, this declaration, which is require by the standard,
0111     // cause msvc 7.1 to not generate code to specialization defined in
0112     // value_semantic.cpp
0113 #if ! ( BOOST_WORKAROUND(BOOST_MSVC, == 1310) )
0114     BOOST_PROGRAM_OPTIONS_DECL void validate(boost::any& v, 
0115                        const std::vector<std::string>& xs,
0116                        std::string*,
0117                        int);
0118 
0119 #if !defined(BOOST_NO_STD_WSTRING)
0120     BOOST_PROGRAM_OPTIONS_DECL void validate(boost::any& v, 
0121                        const std::vector<std::wstring>& xs,
0122                        std::string*,
0123                        int);
0124 #endif
0125 #endif
0126 
0127     /** Validates sequences. Allows multiple values per option occurrence
0128        and multiple occurrences. */
0129     template<class T, class charT>
0130     void validate(boost::any& v, 
0131                   const std::vector<std::basic_string<charT> >& s, 
0132                   std::vector<T>*,
0133                   int)
0134     {
0135         if (v.empty()) {
0136             v = boost::any(std::vector<T>());
0137         }
0138         std::vector<T>* tv = boost::any_cast< std::vector<T> >(&v);
0139         assert(NULL != tv);
0140         for (unsigned i = 0; i < s.size(); ++i)
0141         {
0142             try {
0143                 /* We call validate so that if user provided
0144                    a validator for class T, we use it even
0145                    when parsing vector<T>.  */
0146                 boost::any a;
0147                 std::vector<std::basic_string<charT> > cv;
0148                 cv.push_back(s[i]);
0149                 validate(a, cv, (T*)0, 0);                
0150                 tv->push_back(boost::any_cast<T>(a));
0151             }
0152             catch(const bad_lexical_cast& /*e*/) {
0153                 boost::throw_exception(invalid_option_value(s[i]));
0154             }
0155         }
0156     }
0157 
0158     /** Validates optional arguments. */
0159     template<class T, class charT>
0160     void validate(boost::any& v,
0161                   const std::vector<std::basic_string<charT> >& s,
0162                   boost::optional<T>*,
0163                   int)
0164     {
0165         validators::check_first_occurrence(v);
0166         validators::get_single_string(s);
0167         boost::any a;
0168         validate(a, s, (T*)0, 0);
0169         v = boost::any(boost::optional<T>(boost::any_cast<T>(a)));
0170     }
0171 
0172     template<class T, class charT>
0173     void 
0174     typed_value<T, charT>::
0175     xparse(boost::any& value_store, 
0176            const std::vector<std::basic_string<charT> >& new_tokens) const
0177     {
0178         // If no tokens were given, and the option accepts an implicit
0179         // value, then assign the implicit value as the stored value;
0180         // otherwise, validate the user-provided token(s).
0181         if (new_tokens.empty() && !m_implicit_value.empty())
0182             value_store = m_implicit_value;
0183         else
0184             validate(value_store, new_tokens, (T*)0, 0);
0185     }
0186 
0187     template<class T>
0188     typed_value<T>*
0189     value()
0190     {
0191         // Explicit qualification is vc6 workaround.
0192         return boost::program_options::value<T>(0);
0193     }
0194 
0195     template<class T>
0196     typed_value<T>*
0197     value(T* v)
0198     {
0199         typed_value<T>* r = new typed_value<T>(v);
0200 
0201         return r;        
0202     }
0203 
0204     template<class T>
0205     typed_value<T, wchar_t>*
0206     wvalue()
0207     {
0208         return wvalue<T>(0);
0209     }
0210 
0211     template<class T>
0212     typed_value<T, wchar_t>*
0213     wvalue(T* v)
0214     {
0215         typed_value<T, wchar_t>* r = new typed_value<T, wchar_t>(v);
0216 
0217         return r;        
0218     }
0219 
0220 
0221 
0222 }}