annotate DEPENDENCIES/generic/include/boost/program_options/detail/value_semantic.hpp @ 125:34e428693f5d vext

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