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