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

Revision 857, 5.8 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// This file defines template functions that are declared in
7// ../value_semantic.hpp.
8
9#include <boost/throw_exception.hpp>
10
11namespace boost { namespace program_options {
12
13    extern BOOST_PROGRAM_OPTIONS_DECL std::string arg;
14   
15    template<class T, class charT>
16    std::string
17    typed_value<T, charT>::name() const
18    {
19        if (!m_default_value.empty() && !m_default_value_as_text.empty()) {
20            return arg + " (=" + m_default_value_as_text + ")";
21        } else {
22            return arg;
23        }
24    }
25
26    template<class T, class charT>
27    void
28    typed_value<T, charT>::notify(const boost::any& value_store) const
29    {
30        const T* value = boost::any_cast<const T>(&value_store);
31        if (m_store_to) {
32            *m_store_to = *value;
33        }
34        if (m_notifier) {
35            m_notifier(*value);
36        }
37    }
38
39    namespace validators {
40        /* If v.size() > 1, throw validation_error.
41           If v.size() == 1, return v.front()
42           Otherwise, returns a reference to a statically allocated
43           empty string if 'allow_empty' and throws validation_error
44           otherwise. */
45        template<class charT>
46        const std::basic_string<charT>& get_single_string(
47            const std::vector<std::basic_string<charT> >& v,
48            bool allow_empty = false)
49        {
50            static std::basic_string<charT> empty;
51            if (v.size() > 1)
52                throw validation_error("multiple values not allowed");
53            if (v.size() == 1)
54                return v.front();
55            else if (allow_empty)
56                return empty;
57            else
58                throw validation_error("at least one value required");
59        }
60
61        /* Throws multiple_occurrences if 'value' is not empty. */
62        BOOST_PROGRAM_OPTIONS_DECL void
63        check_first_occurrence(const boost::any& value);
64    }
65
66    using namespace validators;
67
68    /** Validates 's' and updates 'v'.
69        @pre 'v' is either empty or in the state assigned by the previous
70        invocation of 'validate'.
71        The target type is specified via a parameter which has the type of
72        pointer to the desired type. This is workaround for compilers without
73        partial template ordering, just like the last 'long/int' parameter.
74    */
75    template<class T, class charT>
76    void validate(boost::any& v,
77                  const std::vector< std::basic_string<charT> >& xs,
78                  T*, long)
79    {
80        validators::check_first_occurrence(v);
81        std::basic_string<charT> s(validators::get_single_string(xs));
82        try {
83            v = any(lexical_cast<T>(s));
84        }
85        catch(const bad_lexical_cast&) {
86            boost::throw_exception(invalid_option_value(s));
87        }
88    }
89
90    BOOST_PROGRAM_OPTIONS_DECL void validate(boost::any& v,
91                       const std::vector<std::string>& xs,
92                       bool*,
93                       int);
94
95#if !defined(BOOST_NO_STD_WSTRING)
96    BOOST_PROGRAM_OPTIONS_DECL void validate(boost::any& v,
97                       const std::vector<std::wstring>& xs,
98                       bool*,
99                       int);
100#endif
101    // For some reason, this declaration, which is require by the standard,
102    // cause gcc 3.2 to not generate code to specialization defined in
103    // value_semantic.cpp
104#if ! ( ( BOOST_WORKAROUND(__GNUC__, <= 3) &&\
105          BOOST_WORKAROUND(__GNUC_MINOR__, < 3) ) || \
106        ( BOOST_WORKAROUND(BOOST_MSVC, == 1310) ) \
107      )
108    BOOST_PROGRAM_OPTIONS_DECL void validate(boost::any& v,
109                       const std::vector<std::string>& xs,
110                       std::string*,
111                       int);
112
113#if !defined(BOOST_NO_STD_WSTRING)
114    BOOST_PROGRAM_OPTIONS_DECL void validate(boost::any& v,
115                       const std::vector<std::wstring>& xs,
116                       std::string*,
117                       int);
118#endif
119#endif
120
121    /** Validates sequences. Allows multiple values per option occurrence
122       and multiple occurrences. */
123    template<class T, class charT>
124    void validate(boost::any& v,
125                  const std::vector<std::basic_string<charT> >& s,
126                  std::vector<T>*,
127                  int)
128    {
129        if (v.empty()) {
130            v = boost::any(std::vector<T>());
131        }
132        std::vector<T>* tv = boost::any_cast< std::vector<T> >(&v);
133        assert(NULL != tv);
134        for (unsigned i = 0; i < s.size(); ++i)
135        {
136            try {
137                tv->push_back(boost::lexical_cast<T>(s[i]));
138            }
139            catch(const bad_lexical_cast& /*e*/) {
140                boost::throw_exception(invalid_option_value(s[i]));
141            }
142        }
143    }
144
145    template<class T, class charT>
146    void
147    typed_value<T, charT>::
148    xparse(boost::any& value_store,
149           const std::vector<std::basic_string<charT> >& new_tokens) const
150    {
151        validate(value_store, new_tokens, (T*)0, 0);
152    }
153
154    template<class T>
155    typed_value<T>*
156    value()
157    {
158        // Explicit qualification is vc6 workaround.
159        return boost::program_options::value<T>(0);
160    }
161
162    template<class T>
163    typed_value<T>*
164    value(T* v)
165    {
166        typed_value<T>* r = new typed_value<T>(v);
167
168        return r;       
169    }
170
171    template<class T>
172    typed_value<T, wchar_t>*
173    wvalue()
174    {
175        return wvalue<T>(0);
176    }
177
178    template<class T>
179    typed_value<T, wchar_t>*
180    wvalue(T* v)
181    {
182        typed_value<T, wchar_t>* r = new typed_value<T, wchar_t>(v);
183
184        return r;       
185    }
186
187
188
189}}
Note: See TracBrowser for help on using the repository browser.