]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/program_options/detail/value_semantic.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / program_options / detail / value_semantic.hpp
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
11 // forward declaration
12 namespace boost { template<class T> class optional; }
13
14 namespace boost { namespace program_options {
15
16 extern BOOST_PROGRAM_OPTIONS_DECL std::string arg;
17
18 template<class T, class charT>
19 std::string
20 typed_value<T, charT>::name() const
21 {
22 std::string const& var = (m_value_name.empty() ? arg : m_value_name);
23 if (!m_implicit_value.empty() && !m_implicit_value_as_text.empty()) {
24 std::string msg = "[=" + var + "(=" + m_implicit_value_as_text + ")]";
25 if (!m_default_value.empty() && !m_default_value_as_text.empty())
26 msg += " (=" + m_default_value_as_text + ")";
27 return msg;
28 }
29 else if (!m_default_value.empty() && !m_default_value_as_text.empty()) {
30 return var + " (=" + m_default_value_as_text + ")";
31 } else {
32 return var;
33 }
34 }
35
36 template<class T, class charT>
37 void
38 typed_value<T, charT>::notify(const boost::any& value_store) const
39 {
40 const T* value = boost::any_cast<T>(&value_store);
41 if (m_store_to) {
42 *m_store_to = *value;
43 }
44 if (m_notifier) {
45 m_notifier(*value);
46 }
47 }
48
49 namespace validators {
50 /* If v.size() > 1, throw validation_error.
51 If v.size() == 1, return v.front()
52 Otherwise, returns a reference to a statically allocated
53 empty string if 'allow_empty' and throws validation_error
54 otherwise. */
55 template<class charT>
56 const std::basic_string<charT>& get_single_string(
57 const std::vector<std::basic_string<charT> >& v,
58 bool allow_empty = false)
59 {
60 static std::basic_string<charT> empty;
61 if (v.size() > 1)
62 boost::throw_exception(validation_error(validation_error::multiple_values_not_allowed));
63 else if (v.size() == 1)
64 return v.front();
65 else if (!allow_empty)
66 boost::throw_exception(validation_error(validation_error::at_least_one_value_required));
67 return empty;
68 }
69
70 /* Throws multiple_occurrences if 'value' is not empty. */
71 BOOST_PROGRAM_OPTIONS_DECL void
72 check_first_occurrence(const boost::any& value);
73 }
74
75 using namespace validators;
76
77 /** Validates 's' and updates 'v'.
78 @pre 'v' is either empty or in the state assigned by the previous
79 invocation of 'validate'.
80 The target type is specified via a parameter which has the type of
81 pointer to the desired type. This is workaround for compilers without
82 partial template ordering, just like the last 'long/int' parameter.
83 */
84 template<class T, class charT>
85 void validate(boost::any& v,
86 const std::vector< std::basic_string<charT> >& xs,
87 T*, long)
88 {
89 validators::check_first_occurrence(v);
90 std::basic_string<charT> s(validators::get_single_string(xs));
91 try {
92 v = any(lexical_cast<T>(s));
93 }
94 catch(const bad_lexical_cast&) {
95 boost::throw_exception(invalid_option_value(s));
96 }
97 }
98
99 BOOST_PROGRAM_OPTIONS_DECL void validate(boost::any& v,
100 const std::vector<std::string>& xs,
101 bool*,
102 int);
103
104 #if !defined(BOOST_NO_STD_WSTRING)
105 BOOST_PROGRAM_OPTIONS_DECL void validate(boost::any& v,
106 const std::vector<std::wstring>& xs,
107 bool*,
108 int);
109 #endif
110 // For some reason, this declaration, which is require by the standard,
111 // cause msvc 7.1 to not generate code to specialization defined in
112 // value_semantic.cpp
113 #if ! ( BOOST_WORKAROUND(BOOST_MSVC, == 1310) )
114 BOOST_PROGRAM_OPTIONS_DECL void validate(boost::any& v,
115 const std::vector<std::string>& xs,
116 std::string*,
117 int);
118
119 #if !defined(BOOST_NO_STD_WSTRING)
120 BOOST_PROGRAM_OPTIONS_DECL void validate(boost::any& v,
121 const std::vector<std::wstring>& xs,
122 std::string*,
123 int);
124 #endif
125 #endif
126
127 /** Validates sequences. Allows multiple values per option occurrence
128 and multiple occurrences. */
129 template<class T, class charT>
130 void validate(boost::any& v,
131 const std::vector<std::basic_string<charT> >& s,
132 std::vector<T>*,
133 int)
134 {
135 if (v.empty()) {
136 v = boost::any(std::vector<T>());
137 }
138 std::vector<T>* tv = boost::any_cast< std::vector<T> >(&v);
139 assert(NULL != tv);
140 for (unsigned i = 0; i < s.size(); ++i)
141 {
142 try {
143 /* We call validate so that if user provided
144 a validator for class T, we use it even
145 when parsing vector<T>. */
146 boost::any a;
147 std::vector<std::basic_string<charT> > cv;
148 cv.push_back(s[i]);
149 validate(a, cv, (T*)0, 0);
150 tv->push_back(boost::any_cast<T>(a));
151 }
152 catch(const bad_lexical_cast& /*e*/) {
153 boost::throw_exception(invalid_option_value(s[i]));
154 }
155 }
156 }
157
158 /** Validates optional arguments. */
159 template<class T, class charT>
160 void validate(boost::any& v,
161 const std::vector<std::basic_string<charT> >& s,
162 boost::optional<T>*,
163 int)
164 {
165 validators::check_first_occurrence(v);
166 validators::get_single_string(s);
167 boost::any a;
168 validate(a, s, (T*)0, 0);
169 v = boost::any(boost::optional<T>(boost::any_cast<T>(a)));
170 }
171
172 template<class T, class charT>
173 void
174 typed_value<T, charT>::
175 xparse(boost::any& value_store,
176 const std::vector<std::basic_string<charT> >& new_tokens) const
177 {
178 // If no tokens were given, and the option accepts an implicit
179 // value, then assign the implicit value as the stored value;
180 // otherwise, validate the user-provided token(s).
181 if (new_tokens.empty() && !m_implicit_value.empty())
182 value_store = m_implicit_value;
183 else
184 validate(value_store, new_tokens, (T*)0, 0);
185 }
186
187 template<class T>
188 typed_value<T>*
189 value()
190 {
191 // Explicit qualification is vc6 workaround.
192 return boost::program_options::value<T>(0);
193 }
194
195 template<class T>
196 typed_value<T>*
197 value(T* v)
198 {
199 typed_value<T>* r = new typed_value<T>(v);
200
201 return r;
202 }
203
204 template<class T>
205 typed_value<T, wchar_t>*
206 wvalue()
207 {
208 return wvalue<T>(0);
209 }
210
211 template<class T>
212 typed_value<T, wchar_t>*
213 wvalue(T* v)
214 {
215 typed_value<T, wchar_t>* r = new typed_value<T, wchar_t>(v);
216
217 return r;
218 }
219
220
221
222 }}