summaryrefslogtreecommitdiff
path: root/boost/program_options/detail
diff options
context:
space:
mode:
authorAnas Nashif <anas.nashif@intel.com>2012-10-30 12:57:26 -0700
committerAnas Nashif <anas.nashif@intel.com>2012-10-30 12:57:26 -0700
commit1a78a62555be32868418fe52f8e330c9d0f95d5a (patch)
treed3765a80e7d3b9640ec2e930743630cd6b9fce2b /boost/program_options/detail
downloadboost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.gz
boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.bz2
boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.zip
Imported Upstream version 1.49.0upstream/1.49.0
Diffstat (limited to 'boost/program_options/detail')
-rw-r--r--boost/program_options/detail/cmdline.hpp147
-rw-r--r--boost/program_options/detail/config_file.hpp182
-rw-r--r--boost/program_options/detail/convert.hpp107
-rw-r--r--boost/program_options/detail/parsers.hpp146
-rw-r--r--boost/program_options/detail/utf8_codecvt_facet.hpp25
-rw-r--r--boost/program_options/detail/value_semantic.hpp207
6 files changed, 814 insertions, 0 deletions
diff --git a/boost/program_options/detail/cmdline.hpp b/boost/program_options/detail/cmdline.hpp
new file mode 100644
index 0000000000..7c431525f4
--- /dev/null
+++ b/boost/program_options/detail/cmdline.hpp
@@ -0,0 +1,147 @@
+// Copyright Vladimir Prus 2002-2004.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_CMDLINE_VP_2003_05_19
+#define BOOST_CMDLINE_VP_2003_05_19
+
+#include <boost/program_options/config.hpp>
+#include <boost/program_options/errors.hpp>
+#include <boost/program_options/cmdline.hpp>
+#include <boost/program_options/option.hpp>
+#include <boost/program_options/options_description.hpp>
+#include <boost/program_options/positional_options.hpp>
+
+
+#include <boost/detail/workaround.hpp>
+
+#include <boost/function.hpp>
+
+#include <string>
+#include <vector>
+
+#if defined(BOOST_MSVC)
+# pragma warning (push)
+# pragma warning (disable:4251) // class 'std::vector<_Ty>' needs to have dll-interface to be used by clients of class 'boost::program_options::positional_options_description'
+#endif
+
+namespace boost { namespace program_options { namespace detail {
+
+ /** Command line parser class. Main requirements were:
+ - Powerful enough to support all common uses.
+ - Simple and easy to learn/use.
+ - Minimal code size and external dependencies.
+ - Extensible for custom syntaxes.
+
+ First all options are registered. After that, elements of command line
+ are extracted using operator++.
+
+ For each element, user can find
+ - if it's an option or an argument
+ - name of the option
+ - index of the option
+ - option value(s), if any
+
+ Sometimes the registered option name is not equal to the encountered
+ one, for example, because name abbreviation is supported. Therefore
+ two option names can be obtained:
+ - the registered one
+ - the one found at the command line
+
+ There are lot of style options, which can be used to tune the command
+ line parsing. In addition, it's possible to install additional parser
+ which will process custom option styles.
+
+ @todo mininal match length for guessing?
+ */
+ class BOOST_PROGRAM_OPTIONS_DECL cmdline {
+ public:
+
+ typedef ::boost::program_options::command_line_style::style_t style_t;
+
+ typedef function1<std::pair<std::string, std::string>,
+ const std::string&>
+ additional_parser;
+
+ typedef function1<std::vector<option>, std::vector<std::string>&>
+ style_parser;
+
+ /** Constructs a command line parser for (argc, argv) pair. Uses
+ style options passed in 'style', which should be binary or'ed values
+ of style_t enum. It can also be zero, in which case a "default"
+ style will be used. If 'allow_unregistered' is true, then allows
+ unregistered options. They will be assigned index 1 and are
+ assumed to have optional parameter.
+ */
+ cmdline(const std::vector<std::string>& args);
+
+ /** @overload */
+ cmdline(int argc, const char*const * argv);
+
+ void style(int style);
+ void allow_unregistered();
+
+ void set_options_description(const options_description& desc);
+ void set_positional_options(
+ const positional_options_description& m_positional);
+
+ std::vector<option> run();
+
+ std::vector<option> parse_long_option(std::vector<std::string>& args);
+ std::vector<option> parse_short_option(std::vector<std::string>& args);
+ std::vector<option> parse_dos_option(std::vector<std::string>& args);
+ std::vector<option> parse_disguised_long_option(
+ std::vector<std::string>& args);
+ std::vector<option> parse_terminator(
+ std::vector<std::string>& args);
+ std::vector<option> handle_additional_parser(
+ std::vector<std::string>& args);
+
+
+ /** Set additional parser. This will be called for each token
+ of command line. If first string in pair is not empty,
+ then the token is considered matched by this parser,
+ and the first string will be considered an option name
+ (which can be long or short), while the second will be
+ option's parameter (if not empty).
+ Note that additional parser can match only one token.
+ */
+ void set_additional_parser(additional_parser p);
+
+ void extra_style_parser(style_parser s);
+
+ void check_style(int style) const;
+
+ bool is_style_active(style_t style) const;
+
+ void init(const std::vector<std::string>& args);
+
+ void
+ finish_option(option& opt,
+ std::vector<std::string>& other_tokens,
+ const std::vector<style_parser>& style_parsers);
+
+ // Copies of input.
+ std::vector<std::string> args;
+ style_t m_style;
+ bool m_allow_unregistered;
+
+ const options_description* m_desc;
+ const positional_options_description* m_positional;
+
+ additional_parser m_additional_parser;
+ style_parser m_style_parser;
+ };
+
+ void test_cmdline_detail();
+
+}}}
+
+#if defined(BOOST_MSVC)
+# pragma warning (pop)
+#endif
+
+#endif
+
diff --git a/boost/program_options/detail/config_file.hpp b/boost/program_options/detail/config_file.hpp
new file mode 100644
index 0000000000..91caac754d
--- /dev/null
+++ b/boost/program_options/detail/config_file.hpp
@@ -0,0 +1,182 @@
+// Copyright Vladimir Prus 2002-2004.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_CONFIG_FILE_VP_2003_01_02
+#define BOOST_CONFIG_FILE_VP_2003_01_02
+
+#include <iosfwd>
+#include <string>
+#include <set>
+
+#include <boost/noncopyable.hpp>
+#include <boost/program_options/config.hpp>
+#include <boost/program_options/option.hpp>
+#include <boost/program_options/eof_iterator.hpp>
+
+#include <boost/detail/workaround.hpp>
+#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202))
+#include <boost/program_options/detail/convert.hpp>
+#endif
+
+#if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042))
+#include <istream> // std::getline
+#endif
+
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/shared_ptr.hpp>
+
+
+
+namespace boost { namespace program_options { namespace detail {
+
+ /** Standalone parser for config files in ini-line format.
+ The parser is a model of single-pass lvalue iterator, and
+ default constructor creates past-the-end-iterator. The typical usage is:
+ config_file_iterator i(is, ... set of options ...), e;
+ for(; i !=e; ++i) {
+ *i;
+ }
+
+ Syntax conventions:
+
+ - config file can not contain positional options
+ - '#' is comment character: it is ignored together with
+ the rest of the line.
+ - variable assignments are in the form
+ name '=' value.
+ spaces around '=' are trimmed.
+ - Section names are given in brackets.
+
+ The actual option name is constructed by combining current section
+ name and specified option name, with dot between. If section_name
+ already contains dot at the end, new dot is not inserted. For example:
+ @verbatim
+ [gui.accessibility]
+ visual_bell=yes
+ @endverbatim
+ will result in option "gui.accessibility.visual_bell" with value
+ "yes" been returned.
+
+ TODO: maybe, we should just accept a pointer to options_description
+ class.
+ */
+ class common_config_file_iterator
+ : public eof_iterator<common_config_file_iterator, option>
+ {
+ public:
+ common_config_file_iterator() { found_eof(); }
+ common_config_file_iterator(
+ const std::set<std::string>& allowed_options,
+ bool allow_unregistered = false);
+
+ virtual ~common_config_file_iterator() {}
+
+ public: // Method required by eof_iterator
+
+ void get();
+
+ protected: // Stubs for derived classes
+
+ // Obtains next line from the config file
+ // Note: really, this design is a bit ugly
+ // The most clean thing would be to pass 'line_iterator' to
+ // constructor of this class, but to avoid templating this class
+ // we'd need polymorphic iterator, which does not exist yet.
+ virtual bool getline(std::string&) { return false; }
+
+ private:
+ /** Adds another allowed option. If the 'name' ends with
+ '*', then all options with the same prefix are
+ allowed. For example, if 'name' is 'foo*', then 'foo1' and
+ 'foo_bar' are allowed. */
+ void add_option(const char* name);
+
+ // Returns true if 's' is a registered option name.
+ bool allowed_option(const std::string& s) const;
+
+ // That's probably too much data for iterator, since
+ // it will be copied, but let's not bother for now.
+ std::set<std::string> allowed_options;
+ // Invariant: no element is prefix of other element.
+ std::set<std::string> allowed_prefixes;
+ std::string m_prefix;
+ bool m_allow_unregistered;
+ };
+
+ template<class charT>
+ class basic_config_file_iterator : public common_config_file_iterator {
+ public:
+ basic_config_file_iterator()
+ {
+ found_eof();
+ }
+
+ /** Creates a config file parser for the specified stream.
+ */
+ basic_config_file_iterator(std::basic_istream<charT>& is,
+ const std::set<std::string>& allowed_options,
+ bool allow_unregistered = false);
+
+ private: // base overrides
+
+ bool getline(std::string&);
+
+ private: // internal data
+ shared_ptr<std::basic_istream<charT> > is;
+ };
+
+ typedef basic_config_file_iterator<char> config_file_iterator;
+ typedef basic_config_file_iterator<wchar_t> wconfig_file_iterator;
+
+
+ struct null_deleter
+ {
+ void operator()(void const *) const {}
+ };
+
+
+ template<class charT>
+ basic_config_file_iterator<charT>::
+ basic_config_file_iterator(std::basic_istream<charT>& is,
+ const std::set<std::string>& allowed_options,
+ bool allow_unregistered)
+ : common_config_file_iterator(allowed_options, allow_unregistered)
+ {
+ this->is.reset(&is, null_deleter());
+ get();
+ }
+
+ // Specializing this function for wchar_t causes problems on
+ // borland and vc7, as well as on metrowerks. On the first two
+ // I don't know a workaround, so make use of 'to_internal' to
+ // avoid specialization.
+ template<class charT>
+ bool
+ basic_config_file_iterator<charT>::getline(std::string& s)
+ {
+ std::basic_string<charT> in;
+ if (std::getline(*is, in)) {
+ s = to_internal(in);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ // Specialization is needed to workaround getline bug on Comeau.
+#if BOOST_WORKAROUND(__COMO_VERSION__, BOOST_TESTED_AT(4303)) || \
+ (defined(__sgi) && BOOST_WORKAROUND(_COMPILER_VERSION, BOOST_TESTED_AT(741)))
+ template<>
+ bool
+ basic_config_file_iterator<wchar_t>::getline(std::string& s);
+#endif
+
+
+
+}}}
+
+#endif
diff --git a/boost/program_options/detail/convert.hpp b/boost/program_options/detail/convert.hpp
new file mode 100644
index 0000000000..a22dd6f37c
--- /dev/null
+++ b/boost/program_options/detail/convert.hpp
@@ -0,0 +1,107 @@
+// Copyright Vladimir Prus 2004.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_CONVERT_HPP_VP_2004_04_28
+#define BOOST_CONVERT_HPP_VP_2004_04_28
+
+#include <boost/program_options/config.hpp>
+
+#if !defined(BOOST_NO_STD_WSTRING)
+
+#include <boost/detail/workaround.hpp>
+
+#include <string>
+#include <vector>
+#include <locale>
+// for mbstate_t
+#include <cwchar>
+#include <stdexcept>
+
+#if defined(BOOST_NO_STDC_NAMESPACE)
+#include <wchar.h>
+namespace std
+{
+ using ::mbstate_t;
+}
+#endif
+
+namespace boost {
+
+ /** Converts from local 8 bit encoding into wchar_t string using
+ the specified locale facet. */
+ BOOST_PROGRAM_OPTIONS_DECL std::wstring
+ from_8_bit(const std::string& s,
+ const std::codecvt<wchar_t, char, std::mbstate_t>& cvt);
+
+ /** Converts from wchar_t string into local 8 bit encoding into using
+ the specified locale facet. */
+ BOOST_PROGRAM_OPTIONS_DECL std::string
+ to_8_bit(const std::wstring& s,
+ const std::codecvt<wchar_t, char, std::mbstate_t>& cvt);
+
+
+ /** Converts 's', which is assumed to be in UTF8 encoding, into wide
+ string. */
+ BOOST_PROGRAM_OPTIONS_DECL std::wstring
+ from_utf8(const std::string& s);
+
+ /** Converts wide string 's' into string in UTF8 encoding. */
+ BOOST_PROGRAM_OPTIONS_DECL std::string
+ to_utf8(const std::wstring& s);
+
+ /** Converts wide string 's' into local 8 bit encoding determined by
+ the current locale. */
+ BOOST_PROGRAM_OPTIONS_DECL std::string
+ to_local_8_bit(const std::wstring& s);
+
+ /** Converts 's', which is assumed to be in local 8 bit encoding, into wide
+ string. */
+ BOOST_PROGRAM_OPTIONS_DECL std::wstring
+ from_local_8_bit(const std::string& s);
+
+ namespace program_options
+ {
+ /** Convert the input string into internal encoding used by
+ program_options. Presence of this function allows to avoid
+ specializing all methods which access input on wchar_t.
+ */
+ BOOST_PROGRAM_OPTIONS_DECL std::string to_internal(const std::string&);
+ /** @overload */
+ BOOST_PROGRAM_OPTIONS_DECL std::string to_internal(const std::wstring&);
+
+ template<class T>
+ std::vector<std::string> to_internal(const std::vector<T>& s)
+ {
+ std::vector<std::string> result;
+ for (unsigned i = 0; i < s.size(); ++i)
+ result.push_back(to_internal(s[i]));
+ return result;
+ }
+
+ }
+
+
+
+}
+
+#else
+#include <vector>
+#include <string>
+namespace boost{
+ namespace program_options{
+ BOOST_PROGRAM_OPTIONS_DECL std::string to_internal(const std::string&);
+
+ template<class T>
+ std::vector<std::string> to_internal(const std::vector<T>& s)
+ {
+ std::vector<std::string> result;
+ for (unsigned i = 0; i < s.size(); ++i)
+ result.push_back(to_internal(s[i]));
+ return result;
+ }
+ }
+}
+#endif
+#endif
diff --git a/boost/program_options/detail/parsers.hpp b/boost/program_options/detail/parsers.hpp
new file mode 100644
index 0000000000..a1124b277f
--- /dev/null
+++ b/boost/program_options/detail/parsers.hpp
@@ -0,0 +1,146 @@
+// Copyright Vladimir Prus 2004.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PARSERS_HPP_VP_2004_05_06
+#define BOOST_PARSERS_HPP_VP_2004_05_06
+
+#include <boost/program_options/detail/convert.hpp>
+
+#include <iterator>
+
+namespace boost { namespace program_options {
+
+ namespace detail {
+ template<class charT, class Iterator>
+ std::vector<std::basic_string<charT> >
+ make_vector(Iterator i, Iterator e)
+ {
+ std::vector<std::basic_string<charT> > result;
+ // Some compilers don't have templated constructor for
+ // vector, so we can't create vector from (argv+1, argv+argc) range
+ for(; i != e; ++i)
+ result.push_back(*i);
+ return result;
+ }
+ }
+
+ template<class charT>
+ basic_command_line_parser<charT>::
+ basic_command_line_parser(const std::vector<
+ std::basic_string<charT> >& xargs)
+ : detail::cmdline(to_internal(xargs))
+ {}
+
+
+ template<class charT>
+ basic_command_line_parser<charT>::
+ basic_command_line_parser(int argc, const charT* const argv[])
+ : detail::cmdline(
+ // Explicit template arguments are required by gcc 3.3.1
+ // (at least mingw version), and do no harm on other compilers.
+ to_internal(detail::make_vector<charT, const charT* const*>(argv+1, argv+argc+!argc)))
+ {}
+
+
+ template<class charT>
+ basic_command_line_parser<charT>&
+ basic_command_line_parser<charT>::options(const options_description& desc)
+ {
+ detail::cmdline::set_options_description(desc);
+ m_desc = &desc;
+ return *this;
+ }
+
+ template<class charT>
+ basic_command_line_parser<charT>&
+ basic_command_line_parser<charT>::positional(
+ const positional_options_description& desc)
+ {
+ detail::cmdline::set_positional_options(desc);
+ return *this;
+ }
+
+ template<class charT>
+ basic_command_line_parser<charT>&
+ basic_command_line_parser<charT>::style(int xstyle)
+ {
+ detail::cmdline::style(xstyle);
+ return *this;
+ }
+
+ template<class charT>
+ basic_command_line_parser<charT>&
+ basic_command_line_parser<charT>::extra_parser(ext_parser ext)
+ {
+ detail::cmdline::set_additional_parser(ext);
+ return *this;
+ }
+
+ template<class charT>
+ basic_command_line_parser<charT>&
+ basic_command_line_parser<charT>::allow_unregistered()
+ {
+ detail::cmdline::allow_unregistered();
+ return *this;
+ }
+
+ template<class charT>
+ basic_command_line_parser<charT>&
+ basic_command_line_parser<charT>::extra_style_parser(style_parser s)
+ {
+ detail::cmdline::extra_style_parser(s);
+ return *this;
+ }
+
+
+
+ template<class charT>
+ basic_parsed_options<charT>
+ basic_command_line_parser<charT>::run()
+ {
+ parsed_options result(m_desc);
+ result.options = detail::cmdline::run();
+
+ // Presense of parsed_options -> wparsed_options conversion
+ // does the trick.
+ return basic_parsed_options<charT>(result);
+ }
+
+
+ template<class charT>
+ basic_parsed_options<charT>
+ parse_command_line(int argc, const charT* const argv[],
+ const options_description& desc,
+ int style,
+ function1<std::pair<std::string, std::string>,
+ const std::string&> ext)
+ {
+ return basic_command_line_parser<charT>(argc, argv).options(desc).
+ style(style).extra_parser(ext).run();
+ }
+
+ template<class charT>
+ std::vector< std::basic_string<charT> >
+ collect_unrecognized(const std::vector< basic_option<charT> >& options,
+ enum collect_unrecognized_mode mode)
+ {
+ std::vector< std::basic_string<charT> > result;
+ for(unsigned i = 0; i < options.size(); ++i)
+ {
+ if (options[i].unregistered ||
+ (mode == include_positional && options[i].position_key != -1))
+ {
+ copy(options[i].original_tokens.begin(),
+ options[i].original_tokens.end(),
+ back_inserter(result));
+ }
+ }
+ return result;
+ }
+
+
+}}
+
+#endif
diff --git a/boost/program_options/detail/utf8_codecvt_facet.hpp b/boost/program_options/detail/utf8_codecvt_facet.hpp
new file mode 100644
index 0000000000..b77b5515fa
--- /dev/null
+++ b/boost/program_options/detail/utf8_codecvt_facet.hpp
@@ -0,0 +1,25 @@
+// Copyright (c) 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu)
+// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu). Permission to copy,
+// use, modify, sell and distribute this software is granted provided this
+// copyright notice appears in all copies. This software is provided "as is"
+// without express or implied warranty, and with no claim as to its suitability
+// for any purpose.
+
+#ifndef BOOST_PROGRAM_OPTIONS_UTF8_CODECVT_FACET_HPP
+#define BOOST_PROGRAM_OPTIONS_UTF8_CODECVT_FACET_HPP
+
+#include <boost/program_options/config.hpp>
+
+#define BOOST_UTF8_BEGIN_NAMESPACE \
+ namespace boost { namespace program_options { namespace detail {
+
+#define BOOST_UTF8_END_NAMESPACE }}}
+#define BOOST_UTF8_DECL BOOST_PROGRAM_OPTIONS_DECL
+
+#include <boost/detail/utf8_codecvt_facet.hpp>
+
+#undef BOOST_UTF8_BEGIN_NAMESPACE
+#undef BOOST_UTF8_END_NAMESPACE
+#undef BOOST_UTF8_DECL
+
+#endif
diff --git a/boost/program_options/detail/value_semantic.hpp b/boost/program_options/detail/value_semantic.hpp
new file mode 100644
index 0000000000..e4b15d7621
--- /dev/null
+++ b/boost/program_options/detail/value_semantic.hpp
@@ -0,0 +1,207 @@
+// Copyright Vladimir Prus 2004.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// This file defines template functions that are declared in
+// ../value_semantic.hpp.
+
+#include <boost/throw_exception.hpp>
+
+namespace boost { namespace program_options {
+
+ extern BOOST_PROGRAM_OPTIONS_DECL std::string arg;
+
+ template<class T, class charT>
+ std::string
+ typed_value<T, charT>::name() const
+ {
+ if (!m_implicit_value.empty() && !m_implicit_value_as_text.empty()) {
+ std::string msg = "[=arg(=" + m_implicit_value_as_text + ")]";
+ if (!m_default_value.empty() && !m_default_value_as_text.empty())
+ msg += " (=" + m_default_value_as_text + ")";
+ return msg;
+ }
+ else if (!m_default_value.empty() && !m_default_value_as_text.empty()) {
+ return arg + " (=" + m_default_value_as_text + ")";
+ } else {
+ return arg;
+ }
+ }
+
+ template<class T, class charT>
+ void
+ typed_value<T, charT>::notify(const boost::any& value_store) const
+ {
+ const T* value = boost::any_cast<T>(&value_store);
+ if (m_store_to) {
+ *m_store_to = *value;
+ }
+ if (m_notifier) {
+ m_notifier(*value);
+ }
+ }
+
+ namespace validators {
+ /* If v.size() > 1, throw validation_error.
+ If v.size() == 1, return v.front()
+ Otherwise, returns a reference to a statically allocated
+ empty string if 'allow_empty' and throws validation_error
+ otherwise. */
+ template<class charT>
+ const std::basic_string<charT>& get_single_string(
+ const std::vector<std::basic_string<charT> >& v,
+ bool allow_empty = false)
+ {
+ static std::basic_string<charT> empty;
+ if (v.size() > 1)
+ boost::throw_exception(validation_error(validation_error::multiple_values_not_allowed));
+ else if (v.size() == 1)
+ return v.front();
+ else if (!allow_empty)
+ boost::throw_exception(validation_error(validation_error::at_least_one_value_required));
+ return empty;
+ }
+
+ /* Throws multiple_occurrences if 'value' is not empty. */
+ BOOST_PROGRAM_OPTIONS_DECL void
+ check_first_occurrence(const boost::any& value);
+ }
+
+ using namespace validators;
+
+ /** Validates 's' and updates 'v'.
+ @pre 'v' is either empty or in the state assigned by the previous
+ invocation of 'validate'.
+ The target type is specified via a parameter which has the type of
+ pointer to the desired type. This is workaround for compilers without
+ partial template ordering, just like the last 'long/int' parameter.
+ */
+ template<class T, class charT>
+ void validate(boost::any& v,
+ const std::vector< std::basic_string<charT> >& xs,
+ T*, long)
+ {
+ validators::check_first_occurrence(v);
+ std::basic_string<charT> s(validators::get_single_string(xs));
+ try {
+ v = any(lexical_cast<T>(s));
+ }
+ catch(const bad_lexical_cast&) {
+ boost::throw_exception(invalid_option_value(s));
+ }
+ }
+
+ BOOST_PROGRAM_OPTIONS_DECL void validate(boost::any& v,
+ const std::vector<std::string>& xs,
+ bool*,
+ int);
+
+#if !defined(BOOST_NO_STD_WSTRING)
+ BOOST_PROGRAM_OPTIONS_DECL void validate(boost::any& v,
+ const std::vector<std::wstring>& xs,
+ bool*,
+ int);
+#endif
+ // For some reason, this declaration, which is require by the standard,
+ // cause gcc 3.2 to not generate code to specialization defined in
+ // value_semantic.cpp
+#if ! ( ( BOOST_WORKAROUND(__GNUC__, <= 3) &&\
+ BOOST_WORKAROUND(__GNUC_MINOR__, < 3) ) || \
+ ( BOOST_WORKAROUND(BOOST_MSVC, == 1310) ) \
+ )
+ BOOST_PROGRAM_OPTIONS_DECL void validate(boost::any& v,
+ const std::vector<std::string>& xs,
+ std::string*,
+ int);
+
+#if !defined(BOOST_NO_STD_WSTRING)
+ BOOST_PROGRAM_OPTIONS_DECL void validate(boost::any& v,
+ const std::vector<std::wstring>& xs,
+ std::string*,
+ int);
+#endif
+#endif
+
+ /** Validates sequences. Allows multiple values per option occurrence
+ and multiple occurrences. */
+ template<class T, class charT>
+ void validate(boost::any& v,
+ const std::vector<std::basic_string<charT> >& s,
+ std::vector<T>*,
+ int)
+ {
+ if (v.empty()) {
+ v = boost::any(std::vector<T>());
+ }
+ std::vector<T>* tv = boost::any_cast< std::vector<T> >(&v);
+ assert(NULL != tv);
+ for (unsigned i = 0; i < s.size(); ++i)
+ {
+ try {
+ /* We call validate so that if user provided
+ a validator for class T, we use it even
+ when parsing vector<T>. */
+ boost::any a;
+ std::vector<std::basic_string<charT> > cv;
+ cv.push_back(s[i]);
+ validate(a, cv, (T*)0, 0);
+ tv->push_back(boost::any_cast<T>(a));
+ }
+ catch(const bad_lexical_cast& /*e*/) {
+ boost::throw_exception(invalid_option_value(s[i]));
+ }
+ }
+ }
+
+ template<class T, class charT>
+ void
+ typed_value<T, charT>::
+ xparse(boost::any& value_store,
+ const std::vector<std::basic_string<charT> >& new_tokens) const
+ {
+ // If no tokens were given, and the option accepts an implicit
+ // value, then assign the implicit value as the stored value;
+ // otherwise, validate the user-provided token(s).
+ if (new_tokens.empty() && !m_implicit_value.empty())
+ value_store = m_implicit_value;
+ else
+ validate(value_store, new_tokens, (T*)0, 0);
+ }
+
+ template<class T>
+ typed_value<T>*
+ value()
+ {
+ // Explicit qualification is vc6 workaround.
+ return boost::program_options::value<T>(0);
+ }
+
+ template<class T>
+ typed_value<T>*
+ value(T* v)
+ {
+ typed_value<T>* r = new typed_value<T>(v);
+
+ return r;
+ }
+
+ template<class T>
+ typed_value<T, wchar_t>*
+ wvalue()
+ {
+ return wvalue<T>(0);
+ }
+
+ template<class T>
+ typed_value<T, wchar_t>*
+ wvalue(T* v)
+ {
+ typed_value<T, wchar_t>* r = new typed_value<T, wchar_t>(v);
+
+ return r;
+ }
+
+
+
+}}