annotate DEPENDENCIES/generic/include/boost/program_options/value_semantic.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
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 #ifndef BOOST_VALUE_SEMANTIC_HPP_VP_2004_02_24
Chris@16 7 #define BOOST_VALUE_SEMANTIC_HPP_VP_2004_02_24
Chris@16 8
Chris@16 9 #include <boost/program_options/config.hpp>
Chris@16 10 #include <boost/program_options/errors.hpp>
Chris@16 11
Chris@16 12 #include <boost/any.hpp>
Chris@16 13 #include <boost/function/function1.hpp>
Chris@16 14 #include <boost/lexical_cast.hpp>
Chris@16 15
Chris@16 16
Chris@16 17 #include <string>
Chris@16 18 #include <vector>
Chris@16 19 #include <typeinfo>
Chris@16 20
Chris@16 21 namespace boost { namespace program_options {
Chris@16 22
Chris@16 23 /** Class which specifies how the option's value is to be parsed
Chris@16 24 and converted into C++ types.
Chris@16 25 */
Chris@16 26 class BOOST_PROGRAM_OPTIONS_DECL value_semantic {
Chris@16 27 public:
Chris@16 28 /** Returns the name of the option. The name is only meaningful
Chris@16 29 for automatic help message.
Chris@16 30 */
Chris@16 31 virtual std::string name() const = 0;
Chris@16 32
Chris@16 33 /** The minimum number of tokens for this option that
Chris@16 34 should be present on the command line. */
Chris@16 35 virtual unsigned min_tokens() const = 0;
Chris@16 36
Chris@16 37 /** The maximum number of tokens for this option that
Chris@16 38 should be present on the command line. */
Chris@16 39 virtual unsigned max_tokens() const = 0;
Chris@16 40
Chris@16 41 /** Returns true if values from different sources should be composed.
Chris@16 42 Otherwise, value from the first source is used and values from
Chris@16 43 other sources are discarded.
Chris@16 44 */
Chris@16 45 virtual bool is_composing() const = 0;
Chris@16 46
Chris@16 47 /** Returns true if value must be given. Non-optional value
Chris@16 48
Chris@16 49 */
Chris@16 50 virtual bool is_required() const = 0;
Chris@16 51
Chris@16 52 /** Parses a group of tokens that specify a value of option.
Chris@16 53 Stores the result in 'value_store', using whatever representation
Chris@16 54 is desired. May be be called several times if value of the same
Chris@16 55 option is specified more than once.
Chris@16 56 */
Chris@16 57 virtual void parse(boost::any& value_store,
Chris@16 58 const std::vector<std::string>& new_tokens,
Chris@16 59 bool utf8) const
Chris@16 60 = 0;
Chris@16 61
Chris@16 62 /** Called to assign default value to 'value_store'. Returns
Chris@16 63 true if default value is assigned, and false if no default
Chris@16 64 value exists. */
Chris@16 65 virtual bool apply_default(boost::any& value_store) const = 0;
Chris@16 66
Chris@16 67 /** Called when final value of an option is determined.
Chris@16 68 */
Chris@16 69 virtual void notify(const boost::any& value_store) const = 0;
Chris@16 70
Chris@16 71 virtual ~value_semantic() {}
Chris@16 72 };
Chris@16 73
Chris@16 74 /** Helper class which perform necessary character conversions in the
Chris@16 75 'parse' method and forwards the data further.
Chris@16 76 */
Chris@16 77 template<class charT>
Chris@16 78 class value_semantic_codecvt_helper {
Chris@16 79 // Nothing here. Specializations to follow.
Chris@16 80 };
Chris@16 81
Chris@16 82 /** Helper conversion class for values that accept ascii
Chris@16 83 strings as input.
Chris@16 84 Overrides the 'parse' method and defines new 'xparse'
Chris@16 85 method taking std::string. Depending on whether input
Chris@16 86 to parse is ascii or UTF8, will pass it to xparse unmodified,
Chris@16 87 or with UTF8->ascii conversion.
Chris@16 88 */
Chris@16 89 template<>
Chris@16 90 class BOOST_PROGRAM_OPTIONS_DECL
Chris@16 91 value_semantic_codecvt_helper<char> : public value_semantic {
Chris@16 92 private: // base overrides
Chris@16 93 void parse(boost::any& value_store,
Chris@16 94 const std::vector<std::string>& new_tokens,
Chris@16 95 bool utf8) const;
Chris@16 96 protected: // interface for derived classes.
Chris@16 97 virtual void xparse(boost::any& value_store,
Chris@16 98 const std::vector<std::string>& new_tokens)
Chris@16 99 const = 0;
Chris@16 100 };
Chris@16 101
Chris@16 102 /** Helper conversion class for values that accept ascii
Chris@16 103 strings as input.
Chris@16 104 Overrides the 'parse' method and defines new 'xparse'
Chris@16 105 method taking std::wstring. Depending on whether input
Chris@16 106 to parse is ascii or UTF8, will recode input to Unicode, or
Chris@16 107 pass it unmodified.
Chris@16 108 */
Chris@16 109 template<>
Chris@16 110 class BOOST_PROGRAM_OPTIONS_DECL
Chris@16 111 value_semantic_codecvt_helper<wchar_t> : public value_semantic {
Chris@16 112 private: // base overrides
Chris@16 113 void parse(boost::any& value_store,
Chris@16 114 const std::vector<std::string>& new_tokens,
Chris@16 115 bool utf8) const;
Chris@16 116 protected: // interface for derived classes.
Chris@16 117 #if !defined(BOOST_NO_STD_WSTRING)
Chris@16 118 virtual void xparse(boost::any& value_store,
Chris@16 119 const std::vector<std::wstring>& new_tokens)
Chris@16 120 const = 0;
Chris@16 121 #endif
Chris@16 122 };
Chris@16 123
Chris@16 124 /** Class which specifies a simple handling of a value: the value will
Chris@16 125 have string type and only one token is allowed. */
Chris@16 126 class BOOST_PROGRAM_OPTIONS_DECL
Chris@16 127 untyped_value : public value_semantic_codecvt_helper<char> {
Chris@16 128 public:
Chris@16 129 untyped_value(bool zero_tokens = false)
Chris@16 130 : m_zero_tokens(zero_tokens)
Chris@16 131 {}
Chris@16 132
Chris@16 133 std::string name() const;
Chris@16 134
Chris@16 135 unsigned min_tokens() const;
Chris@16 136 unsigned max_tokens() const;
Chris@16 137
Chris@16 138 bool is_composing() const { return false; }
Chris@16 139
Chris@16 140 bool is_required() const { return false; }
Chris@16 141
Chris@16 142 /** If 'value_store' is already initialized, or new_tokens
Chris@16 143 has more than one elements, throws. Otherwise, assigns
Chris@16 144 the first string from 'new_tokens' to 'value_store', without
Chris@16 145 any modifications.
Chris@16 146 */
Chris@16 147 void xparse(boost::any& value_store,
Chris@16 148 const std::vector<std::string>& new_tokens) const;
Chris@16 149
Chris@16 150 /** Does nothing. */
Chris@16 151 bool apply_default(boost::any&) const { return false; }
Chris@16 152
Chris@16 153 /** Does nothing. */
Chris@16 154 void notify(const boost::any&) const {}
Chris@16 155 private:
Chris@16 156 bool m_zero_tokens;
Chris@16 157 };
Chris@16 158
Chris@16 159 /** Base class for all option that have a fixed type, and are
Chris@16 160 willing to announce this type to the outside world.
Chris@16 161 Any 'value_semantics' for which you want to find out the
Chris@16 162 type can be dynamic_cast-ed to typed_value_base. If conversion
Chris@16 163 succeeds, the 'type' method can be called.
Chris@16 164 */
Chris@16 165 class typed_value_base
Chris@16 166 {
Chris@16 167 public:
Chris@16 168 // Returns the type of the value described by this
Chris@16 169 // object.
Chris@16 170 virtual const std::type_info& value_type() const = 0;
Chris@16 171 // Not really needed, since deletion from this
Chris@16 172 // class is silly, but just in case.
Chris@16 173 virtual ~typed_value_base() {}
Chris@16 174 };
Chris@16 175
Chris@16 176
Chris@16 177 /** Class which handles value of a specific type. */
Chris@16 178 template<class T, class charT = char>
Chris@16 179 class typed_value : public value_semantic_codecvt_helper<charT>,
Chris@16 180 public typed_value_base
Chris@16 181 {
Chris@16 182 public:
Chris@16 183 /** Ctor. The 'store_to' parameter tells where to store
Chris@16 184 the value when it's known. The parameter can be NULL. */
Chris@16 185 typed_value(T* store_to)
Chris@16 186 : m_store_to(store_to), m_composing(false),
Chris@16 187 m_multitoken(false), m_zero_tokens(false),
Chris@16 188 m_required(false)
Chris@16 189 {}
Chris@16 190
Chris@16 191 /** Specifies default value, which will be used
Chris@16 192 if none is explicitly specified. The type 'T' should
Chris@16 193 provide operator<< for ostream.
Chris@16 194 */
Chris@16 195 typed_value* default_value(const T& v)
Chris@16 196 {
Chris@16 197 m_default_value = boost::any(v);
Chris@16 198 m_default_value_as_text = boost::lexical_cast<std::string>(v);
Chris@16 199 return this;
Chris@16 200 }
Chris@16 201
Chris@16 202 /** Specifies default value, which will be used
Chris@16 203 if none is explicitly specified. Unlike the above overload,
Chris@16 204 the type 'T' need not provide operator<< for ostream,
Chris@16 205 but textual representation of default value must be provided
Chris@16 206 by the user.
Chris@16 207 */
Chris@16 208 typed_value* default_value(const T& v, const std::string& textual)
Chris@16 209 {
Chris@16 210 m_default_value = boost::any(v);
Chris@16 211 m_default_value_as_text = textual;
Chris@16 212 return this;
Chris@16 213 }
Chris@16 214
Chris@16 215 /** Specifies an implicit value, which will be used
Chris@16 216 if the option is given, but without an adjacent value.
Chris@16 217 Using this implies that an explicit value is optional, but if
Chris@16 218 given, must be strictly adjacent to the option, i.e.: '-ovalue'
Chris@16 219 or '--option=value'. Giving '-o' or '--option' will cause the
Chris@16 220 implicit value to be applied.
Chris@16 221 */
Chris@16 222 typed_value* implicit_value(const T &v)
Chris@16 223 {
Chris@16 224 m_implicit_value = boost::any(v);
Chris@16 225 m_implicit_value_as_text =
Chris@16 226 boost::lexical_cast<std::string>(v);
Chris@16 227 return this;
Chris@16 228 }
Chris@16 229
Chris@16 230 /** Specifies the name used to to the value in help message. */
Chris@16 231 typed_value* value_name(const std::string& name)
Chris@16 232 {
Chris@16 233 m_value_name = name;
Chris@16 234 return this;
Chris@16 235 }
Chris@16 236
Chris@16 237 /** Specifies an implicit value, which will be used
Chris@16 238 if the option is given, but without an adjacent value.
Chris@16 239 Using this implies that an explicit value is optional, but if
Chris@16 240 given, must be strictly adjacent to the option, i.e.: '-ovalue'
Chris@16 241 or '--option=value'. Giving '-o' or '--option' will cause the
Chris@16 242 implicit value to be applied.
Chris@16 243 Unlike the above overload, the type 'T' need not provide
Chris@16 244 operator<< for ostream, but textual representation of default
Chris@16 245 value must be provided by the user.
Chris@16 246 */
Chris@16 247 typed_value* implicit_value(const T &v, const std::string& textual)
Chris@16 248 {
Chris@16 249 m_implicit_value = boost::any(v);
Chris@16 250 m_implicit_value_as_text = textual;
Chris@16 251 return this;
Chris@16 252 }
Chris@16 253
Chris@16 254 /** Specifies a function to be called when the final value
Chris@16 255 is determined. */
Chris@16 256 typed_value* notifier(function1<void, const T&> f)
Chris@16 257 {
Chris@16 258 m_notifier = f;
Chris@16 259 return this;
Chris@16 260 }
Chris@16 261
Chris@16 262 /** Specifies that the value is composing. See the 'is_composing'
Chris@16 263 method for explanation.
Chris@16 264 */
Chris@16 265 typed_value* composing()
Chris@16 266 {
Chris@16 267 m_composing = true;
Chris@16 268 return this;
Chris@16 269 }
Chris@16 270
Chris@16 271 /** Specifies that the value can span multiple tokens.
Chris@16 272 */
Chris@16 273 typed_value* multitoken()
Chris@16 274 {
Chris@16 275 m_multitoken = true;
Chris@16 276 return this;
Chris@16 277 }
Chris@16 278
Chris@16 279 /** Specifies that no tokens may be provided as the value of
Chris@16 280 this option, which means that only presense of the option
Chris@16 281 is significant. For such option to be useful, either the
Chris@16 282 'validate' function should be specialized, or the
Chris@16 283 'implicit_value' method should be also used. In most
Chris@16 284 cases, you can use the 'bool_switch' function instead of
Chris@16 285 using this method. */
Chris@16 286 typed_value* zero_tokens()
Chris@16 287 {
Chris@16 288 m_zero_tokens = true;
Chris@16 289 return this;
Chris@16 290 }
Chris@16 291
Chris@16 292 /** Specifies that the value must occur. */
Chris@16 293 typed_value* required()
Chris@16 294 {
Chris@16 295 m_required = true;
Chris@16 296 return this;
Chris@16 297 }
Chris@16 298
Chris@16 299 public: // value semantic overrides
Chris@16 300
Chris@16 301 std::string name() const;
Chris@16 302
Chris@16 303 bool is_composing() const { return m_composing; }
Chris@16 304
Chris@16 305 unsigned min_tokens() const
Chris@16 306 {
Chris@16 307 if (m_zero_tokens || !m_implicit_value.empty()) {
Chris@16 308 return 0;
Chris@16 309 } else {
Chris@16 310 return 1;
Chris@16 311 }
Chris@16 312 }
Chris@16 313
Chris@16 314 unsigned max_tokens() const {
Chris@16 315 if (m_multitoken) {
Chris@16 316 return 32000;
Chris@16 317 } else if (m_zero_tokens) {
Chris@16 318 return 0;
Chris@16 319 } else {
Chris@16 320 return 1;
Chris@16 321 }
Chris@16 322 }
Chris@16 323
Chris@16 324 bool is_required() const { return m_required; }
Chris@16 325
Chris@16 326 /** Creates an instance of the 'validator' class and calls
Chris@16 327 its operator() to perform the actual conversion. */
Chris@16 328 void xparse(boost::any& value_store,
Chris@16 329 const std::vector< std::basic_string<charT> >& new_tokens)
Chris@16 330 const;
Chris@16 331
Chris@16 332 /** If default value was specified via previous call to
Chris@16 333 'default_value', stores that value into 'value_store'.
Chris@16 334 Returns true if default value was stored.
Chris@16 335 */
Chris@16 336 virtual bool apply_default(boost::any& value_store) const
Chris@16 337 {
Chris@16 338 if (m_default_value.empty()) {
Chris@16 339 return false;
Chris@16 340 } else {
Chris@16 341 value_store = m_default_value;
Chris@16 342 return true;
Chris@16 343 }
Chris@16 344 }
Chris@16 345
Chris@16 346 /** If an address of variable to store value was specified
Chris@16 347 when creating *this, stores the value there. Otherwise,
Chris@16 348 does nothing. */
Chris@16 349 void notify(const boost::any& value_store) const;
Chris@16 350
Chris@16 351 public: // typed_value_base overrides
Chris@16 352
Chris@16 353 const std::type_info& value_type() const
Chris@16 354 {
Chris@16 355 return typeid(T);
Chris@16 356 }
Chris@16 357
Chris@16 358
Chris@16 359 private:
Chris@16 360 T* m_store_to;
Chris@16 361
Chris@16 362 // Default value is stored as boost::any and not
Chris@16 363 // as boost::optional to avoid unnecessary instantiations.
Chris@16 364 std::string m_value_name;
Chris@16 365 boost::any m_default_value;
Chris@16 366 std::string m_default_value_as_text;
Chris@16 367 boost::any m_implicit_value;
Chris@16 368 std::string m_implicit_value_as_text;
Chris@16 369 bool m_composing, m_implicit, m_multitoken, m_zero_tokens, m_required;
Chris@16 370 boost::function1<void, const T&> m_notifier;
Chris@16 371 };
Chris@16 372
Chris@16 373
Chris@16 374 /** Creates a typed_value<T> instance. This function is the primary
Chris@16 375 method to create value_semantic instance for a specific type, which
Chris@16 376 can later be passed to 'option_description' constructor.
Chris@16 377 The second overload is used when it's additionally desired to store the
Chris@16 378 value of option into program variable.
Chris@16 379 */
Chris@16 380 template<class T>
Chris@16 381 typed_value<T>*
Chris@16 382 value();
Chris@16 383
Chris@16 384 /** @overload
Chris@16 385 */
Chris@16 386 template<class T>
Chris@16 387 typed_value<T>*
Chris@16 388 value(T* v);
Chris@16 389
Chris@16 390 /** Creates a typed_value<T> instance. This function is the primary
Chris@16 391 method to create value_semantic instance for a specific type, which
Chris@16 392 can later be passed to 'option_description' constructor.
Chris@16 393 */
Chris@16 394 template<class T>
Chris@16 395 typed_value<T, wchar_t>*
Chris@16 396 wvalue();
Chris@16 397
Chris@16 398 /** @overload
Chris@16 399 */
Chris@16 400 template<class T>
Chris@16 401 typed_value<T, wchar_t>*
Chris@16 402 wvalue(T* v);
Chris@16 403
Chris@16 404 /** Works the same way as the 'value<bool>' function, but the created
Chris@16 405 value_semantic won't accept any explicit value. So, if the option
Chris@16 406 is present on the command line, the value will be 'true'.
Chris@16 407 */
Chris@16 408 BOOST_PROGRAM_OPTIONS_DECL typed_value<bool>*
Chris@16 409 bool_switch();
Chris@16 410
Chris@16 411 /** @overload
Chris@16 412 */
Chris@16 413 BOOST_PROGRAM_OPTIONS_DECL typed_value<bool>*
Chris@16 414 bool_switch(bool* v);
Chris@16 415
Chris@16 416 }}
Chris@16 417
Chris@16 418 #include "boost/program_options/detail/value_semantic.hpp"
Chris@16 419
Chris@16 420 #endif
Chris@16 421