summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/convert
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/convert')
-rw-r--r--src/boost/libs/convert/README.md7
-rw-r--r--src/boost/libs/convert/example/algorithms.cpp186
-rw-r--r--src/boost/libs/convert/example/default_converter.cpp39
-rw-r--r--src/boost/libs/convert/example/default_converter_fail.cpp20
-rw-r--r--src/boost/libs/convert/example/getting_serious.cpp155
-rw-r--r--src/boost/libs/convert/example/getting_started.cpp268
-rw-r--r--src/boost/libs/convert/example/jamfile.v234
-rw-r--r--src/boost/libs/convert/example/lexical_cast.cpp35
-rw-r--r--src/boost/libs/convert/example/stream.cpp101
-rw-r--r--src/boost/libs/convert/index.html29
-rw-r--r--src/boost/libs/convert/makefile29
-rw-r--r--src/boost/libs/convert/meta/libraries.json11
-rw-r--r--src/boost/libs/convert/test/callable.cpp114
-rw-r--r--src/boost/libs/convert/test/encryption.cpp44
-rw-r--r--src/boost/libs/convert/test/fallbacks.cpp81
-rw-r--r--src/boost/libs/convert/test/has_member.cpp104
-rw-r--r--src/boost/libs/convert/test/is_converter.cpp86
-rw-r--r--src/boost/libs/convert/test/jamfile.v241
-rw-r--r--src/boost/libs/convert/test/lcast_converter.cpp77
-rw-r--r--src/boost/libs/convert/test/performance.cpp317
-rw-r--r--src/boost/libs/convert/test/performance_spirit.cpp112
-rw-r--r--src/boost/libs/convert/test/prepare.hpp59
-rw-r--r--src/boost/libs/convert/test/printf_converter.cpp47
-rw-r--r--src/boost/libs/convert/test/sfinae.cpp159
-rw-r--r--src/boost/libs/convert/test/spirit_converter.cpp87
-rw-r--r--src/boost/libs/convert/test/str_to_int.cpp156
-rw-r--r--src/boost/libs/convert/test/stream_converter.cpp381
-rw-r--r--src/boost/libs/convert/test/strtol_converter.cpp407
-rw-r--r--src/boost/libs/convert/test/test.hpp187
-rw-r--r--src/boost/libs/convert/test/user_type.cpp101
-rw-r--r--src/boost/libs/convert/todo.txt12
31 files changed, 3486 insertions, 0 deletions
diff --git a/src/boost/libs/convert/README.md b/src/boost/libs/convert/README.md
new file mode 100644
index 000000000..1d45aa7b4
--- /dev/null
+++ b/src/boost/libs/convert/README.md
@@ -0,0 +1,7 @@
+The library builds on the `boost::lexical_cast` experience and takes those type conversion/transformation-related ideas further
+
+* to be useful and applicable in a wider range of deployment scenarios,
+* to provide a flexible, extendible and configurable type-conversion framework.
+
+**HTML documentation is available [here](http://boostorg.github.io/convert).**
+
diff --git a/src/boost/libs/convert/example/algorithms.cpp b/src/boost/libs/convert/example/algorithms.cpp
new file mode 100644
index 000000000..6235fbfb3
--- /dev/null
+++ b/src/boost/libs/convert/example/algorithms.cpp
@@ -0,0 +1,186 @@
+// Copyright (c) 2009-2016 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#include <boost/convert.hpp>
+#include <boost/convert/stream.hpp>
+#include <boost/convert/lexical_cast.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/array.hpp>
+#include <boost/bind.hpp>
+#include <vector>
+
+using std::string;
+
+static
+void
+introduction()
+{
+//[algorithm_introduction
+
+ /*`The following code demonstrates conversion of an array of integers from their textual ['hexadecimal]
+ representation. It assigns -1 to those which fail to convert:
+ */
+
+ boost::array<char const*, 3> strs = {{ " 5", "0XF", "not an int" }};
+ std::vector<int> ints;
+ boost::cnv::cstream cnv;
+
+ // Configure converter to read hexadecimal, skip (leading) white spaces.
+ cnv(std::hex)(std::skipws);
+
+ std::transform(strs.begin(), strs.end(), std::back_inserter(ints),
+ boost::cnv::apply<int>(boost::cref(cnv)).value_or(-1));
+
+ BOOST_TEST(ints.size() == 3); // Number of values processed.
+ BOOST_TEST(ints[0] == 5); // " 5"
+ BOOST_TEST(ints[1] == 15); // "0XF"
+ BOOST_TEST(ints[2] == -1); // "not an int"
+//]
+}
+
+static
+void
+example1()
+{
+//[algorithm_example1
+ /*`The following code demonstrates a failed attempt (and one of the reasons ['Boost.Convert]
+ has been developed) to convert a few `string`s to `int`s with `boost::lexical_cast`:
+ */
+
+ boost::array<char const*, 3> strs = {{ " 5", "0XF", "not an int" }};
+ std::vector<int> ints;
+
+ try
+ {
+ std::transform(strs.begin(), strs.end(), std::back_inserter(ints),
+ boost::bind(boost::lexical_cast<int, string>, _1));
+
+ BOOST_TEST(0 && "Never reached!");
+ }
+ catch (std::exception&)
+ {
+ BOOST_TEST(ints.size() == 0); // No strings converted.
+ }
+//]
+}
+
+static
+void
+example2()
+{
+//[algorithm_example2
+ /*`If the exception-throwing behavior is the desired behavior, then ['Boost.Convert] supports that.
+ In addition, it also supports a non-throwing process-flow:
+ */
+ boost::array<char const*, 3> strs = {{ " 5", "0XF", "not an int" }};
+ std::vector<int> ints;
+
+ std::transform(strs.begin(), strs.end(), std::back_inserter(ints),
+ boost::cnv::apply<int>(boost::cnv::lexical_cast()).value_or(-1));
+
+ BOOST_TEST(ints.size() == 3);
+ BOOST_TEST(ints[0] == -1); // Failed conversion does not throw.
+ BOOST_TEST(ints[1] == -1); // Failed conversion does not throw.
+ BOOST_TEST(ints[2] == -1); // Failed conversion does not throw.
+//]
+}
+
+static
+void
+example3()
+{
+//[algorithm_example3
+ /*`Deploying `boost::cnv::cstream` with better formatting capabilities yields
+ better results with exception-throwing and non-throwing process-flows still supported:
+ */
+
+ boost::array<char const*, 3> strs = {{ " 5", "0XF", "not an int" }};
+ std::vector<int> ints;
+ boost::cnv::cstream cnv;
+
+ try
+ {
+ std::transform(strs.begin(), strs.end(), std::back_inserter(ints),
+ boost::cnv::apply<int>(boost::cref(cnv(std::hex)(std::skipws))));
+
+ BOOST_TEST(0 && "Never reached!");
+ }
+ catch (boost::bad_optional_access const&)
+ {
+ BOOST_TEST(ints.size() == 2); // Only the first two strings converted.
+ BOOST_TEST(ints[0] == 5); // " 5"
+ BOOST_TEST(ints[1] == 15); // "0XF"
+
+ // "not an int" causes the exception thrown.
+ }
+//]
+}
+
+static
+void
+example4()
+{
+ boost::array<char const*, 3> strs = {{ " 5", "0XF", "not an int" }};
+ std::vector<int> ints;
+ boost::cnv::cstream cnv;
+
+//[algorithm_example4
+
+ std::transform(strs.begin(), strs.end(), std::back_inserter(ints),
+ boost::cnv::apply<int>(boost::cref(cnv(std::hex)(std::skipws))).value_or(-1));
+
+ BOOST_TEST(ints.size() == 3);
+ BOOST_TEST(ints[0] == 5);
+ BOOST_TEST(ints[1] == 15);
+ BOOST_TEST(ints[2] == -1); // Failed conversion
+
+ /*`[important One notable difference in the deployment of `boost::cnv::cstream` with algorithms is
+ the use of `boost::cref` (or `std::cref` in C++11).
+
+ It needs to be remembered that with standard algorithms the deployed converter needs to be
+ [@http://en.cppreference.com/w/cpp/named_req/TriviallyCopyable copyable] or
+ [@http://en.cppreference.com/w/cpp/named_req/MoveAssignable movable (C++11)]
+ and is, in fact, copied or moved by the respective algorithm before being used.
+ Given that `std::cstringstream` is not copyable, `boost::cnv::cstream` is not copyable either.
+ That limitation is routinely worked-around using `boost::ref` or `boost::cref`.]
+ */
+//]
+}
+
+static
+void
+example5()
+{
+//[algorithm_example5
+ /*`And now an example of algorithm-based integer-to-string formatted conversion with
+ `std::hex`, `std::uppercase` and `std::showbase` formatting applied:
+ */
+ boost::array<int, 3> ints = {{ 15, 16, 17 }};
+ std::vector<std::string> strs;
+ boost::cnv::cstream cnv;
+
+ cnv(std::hex)(std::uppercase)(std::showbase);
+
+ std::transform(ints.begin(), ints.end(), std::back_inserter(strs),
+ boost::cnv::apply<string>(boost::cref(cnv)));
+
+ BOOST_TEST(strs.size() == 3);
+ BOOST_TEST(strs[0] == "0XF"); // 15
+ BOOST_TEST(strs[1] == "0X10"); // 16
+ BOOST_TEST(strs[2] == "0X11"); // 17
+//]
+}
+
+int
+main(int, char const* [])
+{
+ introduction();
+ example1();
+ example2();
+ example3();
+ example4();
+ example5();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/convert/example/default_converter.cpp b/src/boost/libs/convert/example/default_converter.cpp
new file mode 100644
index 000000000..fdcee8463
--- /dev/null
+++ b/src/boost/libs/convert/example/default_converter.cpp
@@ -0,0 +1,39 @@
+// Boost.Convert test and usage example
+// Copyright (c) 2009-2016 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#include <boost/convert.hpp>
+#include <boost/convert/stream.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#ifdef ONLY_FOR_DEMONSTRATION_PURPOSES
+//[default_converter_declaration_simple
+struct boost::cnv::by_default : boost::cnv::cstream {};
+//]
+#endif
+//[default_converter_declaration_formatted
+struct boost::cnv::by_default : boost::cnv::cstream
+{
+ by_default() { (*this)(std::uppercase)(std::hex); }
+};
+//]
+
+int
+main(int, char const* [])
+{
+ //[default_converter_example1
+ // No explicit converter provided. boost::cnv::by_default is used.
+ int i = boost::convert<int>("F").value_or(-1);
+ std::string s = boost::convert<std::string>(255).value_or("bad");
+
+ // 'i' and 's' are converted using boost::cnv::cstream
+ // with std::uppercase and std::hex formatting applied.
+
+ BOOST_TEST(i == 15); // 15(10) = F(16)
+ BOOST_TEST(s == "FF"); // 255(10) = FF(16)
+ //]
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/convert/example/default_converter_fail.cpp b/src/boost/libs/convert/example/default_converter_fail.cpp
new file mode 100644
index 000000000..966399644
--- /dev/null
+++ b/src/boost/libs/convert/example/default_converter_fail.cpp
@@ -0,0 +1,20 @@
+// Boost.Convert test and usage example
+// Copyright (c) 2009-2016 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#include <boost/convert.hpp>
+
+using std::string;
+using boost::convert;
+
+// This is expected to fail to compile:
+//'boost::cnv::by_default' : class has no constructors.
+
+int
+main(int, char const* [])
+{
+ int i = convert<int>("123").value();
+ string s = convert<string>(123).value();
+}
+
diff --git a/src/boost/libs/convert/example/getting_serious.cpp b/src/boost/libs/convert/example/getting_serious.cpp
new file mode 100644
index 000000000..1e0b7597d
--- /dev/null
+++ b/src/boost/libs/convert/example/getting_serious.cpp
@@ -0,0 +1,155 @@
+// Copyright (c) 2009-2016 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#ifdef BOOST_MSVC
+# pragma warning(disable : 4127) // conditional expression is constant.
+# pragma warning(disable : 4189) // local variable is initialized but not referenced.
+#endif
+
+#include <boost/convert.hpp>
+#include <boost/convert/stream.hpp>
+#include <boost/convert/lexical_cast.hpp>
+
+using std::string;
+using boost::convert;
+using boost::lexical_cast;
+using boost::optional;
+
+static void process_failure() {}
+static void log(...) {}
+static int fallback_function() { return -1; }
+
+//[getting_serious_default_converter
+struct boost::cnv::by_default : boost::cnv::cstream {};
+//]
+static
+void
+example1()
+{
+ boost::cnv::cstream cnv;
+ std::string const str = "123";
+ std::string const str1 = "123";
+ std::string const str2 = "123";
+ std::string const str3 = "123";
+ int const fallback_value = -1;
+
+ {
+ //[getting_serious_example1
+ int i2 = convert<int>("not an int", cnv).value_or(-1); // after the call i2==-1
+
+ if (i2 == -1) process_failure();
+ //]
+ }
+ {
+ //[getting_serious_example2
+ try
+ {
+ int i1 = lexical_cast<int>(str); // Throws if the conversion fails.
+ int i2 = convert<int>(str, cnv).value(); // Throws if the conversion fails.
+ }
+ catch (...)
+ {
+ process_failure();
+ }
+ //]
+ }
+ {
+ //[getting_serious_example3
+ optional<int> r1 = convert<int>(str1, cnv); // Does not throw on conversion failure.
+ optional<int> r2 = convert<int>(str2, cnv); // Does not throw on conversion failure.
+ // ...
+ try // Delayed processing of potential exceptions.
+ {
+ int i1 = r1.value(); // Will throw if conversion failed.
+ int i2 = r2.value(); // Will throw if conversion failed.
+ }
+ catch (boost::bad_optional_access const&)
+ {
+ // Handle failed conversion.
+ }
+
+ // Exceptions are avoided altogether.
+ int i1 = r1 ? r1.value() : fallback_value;
+ int i2 = r2.value_or(fallback_value);
+ int i3 = convert<int>(str3, cnv).value_or(fallback_value);
+ int i4 = convert<int>(str3, cnv).value_or_eval(fallback_function);
+ //]
+ }
+}
+
+//[getting_serious_example5
+struct fallback_func
+{
+ int operator()() const { log("Failed to convert"); return 42; }
+};
+//]
+
+static
+void
+example4()
+{
+ boost::cnv::cstream cnv;
+ std::string const str = "123";
+ int const fallback_value = -1;
+ //[getting_serious_example4
+ boost::optional<int> res = boost::convert<int>(str, cnv);
+
+ if (!res) log("str conversion failed!");
+
+ int i1 = res.value_or(fallback_value);
+
+ // ...proceed
+ //]
+ //[getting_serious_example6
+ // Fallback function is called when failed
+ int i2 = convert<int>(str, cnv).value_or_eval(fallback_func());
+ int i3 = convert<int>(str, cnv, fallback_func()); // Same as above. Alternative API.
+ //]
+}
+
+static
+void
+example7()
+{
+ boost::cnv::cstream cnv;
+ std::string const str = "123";
+ int const fallback_value = -1;
+ //[getting_serious_example7
+ // Error-processing behavior are specified unambiguously and uniformly.
+ // a) i1: Returns the provided fallback value;
+ // b) i2: Calls the provided failure-processing function;
+ // c) i3: Throws an exception.
+
+ int i1 = convert<int>(str, cnv, fallback_value);
+ int i2 = convert<int>(str, cnv, fallback_func());
+
+ try
+ {
+ // Throwing behavior specified explicitly rather than implied.
+ int i3 = convert<int>(str, cnv, boost::throw_on_failure);
+ }
+ catch (boost::bad_optional_access const&)
+ {
+ // Handle failed conversion.
+ }
+ //]
+ //[getting_serious_example8
+ int m1 = convert<int>(str, cnv).value_or(fallback_value);
+ int m2 = convert<int>(str, cnv).value_or_eval(fallback_func());
+ int m3 = convert<int>(str, cnv).value();
+ //]
+ //[getting_serious_example9
+ int n1 = convert<int>(str).value_or(fallback_value);
+ int n2 = convert<int>(str).value_or_eval(fallback_func());
+ int n3 = convert<int>(str).value();
+ //]
+}
+
+int
+main(int, char const* [])
+{
+ example1();
+ example4();
+ example7();
+}
diff --git a/src/boost/libs/convert/example/getting_started.cpp b/src/boost/libs/convert/example/getting_started.cpp
new file mode 100644
index 000000000..5fa9c5314
--- /dev/null
+++ b/src/boost/libs/convert/example/getting_started.cpp
@@ -0,0 +1,268 @@
+// Copyright (c) 2009-2016 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#ifdef _MSC_VER
+# pragma warning(disable : 4127) // conditional expression is constant.
+# pragma warning(disable : 4189) // local variable is initialized but not referenced.
+# pragma warning(disable : 4100) // unreferenced formal parameter.
+# pragma warning(disable : 4714) // marked as __forceinline not inlined.
+#endif
+
+namespace { namespace local
+{
+#if defined(_MSC_VER)
+ static bool const is_msc = true;
+#else
+ static bool const is_msc = false;
+#endif
+}}
+
+#include <boost/bind.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+static
+void
+log(char const*)
+{
+ // Dummy function to demonstrate how problems might be logged.
+}
+
+//[getting_started_headers1
+#include <boost/convert.hpp>
+#include <boost/convert/lexical_cast.hpp>
+//]
+
+//[getting_started_using
+using std::string;
+using boost::lexical_cast;
+using boost::convert;
+//]
+//[getting_started_default_converter
+// Definition of the default converter (optional)
+struct boost::cnv::by_default : boost::cnv::lexical_cast {};
+//]
+
+static
+void
+getting_started_example1()
+{
+ //[getting_started_example1
+ try
+ {
+ boost::cnv::lexical_cast cnv; // boost::lexical_cast-based converter
+
+ int i1 = lexical_cast<int>("123"); // boost::lexical_cast standard deployment
+ int i2 = convert<int>("123").value(); // boost::convert with the default converter
+ int i3 = convert<int>("123", cnv).value(); // boost::convert with an explicit converter
+ string s1 = lexical_cast<string>(123); // boost::lexical_cast standard deployment
+ string s2 = convert<string>(123).value(); // boost::convert with the default converter
+ string s3 = convert<string>(123, cnv).value(); // boost::convert with an explicit converter
+
+ BOOST_TEST(i1 == 123);
+ BOOST_TEST(i2 == 123);
+ BOOST_TEST(i3 == 123);
+ BOOST_TEST(s1 == "123");
+ BOOST_TEST(s2 == "123");
+ BOOST_TEST(s3 == "123");
+ }
+ catch (std::exception const& ex)
+ {
+ // Please be aware that the conversion requests above can fail.
+ // Use try'n'catch blocks to handle any exceptions thrown.
+ // Ignore this at your peril!
+ std::cerr << "Exception " << ex.what() << std::endl;
+ }
+ //] [/getting_started_example1]
+}
+
+static
+void
+getting_started_example2()
+{
+ //[getting_started_example2
+ // Does not throw. Returns fallback value (-1) when failed.
+ int i = convert<int>("uhm", boost::cnv::lexical_cast()).value_or(-1);
+
+ BOOST_TEST(i == -1); // Conversion failed. 'i' assigned the fallback value.
+ //]
+}
+
+//[getting_started_headers3
+#include <boost/convert/strtol.hpp>
+#include <boost/convert/spirit.hpp>
+//]
+
+static
+void
+getting_started_example3()
+{
+ //[getting_started_example3
+ boost::cnv::lexical_cast cnv1;
+ boost::cnv::strtol cnv2;
+ boost::cnv::spirit cnv3;
+
+ int i1 = convert<int>("123", cnv1).value();
+ int i2 = convert<int>("123", cnv2).value(); // Two times faster than lexical_cast.
+ int i3 = convert<int>("123", cnv3).value(); // Four times faster than lexical_cast.
+ //]
+}
+
+//[getting_started_headers4
+#include <boost/convert/stream.hpp>
+//]
+
+static
+void
+getting_started_example4()
+{
+ //[getting_started_example4
+ boost::cnv::cstream cnv;
+
+ try
+ {
+ int i1 = lexical_cast<int>(" 123"); // Does not work.
+ BOOST_TEST(!"Never reached");
+ }
+ catch (...) {}
+
+ int i2 = convert<int>(" 123", cnv(std::skipws)).value(); // Success
+ string s1 = lexical_cast<string>(12.34567);
+ string s2 = convert<string>(12.34567, cnv(std::fixed)(std::setprecision(3))).value();
+ string s3 = convert<string>(12.34567, cnv(std::scientific)(std::setprecision(3))).value();
+ string expected = local::is_msc ? "1.235e+001" : "1.235e+01";
+
+ BOOST_TEST(i2 == 123); // boost::cnv::cstream. Successful conversion of " 123".
+ BOOST_TEST(s1 == "12.34567"); // boost::lexical_cast. Precision is not configurable.
+ BOOST_TEST(s2 == "12.346"); // boost::cnv::cstream. Precision was set to 3. Fixed.
+ BOOST_TEST(s3 == expected); // boost::cnv::cstream. Precision was set to 3. Scientific.
+ //]
+}
+
+static
+void
+getting_started_example5()
+{
+ //[getting_started_example5
+ boost::cnv::cstream cnv;
+
+ int i1 = lexical_cast<int>("123"); // Throws when conversion fails.
+ int i2 = convert<int>("123", cnv).value(); // Throws when conversion fails.
+ int i3 = convert<int>("uhm", cnv).value_or(-1); // Returns -1 when conversion fails.
+
+ BOOST_TEST(i1 == 123);
+ BOOST_TEST(i2 == 123);
+ BOOST_TEST(i3 == -1);
+ //]
+}
+
+static
+void
+getting_started_example6()
+{
+ std::string const s1 = "123";
+ std::string const s2 = "456";
+ int const default_i1 = 11;
+ int const default_i2 = 12;
+ boost::cnv::cstream cnv;
+
+ //[getting_started_example6
+
+ int i1 = convert<int>(s1, cnv(std::hex)).value_or(-1); // Read as hex
+ int i2 = convert<int>(s2, cnv(std::dec)).value_or(-1); // Read as decimal
+
+ if (i1 == -1) log("bad i1"), i1 = default_i1; // Log failure. Proceed with the default
+ if (i2 == -1) log("bad i2"), i2 = default_i2; // Log failure. Proceed with the default
+
+ // ... proceed
+ //]
+ BOOST_TEST(i1 == 291);
+ BOOST_TEST(i2 == 456);
+}
+
+static
+void
+getting_started_example7()
+{
+ std::string const s1 = "123";
+ std::string const s2 = "456";
+ int const default_i1 = 11;
+ int const default_i2 = 12;
+ boost::cnv::cstream cnv;
+
+ //[getting_started_example7
+
+ int i1 = convert<int>(s1, cnv(std::hex)).value_or(default_i1); // If failed, proceed with the default
+ int i2 = convert<int>(s2, cnv(std::dec)).value_or(default_i2); // If failed, proceed with the default
+ // ... proceed
+ //]
+ BOOST_TEST(i1 == 291);
+ BOOST_TEST(i2 == 456);
+}
+
+static
+//[getting_started_example9_func
+int
+fallback_fun(char const* msg, int fallback_value)
+{
+ // The principal advantage of a fallback_func over a fallback_value
+ // is that the former is only called when the conversion request fails.
+ // Consequently, the returned fallback_value is only calculated (which
+ // potentially might be expensive) when it is absolutely necessary.
+ log(msg); return fallback_value;
+}
+//]
+static
+void
+getting_started_example9()
+{
+ std::string const s1 = "123";
+ std::string const s2 = "456";
+ int const default_i1 = 11;
+ int const default_i2 = 12;
+
+ //[getting_started_example9
+ int i1 = convert<int>(s1).value_or_eval(boost::bind(fallback_fun, "bad i1", default_i1));
+ int i2 = convert<int>(s2).value_or_eval(boost::bind(fallback_fun, "bad i2", default_i2));
+ // ... proceed
+ //]
+ BOOST_TEST(i1 == 123);
+ BOOST_TEST(i2 == 456);
+}
+
+static
+void
+getting_started_example8()
+{
+ std::string const str = "123";
+ int const default_i1 = 12;
+ //[getting_started_example8
+ int i1 = default_i1;
+
+ try
+ {
+ i1 = lexical_cast<int>(str);
+ }
+ catch (...)
+ {
+ log("bad i1");
+ }
+ //]
+ BOOST_TEST(i1 == 123);
+}
+
+int
+main(int, char const* [])
+{
+ getting_started_example1();
+ getting_started_example2();
+ getting_started_example3();
+ getting_started_example4();
+ getting_started_example5();
+ getting_started_example6();
+ getting_started_example7();
+ getting_started_example8();
+ getting_started_example9();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/convert/example/jamfile.v2 b/src/boost/libs/convert/example/jamfile.v2
new file mode 100644
index 000000000..485cb4914
--- /dev/null
+++ b/src/boost/libs/convert/example/jamfile.v2
@@ -0,0 +1,34 @@
+# Convert Jamfile
+# Copyright (c) Vladimir Batov 2009-2014
+# Distributed under the Boost Software License, Version 1.0.
+# See copy at http://www.boost.org/LICENSE_1_0.txt.
+
+# bring in the rules for testing
+import testing ;
+
+project convert_examples
+ : requirements
+ <warnings>on
+ <toolset>gcc:<warnings>all
+ <toolset>msvc:<warnings>all
+ <toolset>gcc:<cxxflags>"-Wno-unused-local-typedefs -Wno-unused-variable -Wno-long-long"
+ <toolset>msvc:<cxxflags>"/wd4996 /wd4512 /wd4610 /wd4510 /wd4127 /wd4701 /wd4127 /wd4305 /wd4100 /wd4512 /wd4714"
+ <toolset>msvc:<asynch-exceptions>on
+ <toolset>msvc:<define>_CRT_SECURE_NO_DEPRECATE
+ <toolset>msvc:<define>_SCL_SECURE_NO_DEPRECATE
+ <toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS
+ <toolset>msvc:<define>_CRT_SECURE_NO_WARNINGS
+ <include>../include
+ ;
+
+run algorithms.cpp : : : : convert_example_algorithms ;
+run default_converter.cpp : : : : convert_example_default_converter ;
+run getting_serious.cpp : : : : convert_example_getting_started ;
+run getting_started.cpp : : : : convert_example_getting_serious ;
+run lexical_cast.cpp : : : : convert_example_lexical_cast_converter ;
+run stream.cpp : : : : convert_example_stream_converter ;
+
+compile-fail default_converter_fail.cpp : <warnings>off <cxxflags>"-w" ;
+
+
+
diff --git a/src/boost/libs/convert/example/lexical_cast.cpp b/src/boost/libs/convert/example/lexical_cast.cpp
new file mode 100644
index 000000000..5527cf142
--- /dev/null
+++ b/src/boost/libs/convert/example/lexical_cast.cpp
@@ -0,0 +1,35 @@
+// Copyright (c) 2009-2016 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+//[lexical_cast_headers1
+#include <boost/convert.hpp>
+#include <boost/convert/lexical_cast.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+using std::string;
+using boost::convert;
+using boost::lexical_cast;
+
+struct boost::cnv::by_default : boost::cnv::lexical_cast {};
+//]
+
+int
+main(int, char const* [])
+{
+ //[lexical_cast_example1
+ int i1 = lexical_cast<int>("123"); // Throws if the conversion fails.
+ int i2 = convert<int>("123").value(); // Throws if the conversion fails.
+ int i3 = convert<int>("uhm").value_or(-1); // Returns -1 if the conversion fails.
+ string s1 = lexical_cast<string>(123);
+ string s2 = convert<string>(123).value();
+
+ BOOST_TEST(i1 == 123);
+ BOOST_TEST(i2 == 123);
+ BOOST_TEST(i3 == -1);
+ BOOST_TEST(s1 == "123");
+ BOOST_TEST(s2 == "123");
+ //]
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/convert/example/stream.cpp b/src/boost/libs/convert/example/stream.cpp
new file mode 100644
index 000000000..0a22c2346
--- /dev/null
+++ b/src/boost/libs/convert/example/stream.cpp
@@ -0,0 +1,101 @@
+// Copyright (c) 2009-2016 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#include <boost/convert.hpp>
+#include <boost/convert/lexical_cast.hpp>
+
+//[stream_headers1
+#include <boost/convert.hpp>
+#include <boost/convert/stream.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+using std::string;
+using boost::convert;
+
+struct boost::cnv::by_default : boost::cnv::cstream {};
+//]
+//[stream_headers2
+namespace cnv = boost::cnv;
+namespace arg = boost::cnv::parameter;
+//]
+
+#include "../test/test.hpp"
+
+static
+void
+example1()
+{
+ //[stream_example1
+ int i2 = convert<int>("123").value(); // Throws when fails.
+ int i3 = convert<int>("uhm").value_or(-1); // Returns -1 when fails.
+ string s2 = convert<string>(123).value();
+
+ BOOST_TEST(i2 == 123);
+ BOOST_TEST(i3 == -1);
+ BOOST_TEST(s2 == "123");
+ //]
+}
+
+static
+void
+example2()
+{
+ //[stream_example2
+ boost::cnv::cstream ccnv;
+ boost::cnv::wstream wcnv;
+
+ int v01 = convert<int>(" FF", ccnv(std::hex)(std::skipws)).value_or(0);
+ int v02 = convert<int>(L" F", wcnv(std::hex)(std::skipws)).value_or(0);
+ int v03 = convert<int>(" FF", ccnv(std::dec)(std::skipws)).value_or(-5);
+ int v04 = convert<int>(L" F", wcnv(std::dec)(std::skipws)).value_or(-5);
+
+ BOOST_TEST(v01 == 255); // "FF"
+ BOOST_TEST(v02 == 15); // L"F"
+ BOOST_TEST(v03 == -5); // Failed to convert "FF" as decimal.
+ BOOST_TEST(v04 == -5); // Failed to convert L"F" as decimal.
+ //]
+ //[stream_example3
+ ccnv(std::showbase)(std::uppercase)(std::hex);
+
+ BOOST_TEST(convert<string>(255, ccnv, "bad") == "0XFF");
+ BOOST_TEST(convert<string>( 15, ccnv, "bad") == "0XF");
+ //]
+ //[stream_example4
+ ccnv(arg::base = cnv::base::dec)
+ (arg::uppercase = true)
+ (arg::notation = cnv::notation::scientific);
+ //]
+ //[stream_example5
+ ccnv(std::dec)(std::uppercase)(std::scientific);
+ //]
+}
+
+static
+void
+example6()
+{
+ //[stream_example6
+ boost::cnv::cstream cnv1;
+ boost::cnv::lexical_cast cnv2;
+
+ change chg = change::up;
+ string s1 = convert<string>(chg, cnv1, "bad"); // Input type (change) deduced
+ string s2 = convert<string, change>(change::dn, cnv1, "bad"); // Input type (change) enforced
+
+ BOOST_TEST(convert<change>("up", cnv1, change::no) == change::up);
+ BOOST_TEST(convert<change>("up", cnv2, change::no) == change::up);
+ BOOST_TEST(s1 == "up");
+ BOOST_TEST(s2 == "dn");
+ //]
+}
+
+int
+main(int, char const* [])
+{
+ example1();
+ example2();
+ example6();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/convert/index.html b/src/boost/libs/convert/index.html
new file mode 100644
index 000000000..6cc92f7fa
--- /dev/null
+++ b/src/boost/libs/convert/index.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Boost.Convert</title>
+<meta charset="utf-8">
+<meta http-equiv="refresh" content="0; url=doc/html/index.html">
+<style>
+ body {
+ background: #fff;
+ color: #000;
+ }
+ a {
+ color: #00f;
+ text-decoration: none;
+ }
+</style>
+</head>
+<body>
+ <p>
+ Automatic redirection failed, please go to <a href="doc/html/index.html">doc/html/index.html</a>
+ </p>
+ <p>Copyright&nbsp;Vladimir Batov 2009-2016</p>
+ <p>Distributed under the Boost Software License, Version 1.0. (See accompanying file
+ <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at
+ <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>).
+ </p>
+</body>
+</html>
+
diff --git a/src/boost/libs/convert/makefile b/src/boost/libs/convert/makefile
new file mode 100644
index 000000000..98d69831f
--- /dev/null
+++ b/src/boost/libs/convert/makefile
@@ -0,0 +1,29 @@
+BOOST_ROOT = $(PRJROOT)/boost
+
+cflags = -O3 -I./include -I$(BOOST_ROOT) -Wno-unused-variable -Wno-uninitialized -Wno-deprecated-declarations
+lflags = -L$(BOOST_ROOT)/stage/lib -lboost_timer -lboost_chrono -lboost_system
+
+target_1 = convert-test-callable test/callable.cpp
+target_2 = convert-test-is-converter test/is_converter.cpp
+target_3 = convert-test-fallbacks test/fallbacks.cpp
+target_4 = convert-test-spirit-converter test/spirit_converter.cpp
+target_5 = convert-test-stream-converter test/stream_converter.cpp
+target_6 = convert-test-lcast-converter test/lcast_converter.cpp
+target_7 = convert-test-printf-converter test/printf_converter.cpp
+target_8 = convert-test-strtol-converter test/strtol_converter.cpp
+target_9 = convert-test-encryption test/encryption.cpp
+target_10 = convert-test-user-type test/user_type.cpp
+target_11 = convert-test-str-to-int test/str_to_int.cpp
+target_12 = convert-test-sfinae test/sfinae.cpp
+target_13 = convert-test-has-member test/has_member.cpp
+target_14 = convert-test-performance test/performance.cpp
+target_15 = convert-test-performance-spirit test/performance_spirit.cpp
+
+target_21 = convert-example-algorithms example/algorithms.cpp
+target_22 = convert-example-default_converter example/default_converter.cpp
+target_23 = convert-example-getting_serious example/getting_serious.cpp
+target_24 = convert-example-getting_started example/getting_started.cpp
+target_25 = convert-example-lexical_cast example/lexical_cast.cpp
+target_26 = convert-example-stream example/stream.cpp
+
+include $(PRJROOT)/make/makefile
diff --git a/src/boost/libs/convert/meta/libraries.json b/src/boost/libs/convert/meta/libraries.json
new file mode 100644
index 000000000..23e9511f1
--- /dev/null
+++ b/src/boost/libs/convert/meta/libraries.json
@@ -0,0 +1,11 @@
+{
+ "key": "convert",
+ "name": "Convert",
+ "authors": [ "Vladimir Batov" ],
+ "maintainers": [ "Vladimir Batov <vbmail247 -at- gmail.com>" ],
+ "description": "An extendible and configurable type-conversion framework.",
+ "category": [
+ "Miscellaneous",
+ "String"
+ ]
+}
diff --git a/src/boost/libs/convert/test/callable.cpp b/src/boost/libs/convert/test/callable.cpp
new file mode 100644
index 000000000..b8f36146b
--- /dev/null
+++ b/src/boost/libs/convert/test/callable.cpp
@@ -0,0 +1,114 @@
+// Boost.Convert test and usage example
+// Copyright (c) 2009-2016 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#include "./test.hpp"
+
+#if defined(BOOST_CONVERT_IS_NOT_SUPPORTED)
+int main(int, char const* []) { return 0; }
+#else
+
+#include <boost/convert.hpp>
+#include <boost/convert/lexical_cast.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/function.hpp>
+#include <boost/bind.hpp>
+
+using std::string;
+using boost::convert;
+using boost::lexical_cast;
+
+//[callable_example1
+void plain_old_func(string const& value_in, boost::optional<int>& value_out)
+//]
+{
+ try
+ {
+ value_out = lexical_cast<int>(value_in);
+ }
+ catch (...)
+ {
+ }
+}
+
+template<typename TypeIn, typename TypeOut>
+void
+convert_all(TypeIn const&, boost::optional<TypeOut>&)
+{
+}
+
+template<typename Type>
+void
+assign(boost::optional<Type>& value_out, Type const& value_in)
+{
+ value_out = value_in;
+}
+
+struct converter1
+{
+ template<typename TypeIn, typename TypeOut>
+ void
+ operator()(TypeIn const&, boost::optional<TypeOut>&) const
+ {
+ }
+};
+
+//[callable_example4
+struct take_double { void operator()(double, boost::optional<string>&) const {}};
+struct take_int { void operator()(int, boost::optional<string>&) const {}};
+//]
+
+//[callable_example6
+struct double_only
+{
+ // Declared for all types.
+ template<typename TypeIn> void operator()(TypeIn, boost::optional<string>&) const;
+};
+
+// Defined only for certain types.
+template<> void double_only::operator()<double>(double, boost::optional<string>&) const {}
+//]
+
+int
+main(int, char const* [])
+{
+ typedef boost::function<void (string const& value_in, boost::optional<int>&)> boost_func;
+
+ char const* const str = "-12";
+
+ // Testing old-function-based converter.
+ //[callable_example2
+ int v01 = convert<int>(str, plain_old_func).value_or(-1);
+ //]
+ // Testing boost::function-based converter.
+ int v02 = convert<int>(str, boost_func(plain_old_func)).value_or(-1);
+ // Testing crazy boost::bind-based converter.
+ //[callable_example3
+ int v03 = convert<int>(str,
+ boost::bind(assign<int>, _2,
+ boost::bind(lexical_cast<int, string>, _1))).value_or(-1);
+ //]
+ BOOST_TEST(v01 == -12);
+ BOOST_TEST(v02 == -12);
+ BOOST_TEST(v03 == -12);
+
+ convert<int>(str, convert_all<string, int>);
+ convert<string>(11, convert_all<int, string>);
+ convert< int>(str, converter1());
+ convert<string>(11, converter1());
+ convert<string>(11.23, take_double());
+ convert<string>(11, take_int());
+ //[callable_example5
+ convert<string>(11, take_double()); // Compiler applies int-to-double promotion to call the converter.
+ convert<string>(11.23, take_int()); // Compiler applies double-to-int implicit truncation.
+ //]
+ //[callable_example7
+ convert<string>(11.23, double_only()); // Fine.
+// convert<string>(11, double_only()); // Fails: undefined reference to double_only::operator()<int>
+ //]
+
+ return boost::report_errors();
+}
+
+#endif
diff --git a/src/boost/libs/convert/test/encryption.cpp b/src/boost/libs/convert/test/encryption.cpp
new file mode 100644
index 000000000..684c6d506
--- /dev/null
+++ b/src/boost/libs/convert/test/encryption.cpp
@@ -0,0 +1,44 @@
+// Copyright (c) 2009-2016 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#include "./test.hpp"
+
+#if defined(BOOST_CONVERT_IS_NOT_SUPPORTED)
+int main(int, char const* []) { return 0; }
+#else
+
+#include <boost/convert.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+static
+bool
+my_cypher(std::string const& value_in, boost::optional<std::string>& value_out)
+{
+ size_t const cypher = 'A' - '1';
+
+ value_out = value_in;
+
+ for (std::string::iterator it = value_out->begin(); it != value_out->end(); ++it)
+ (*it < 'A') ? (*it += cypher) : (*it -= cypher);
+
+ return true;
+}
+
+int
+main(int, char const* [])
+{
+ ////////////////////////////////////////////////////////////////////////////
+ // Testing custom converter.
+ ////////////////////////////////////////////////////////////////////////////
+
+ std::string encrypted = boost::convert<std::string>("ABC", my_cypher).value();
+ std::string decrypted = boost::convert<std::string>(encrypted, my_cypher).value();
+
+ BOOST_TEST(encrypted == "123");
+ BOOST_TEST(decrypted == "ABC");
+
+ return boost::report_errors();
+}
+
+#endif
diff --git a/src/boost/libs/convert/test/fallbacks.cpp b/src/boost/libs/convert/test/fallbacks.cpp
new file mode 100644
index 000000000..b0192e9b1
--- /dev/null
+++ b/src/boost/libs/convert/test/fallbacks.cpp
@@ -0,0 +1,81 @@
+// Boost.Convert test and usage example
+// Copyright (c) 2009-2016 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#include "./test.hpp"
+
+#if defined(BOOST_CONVERT_IS_NOT_SUPPORTED)
+int main(int, char const* []) { return 0; }
+#else
+
+#include <boost/convert.hpp>
+#include <boost/convert/stream.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/function.hpp>
+#include <boost/bind.hpp>
+
+namespace { namespace local
+{
+ bool called_functor_int;
+ bool called_functor_double;
+ bool called_functor_foo;
+ bool called_function_int;
+ bool called_function_long;
+}}
+
+struct functor_int { int operator() () const { local:: called_functor_int = true; return INT_MAX; }};
+struct functor_double { double operator() () const { local::called_functor_double = true; return INT_MAX; }};
+struct functor_foo { int func (int) const { local:: called_functor_foo = true; return INT_MAX; }};
+
+int function_int () { local:: called_function_int = true; return INT_MAX; }
+long function_long () { local::called_function_long = true; return INT_MAX; }
+
+int
+main(int, char const* [])
+{
+ boost::cnv::cstream cnv;
+ functor_foo foo;
+
+ int i01 = boost::convert<int>("uhm", cnv).value_or_eval(functor_int());
+ int i02 = boost::convert<int>("uhm", cnv).value_or_eval(functor_double());
+ int i03 = boost::convert<int>("uhm", cnv).value_or_eval(boost::bind(&functor_foo::func, foo, 0));
+ int i04 = boost::convert<int>("uhm", cnv).value_or_eval(function_int);
+ int i05 = boost::convert<int>("uhm", cnv).value_or_eval(function_long);
+
+ BOOST_TEST(local:: called_functor_int && i01 == INT_MAX);
+ BOOST_TEST(local::called_functor_double && i02 == INT_MAX);
+ BOOST_TEST(local:: called_functor_foo && i03 == INT_MAX);
+ BOOST_TEST(local:: called_function_int && i04 == INT_MAX);
+ BOOST_TEST(local:: called_function_long && i05 == INT_MAX);
+
+ local:: called_functor_int = false;
+ local::called_functor_double = false;
+ local:: called_functor_foo = false;
+ local:: called_function_int = false;
+ local:: called_function_long = false;
+
+ boost::convert<int>("uhm", cnv, functor_int());
+ boost::convert<int>("uhm", cnv, functor_double());
+ boost::convert<int>("uhm", cnv, boost::bind(&functor_foo::func, foo, 0));
+ boost::convert<int>("uhm", cnv, function_int);
+ boost::convert<int>("uhm", cnv, function_long);
+
+ BOOST_TEST(local:: called_functor_int && i01 == INT_MAX);
+ BOOST_TEST(local::called_functor_double && i02 == INT_MAX);
+ BOOST_TEST(local:: called_functor_foo && i03 == INT_MAX);
+ BOOST_TEST(local:: called_function_int && i04 == INT_MAX);
+ BOOST_TEST(local:: called_function_long && i05 == INT_MAX);
+
+ try
+ {
+ boost::convert<int>("uhm", cnv, boost::throw_on_failure);
+ BOOST_TEST(0);
+ }
+ catch (boost::bad_optional_access const&)
+ {
+ }
+ return boost::report_errors();
+}
+
+#endif
diff --git a/src/boost/libs/convert/test/has_member.cpp b/src/boost/libs/convert/test/has_member.cpp
new file mode 100644
index 000000000..088d047ae
--- /dev/null
+++ b/src/boost/libs/convert/test/has_member.cpp
@@ -0,0 +1,104 @@
+// Boost.Convert test and usage example
+// Copyright (c) 2009-2016 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#include "./test.hpp"
+
+#if defined(BOOST_CONVERT_IS_NOT_SUPPORTED)
+int main(int, char const* []) { return 0; }
+#else
+
+#include <boost/convert.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <vector>
+#include <iostream>
+
+//[has_member_declaration
+namespace { namespace local
+{
+ BOOST_DECLARE_HAS_MEMBER(has_begin, begin);
+ BOOST_DECLARE_HAS_MEMBER(has_funop, operator());
+}}
+//]
+//[has_member_classes_tested
+namespace { namespace local
+{
+ struct test01 { int begin; };
+ struct test02 { char* begin() { return 0; } };
+ struct test22 { void operator()() {} };
+}}
+//]
+
+namespace { namespace local
+{
+ struct test03
+ {
+ void begin(int) {}
+ int begin(int, int) { return 0; }
+ };
+ struct test04
+ {
+ virtual ~test04() {}
+
+ private: virtual char* begin() { return 0; }
+ };
+ struct test05
+ {
+ virtual char* begin() { return 0; }
+ virtual ~test05() {}
+ };
+ struct test06 : public test04 {};
+ struct test07 : private test04 {};
+ struct test08 : public test05 {};
+ struct test09 : private test05 {};
+
+ struct test11 { int no_begin; };
+ struct test12 { char* no_begin() { return 0; } };
+}}
+
+namespace { namespace local
+{
+ struct test21 { void zoo () {} };
+ struct test23 { void operator() () const {} };
+ struct test24 { int operator() (int) { return 0; } };
+ struct test25 { int operator() (int) const { return 0; } };
+ struct test26 { int operator() (int) const { return 0; } void operator() () const {} };
+}}
+
+int
+main(int, char const* [])
+{
+ BOOST_TEST(local::has_begin<local::test01>::value == true);
+ BOOST_TEST(local::has_begin<local::test02>::value == true);
+ BOOST_TEST(local::has_begin<local::test03>::value == true);
+ BOOST_TEST(local::has_begin<local::test04>::value == true);
+ BOOST_TEST(local::has_begin<local::test05>::value == true);
+ BOOST_TEST(local::has_begin<local::test06>::value == true);
+ BOOST_TEST(local::has_begin<local::test07>::value == true);
+ BOOST_TEST(local::has_begin<local::test08>::value == true);
+ BOOST_TEST(local::has_begin<local::test09>::value == true);
+ BOOST_TEST(local::has_begin<std::string>::value == true);
+ BOOST_TEST(local::has_begin<std::vector<int> >::value == true);
+
+ BOOST_TEST(local::has_begin<local::test11>::value == false);
+ BOOST_TEST(local::has_begin<local::test12>::value == false);
+ BOOST_TEST(local::has_begin<std::iostream>::value == false);
+
+ //[has_member_usage
+ BOOST_TEST(local::has_begin<local::test01>::value == true);
+ BOOST_TEST(local::has_begin<local::test02>::value == true);
+ BOOST_TEST(local::has_funop<local::test22>::value == true);
+ //]
+
+ BOOST_TEST(local::has_funop<local::test21>::value == false);
+ BOOST_TEST(local::has_funop<local::test22>::value == true);
+ BOOST_TEST(local::has_funop<local::test23>::value == true);
+ BOOST_TEST(local::has_funop<local::test24>::value == true);
+ BOOST_TEST(local::has_funop<local::test25>::value == true);
+ BOOST_TEST(local::has_funop<local::test26>::value == true);
+
+ return boost::report_errors();
+}
+
+#endif
diff --git a/src/boost/libs/convert/test/is_converter.cpp b/src/boost/libs/convert/test/is_converter.cpp
new file mode 100644
index 000000000..f528a33c5
--- /dev/null
+++ b/src/boost/libs/convert/test/is_converter.cpp
@@ -0,0 +1,86 @@
+// Boost.Convert test and usage example
+// Copyright (c) 2009-2016 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#include "./test.hpp"
+
+#if defined(BOOST_CONVERT_IS_NOT_SUPPORTED)
+int main(int, char const* []) { return 0; }
+#else
+
+#include <boost/convert.hpp>
+#include <boost/convert/detail/is_converter.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+using std::string;
+using std::wstring;
+
+namespace { namespace local
+{
+ typedef void not_converter01 (string const&);
+ typedef void not_converter02 (int const&, string const&);
+ typedef void not_converter03 ();
+ typedef void converter01 (int const&, boost::optional<string>&);
+ typedef void converter02 (double const&, boost::optional<string>&);
+
+ struct converter11
+ {
+ void operator()(int const&, boost::optional<string>&) {}
+ void operator()(double const&, boost::optional<string>&) {}
+ void operator()(string const&, boost::optional<int>&) {}
+ };
+ struct converter12
+ {
+ template<typename TypeIn, typename TypeOut> void operator()(TypeIn const&, boost::optional<TypeOut>&) {}
+ };
+ struct converter13
+ {
+ void operator()(int const&, boost::optional<string>&) {}
+ };
+ struct converter14
+ {
+ void operator()(int const&, boost::optional<string>&) const {}
+ };
+ struct not_converter11
+ {
+ };
+ struct not_converter12
+ {
+ void operator()() {}
+ };
+ struct not_converter13
+ {
+ void operator()(int const&, string const&) {}
+ };
+}}
+
+int
+main(int, char const* [])
+{
+ BOOST_TEST( (boost::cnv::is_cnv<local::converter01, int, string>::value));
+ BOOST_TEST( (boost::cnv::is_cnv<local::converter01, double, string>::value));
+ BOOST_TEST( (boost::cnv::is_cnv<local::converter01, short int, string>::value));
+ BOOST_TEST( (boost::cnv::is_cnv<local::converter11, int, string>::value));
+ BOOST_TEST( (boost::cnv::is_cnv<local::converter11, double, string>::value));
+ BOOST_TEST( (boost::cnv::is_cnv<local::converter11, string, int>::value));
+ BOOST_TEST( (boost::cnv::is_cnv<local::converter12, int, string>::value));
+ BOOST_TEST( (boost::cnv::is_cnv<local::converter12, double, string>::value));
+ BOOST_TEST( (boost::cnv::is_cnv<local::converter12, string, int>::value));
+ BOOST_TEST( (boost::cnv::is_cnv<local::converter13, int, string>::value));
+ BOOST_TEST( (boost::cnv::is_cnv<local::converter13, double, string>::value));
+ BOOST_TEST( (boost::cnv::is_cnv<local::converter13, int, string>::value));
+ BOOST_TEST( (boost::cnv::is_cnv<local::converter14, int, string>::value));
+ BOOST_TEST(!(boost::cnv::is_cnv<local::converter13, string, int>::value));
+ BOOST_TEST(!(boost::cnv::is_cnv<local::converter14, string, int>::value));
+
+ BOOST_TEST(!(boost::cnv::is_cnv<local::not_converter01, int, string>::value));
+ BOOST_TEST(!(boost::cnv::is_cnv<local::not_converter02, int, string>::value));
+ BOOST_TEST(!(boost::cnv::is_cnv<local::not_converter11, int, string>::value));
+ BOOST_TEST(!(boost::cnv::is_cnv<local::not_converter12, int, string>::value));
+ BOOST_TEST(!(boost::cnv::is_cnv<local::not_converter13, int, string>::value));
+
+ return boost::report_errors();
+}
+
+#endif
diff --git a/src/boost/libs/convert/test/jamfile.v2 b/src/boost/libs/convert/test/jamfile.v2
new file mode 100644
index 000000000..9a60a3f5d
--- /dev/null
+++ b/src/boost/libs/convert/test/jamfile.v2
@@ -0,0 +1,41 @@
+# Convert Jamfile
+# Copyright (c) Vladimir Batov 2009-2014
+# Distributed under the Boost Software License, Version 1.0.
+# See copy at http://www.boost.org/LICENSE_1_0.txt.
+
+# bring in the rules for testing
+import testing ;
+
+project convert_test
+ : requirements
+ <warnings>on
+ <toolset>icpc:<cxxflags>"-std=c++11"
+ <toolset>clang:<cxxflags>"-std=c++11"
+ <toolset>gcc:<warnings>all
+ <toolset>gcc:<cxxflags>"-O3 -std=c++0x -Wno-unused-variable -Wno-unused-local-typedefs -Wno-long-long"
+ <toolset>msvc:<warnings>all
+ <toolset>msvc:<cxxflags>"/wd4996 /wd4512 /wd4610 /wd4510 /wd4127 /wd4701 /wd4127 /wd4305 /wd4244 /wd4714 /wd4189"
+ <toolset>msvc:<asynch-exceptions>on
+ <toolset>msvc:<define>_CRT_SECURE_NO_DEPRECATE
+ <toolset>msvc:<define>_SCL_SECURE_NO_DEPRECATE
+ <toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS
+ <toolset>msvc:<define>_CRT_SECURE_NO_WARNINGS
+ <include>../include
+ ;
+
+exe convert_test_performance : performance.cpp /boost/timer//boost_timer ;
+exe convert_test_performance_spirit : performance_spirit.cpp ;
+
+run callable.cpp : : : : convert_test_callable ;
+run fallbacks.cpp : : : : convert_test_fallbacks ;
+run spirit_converter.cpp : : : : convert_test_spirit_converter ;
+run stream_converter.cpp : : : : convert_test_stream_converter ;
+run printf_converter.cpp : : : : convert_test_printf_converter ;
+run strtol_converter.cpp : : : : convert_test_strtol_converter ;
+run lcast_converter.cpp : : : : convert_test_lcast_converter ;
+run encryption.cpp : : : : convert_test_encryption ;
+run user_type.cpp : : : : convert_test_user_type ;
+run str_to_int.cpp : : : : convert_test_str_to_int ;
+run sfinae.cpp : : : : convert_test_sfinae ;
+run has_member.cpp : : : : convert_test_has_member ;
+
diff --git a/src/boost/libs/convert/test/lcast_converter.cpp b/src/boost/libs/convert/test/lcast_converter.cpp
new file mode 100644
index 000000000..8cd14c448
--- /dev/null
+++ b/src/boost/libs/convert/test/lcast_converter.cpp
@@ -0,0 +1,77 @@
+// Boost.Convert test and usage example
+// Copyright (c) 2009-2016 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#include "./test.hpp"
+
+#if defined(BOOST_CONVERT_IS_NOT_SUPPORTED)
+int main(int, char const* []) { return 0; }
+#else
+
+#include <boost/convert.hpp>
+#include <boost/convert/lexical_cast.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+using std::string;
+using boost::convert;
+
+struct boost::cnv::by_default : boost::cnv::lexical_cast {};
+
+static
+void
+test_invalid()
+{
+ char const* str[] = { "not", "1 2", " 33", "44 ", "0x11", "7 + 5" };
+ int const size = sizeof(str) / sizeof(str[0]);
+
+ for (int k = 0; k < size; ++k)
+ {
+ boost::optional<int> const res = convert<int>(str[k]);
+ bool const failed = !res;
+
+ if (!failed)
+ {
+ printf("test::cnv::invalid() failed for: <%s><%d>\n", str[k], res.value());
+ }
+ BOOST_TEST(failed);
+ }
+}
+
+static
+void
+test_dbl_to_str()
+{
+// printf("100.00 %s\n", convert<string>( 99.999).value().c_str());
+// printf( "99.95 %s\n", convert<string>( 99.949).value().c_str());
+// printf("-99.95 %s\n", convert<string>(-99.949).value().c_str());
+// printf( "99.9 %s\n", convert<string>( 99.949).value().c_str());
+// printf( "1.00 %s\n", convert<string>( 0.999).value().c_str());
+// printf( "-1.00 %s\n", convert<string>( -0.999).value().c_str());
+// printf( "0.95 %s\n", convert<string>( 0.949).value().c_str());
+// printf( "-0.95 %s\n", convert<string>( -0.949).value().c_str());
+// printf( "1.9 %s\n", convert<string>( 1.949).value().c_str());
+// printf( "-1.9 %s\n", convert<string>( -1.949).value().c_str());
+}
+
+int
+main(int, char const* [])
+{
+ string const not_int_str = "not an int";
+ string const std_str = "-11";
+ char const* const c_str = "-12";
+ int const v00 = convert<int>(not_int_str).value_or(-1);
+ int const v01 = convert<int>( std_str).value_or(-1);
+ int const v02 = convert<int>( c_str).value_or(-1);
+
+ BOOST_TEST(v00 == -1); // Failed conversion. No throw
+ BOOST_TEST(v01 == -11);
+ BOOST_TEST(v02 == -12);
+
+ test_invalid();
+ test_dbl_to_str();
+
+ return boost::report_errors();
+}
+
+#endif
diff --git a/src/boost/libs/convert/test/performance.cpp b/src/boost/libs/convert/test/performance.cpp
new file mode 100644
index 000000000..ac2080970
--- /dev/null
+++ b/src/boost/libs/convert/test/performance.cpp
@@ -0,0 +1,317 @@
+// Boost.Convert test and usage example
+// Copyright (c) 2009-2016 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#include "./test.hpp"
+
+#if defined(BOOST_CONVERT_IS_NOT_SUPPORTED)
+int main(int, char const* []) { return 0; }
+#else
+
+#include "./prepare.hpp"
+#include <boost/convert.hpp>
+#include <boost/convert/stream.hpp>
+#include <boost/convert/printf.hpp>
+#include <boost/convert/strtol.hpp>
+#include <boost/convert/spirit.hpp>
+#include <boost/convert/lexical_cast.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/timer/timer.hpp>
+#include <boost/array.hpp>
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/uniform_int_distribution.hpp>
+#include <cstdlib>
+#include <cstdio>
+
+using std::string;
+using boost::convert;
+
+namespace cnv = boost::cnv;
+namespace arg = boost::cnv::parameter;
+
+namespace { namespace local
+{
+ template<typename Type>
+ struct array
+ {
+ typedef boost::array<Type, 20> type;
+ };
+ template<typename T> static typename array<T>::type const& get();
+
+ static int const num_cycles = 1000000;
+ int sum = 0;
+
+ struct timer : public boost::timer::cpu_timer
+ {
+ typedef timer this_type;
+ typedef boost::timer::cpu_timer base_type;
+
+ double value() const
+ {
+ boost::timer::cpu_times times = base_type::elapsed();
+ int const use_sum = (sum % 2) ? 0 : (sum % 2); BOOST_TEST(use_sum == 0);
+
+ return double(times.user + times.system) / 1000000000 + use_sum;
+ }
+ };
+ template< typename Type, typename Cnv> static double str_to (Cnv const&);
+ template<typename S, typename Type, typename Cnv> static double to_str (Cnv const&);
+
+ template<>
+ local::array<int>::type const&
+ get<int>()
+ {
+ static array<int>::type ints;
+ static bool filled;
+
+ if (!filled)
+ {
+ boost::random::mt19937 gen (::time(0));
+ boost::random::uniform_int_distribution<> dist (INT_MIN, INT_MAX); // INT_MAX(32) = 2,147,483,647
+
+ for (size_t k = 0; k < ints.size(); ++k)
+ ints[k] = dist(gen);
+
+ filled = true;
+ }
+ return ints;
+ }
+ template<>
+ array<long int>::type const&
+ get<long int>()
+ {
+ static array<long int>::type ints;
+ static bool filled;
+
+ if (!filled)
+ {
+ boost::random::mt19937 gen (::time(0));
+ boost::random::uniform_int_distribution<> dist (INT_MIN, INT_MAX); // INT_MAX(32) = 2147483647
+
+ for (size_t k = 0; k < ints.size(); ++k)
+ ints[k] = dist(gen);
+
+ filled = true;
+ }
+ return ints;
+ }
+ template<>
+ array<double>::type const&
+ get<double>()
+ {
+ static array<double>::type dbls;
+ static bool filled;
+
+ if (!filled)
+ {
+ boost::random::mt19937 gen (::time(0));
+ boost::random::uniform_int_distribution<> dist (INT_MIN, INT_MAX); // INT_MAX(32) = 2147483647
+
+ for (size_t k = 0; k < dbls.size(); ++k)
+ dbls[k] = double(dist(gen)) + 0.7654321;
+
+ filled = true;
+ }
+ return dbls;
+ }
+}}
+
+struct raw_str_to_int_spirit
+{
+ int operator()(char const* str) const
+ {
+ char const* beg = str;
+ char const* end = beg + strlen(str);
+ int result;
+
+ if (boost::spirit::qi::parse(beg, end, boost::spirit::int_, result))
+ if (beg == end) // ensure the whole string was parsed
+ return result;
+
+ return (BOOST_ASSERT(0), result);
+ }
+};
+
+struct raw_str_to_int_lxcast
+{
+ int operator()(char const* str) const
+ {
+ return boost::lexical_cast<int>(str);
+ }
+};
+
+template<typename Type, typename Converter>
+double
+raw_str_to(Converter const& cnv)
+{
+ local::strings strings = local::get_strs(); // Create strings on the stack
+ int const size = strings.size();
+ local::timer timer;
+
+ for (int t = 0; t < local::num_cycles; ++t)
+ for (int k = 0; k < size; ++k)
+ local::sum += cnv(strings[k].c_str());
+
+ return timer.value();
+}
+
+template<typename Type, typename Converter>
+double
+local::str_to(Converter const& try_converter)
+{
+ local::strings strings = local::get_strs(); // Create strings on the stack
+ int const size = strings.size();
+ local::timer timer;
+
+ for (int t = 0; t < local::num_cycles; ++t)
+ for (int k = 0; k < size; ++k)
+ local::sum += boost::convert<Type>(strings[k].c_str(), try_converter).value();
+
+ return timer.value();
+}
+
+template<typename string_type, typename Type, typename Converter>
+double
+local::to_str(Converter const& try_converter)
+{
+ typedef typename local::array<Type>::type collection;
+
+ collection values = local::get<Type>();
+ int const size = values.size();
+ local::timer timer;
+
+ for (int t = 0; t < local::num_cycles; ++t)
+ for (int k = 0; k < size; ++k)
+ local::sum += *boost::convert<string_type>(Type(values[k]), try_converter).value().begin();
+
+ return timer.value();
+}
+
+template<typename Converter>
+double
+performance_str_to_type(Converter const& try_converter)
+{
+ char const* input[] = { "no", "up", "dn" };
+ local::timer timer;
+
+ for (int k = 0; k < local::num_cycles; ++k)
+ {
+ change chg = boost::convert<change>(input[k % 3], try_converter).value();
+ int res = chg.value();
+
+ BOOST_TEST(res == k % 3);
+
+ local::sum += res; // Make sure chg is not optimized out
+ }
+ return timer.value();
+}
+
+template<typename Converter>
+double
+performance_type_to_str(Converter const& try_converter)
+{
+ boost::array<change, 3> input = {{ change::no, change::up, change::dn }};
+ boost::array<string, 3> results = {{ "no", "up", "dn" }};
+ local::timer timer;
+
+ for (int k = 0; k < local::num_cycles; ++k)
+ {
+ string res = boost::convert<string>(input[k % 3], try_converter).value();
+
+ BOOST_TEST(res == results[k % 3]);
+
+ local::sum += res[0]; // Make sure res is not optimized out
+ }
+ return timer.value();
+}
+
+template<typename Raw, typename Cnv>
+void
+performance_comparative(Raw const& raw, Cnv const& cnv, char const* txt)
+{
+ int const num_tries = 5;
+ double cnv_time = 0;
+ double raw_time = 0;
+
+ for (int k = 0; k < num_tries; ++k) cnv_time += local::str_to<int>(cnv);
+ for (int k = 0; k < num_tries; ++k) raw_time += raw_str_to<int>(raw);
+
+ cnv_time /= num_tries;
+ raw_time /= num_tries;
+
+ double change = 100 * (1 - cnv_time / raw_time);
+
+ printf("str-to-int: %s raw/cnv=%.2f/%.2f seconds (%.2f%%).\n", txt, raw_time, cnv_time, change);
+}
+
+int
+main(int, char const* [])
+{
+ printf("Started performance tests...\n");
+
+ printf("str-to-int: spirit/strtol/lcast/scanf/stream=%7.2f/%7.2f/%7.2f/%7.2f/%7.2f seconds.\n",
+ local::str_to<int>(boost::cnv::spirit()),
+ local::str_to<int>(boost::cnv::strtol()),
+ local::str_to<int>(boost::cnv::lexical_cast()),
+ local::str_to<int>(boost::cnv::printf()),
+ local::str_to<int>(boost::cnv::cstream()));
+ printf("str-to-lng: spirit/strtol/lcast/scanf/stream=%7.2f/%7.2f/%7.2f/%7.2f/%7.2f seconds.\n",
+ local::str_to<long int>(boost::cnv::spirit()),
+ local::str_to<long int>(boost::cnv::strtol()),
+ local::str_to<long int>(boost::cnv::lexical_cast()),
+ local::str_to<long int>(boost::cnv::printf()),
+ local::str_to<long int>(boost::cnv::cstream()));
+ printf("str-to-dbl: spirit/strtol/lcast/scanf/stream=%7.2f/%7.2f/%7.2f/%7.2f/%7.2f seconds.\n",
+ local::str_to<double>(boost::cnv::spirit()),
+ local::str_to<double>(boost::cnv::strtol()),
+ local::str_to<double>(boost::cnv::lexical_cast()),
+ local::str_to<double>(boost::cnv::printf()),
+ local::str_to<double>(boost::cnv::cstream()));
+
+ printf("int-to-str: spirit/strtol/lcast/prntf/stream=%7.2f/%7.2f/%7.2f/%7.2f/%7.2f seconds.\n",
+ local::to_str<std::string, int>(boost::cnv::spirit()),
+ local::to_str<std::string, int>(boost::cnv::strtol()),
+ local::to_str<std::string, int>(boost::cnv::lexical_cast()),
+ local::to_str<std::string, int>(boost::cnv::printf()),
+ local::to_str<std::string, int>(boost::cnv::cstream()));
+ printf("lng-to-str: spirit/strtol/lcast/prntf/stream=%7.2f/%7.2f/%7.2f/%7.2f/%7.2f seconds.\n",
+ local::to_str<std::string, long int>(boost::cnv::spirit()),
+ local::to_str<std::string, long int>(boost::cnv::strtol()),
+ local::to_str<std::string, long int>(boost::cnv::lexical_cast()),
+ local::to_str<std::string, long int>(boost::cnv::printf()),
+ local::to_str<std::string, long int>(boost::cnv::cstream()));
+ printf("dbl-to-str: spirit/strtol/lcast/prntf/stream=%7.2f/%7.2f/%7.2f/%7.2f/%7.2f seconds.\n",
+ local::to_str<std::string, double>(boost::cnv::spirit()),
+ local::to_str<std::string, double>(boost::cnv::strtol()(arg::precision = 6)),
+ local::to_str<std::string, double>(boost::cnv::lexical_cast()),
+ local::to_str<std::string, double>(boost::cnv::printf()(arg::precision = 6)),
+ local::to_str<std::string, double>(boost::cnv::cstream()(arg::precision = 6)));
+
+ printf("str-to-user-type: lcast/stream/strtol=%.2f/%.2f/%.2f seconds.\n",
+ performance_str_to_type(boost::cnv::lexical_cast()),
+ performance_str_to_type(boost::cnv::cstream()),
+ performance_str_to_type(boost::cnv::strtol()));
+ printf("user-type-to-str: lcast/stream/strtol=%.2f/%.2f/%.2f seconds.\n",
+ performance_type_to_str(boost::cnv::lexical_cast()),
+ performance_type_to_str(boost::cnv::cstream()),
+ performance_type_to_str(boost::cnv::strtol()));
+
+ //[small_string_results
+ printf("strtol int-to std::string/small-string: %.2f/%.2f seconds.\n",
+ local::to_str<std::string, int>(boost::cnv::strtol()),
+ local::to_str< my_string, int>(boost::cnv::strtol()));
+ printf("spirit int-to std::string/small-string: %.2f/%.2f seconds.\n",
+ local::to_str<std::string, int>(boost::cnv::spirit()),
+ local::to_str< my_string, int>(boost::cnv::spirit()));
+ printf("stream int-to std::string/small-string: %.2f/%.2f seconds.\n",
+ local::to_str<std::string, int>(boost::cnv::cstream()),
+ local::to_str< my_string, int>(boost::cnv::cstream()));
+ //]
+ performance_comparative(raw_str_to_int_spirit(), boost::cnv::spirit(), "spirit");
+ performance_comparative(raw_str_to_int_lxcast(), boost::cnv::lexical_cast(), "lxcast");
+
+ return boost::report_errors();
+}
+
+#endif
diff --git a/src/boost/libs/convert/test/performance_spirit.cpp b/src/boost/libs/convert/test/performance_spirit.cpp
new file mode 100644
index 000000000..4878b07d2
--- /dev/null
+++ b/src/boost/libs/convert/test/performance_spirit.cpp
@@ -0,0 +1,112 @@
+// Boost.Convert test and usage example
+// Copyright (c) 2009-2016 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+// This code has been adapted from libs/spirit/optimization/qi/int_parser.cpp.
+// This code uses the performance testing framework from libs/spirit/optimization/measure.cpp.
+// See these mentioned files for the copyright notice.
+
+#include "./test.hpp"
+
+#if defined(BOOST_CONVERT_IS_NOT_SUPPORTED)
+int main(int, char const* []) { return 0; }
+#else
+
+#include <boost/convert.hpp>
+#include <boost/convert/spirit.hpp>
+#include <boost/convert/strtol.hpp>
+#include <boost/convert/lexical_cast.hpp>
+#include "./prepare.hpp"
+
+//#define main() old_str_to_int_test_spirit()
+//#include <libs/spirit/optimization/qi/int_parser.cpp>
+#include <libs/spirit/workbench/measure.hpp>
+#include <string>
+#include <vector>
+#include <cstdlib>
+#include <boost/spirit/include/qi.hpp>
+
+namespace
+{
+ namespace local
+ {
+ struct base : test::base
+ {
+ base() : strings_(local::get_strs()) {}
+
+ // Test strings are created as part of the object, i.e. on the stack to make sure
+ // they are easily accessed.
+ local::strings strings_;
+ };
+ }
+ struct raw_lxcast_str_to_int_test : local::base
+ {
+ void benchmark()
+ {
+ for (size_t i = 0; i < strings_.size(); ++i)
+ this->val += boost::lexical_cast<int>(strings_[i].c_str());
+ }
+ };
+ struct cnv_lxcast_str_to_int_test : local::base
+ {
+ void benchmark()
+ {
+ for (size_t i = 0; i < strings_.size(); ++i)
+ this->val += boost::convert<int>(strings_[i].c_str(), cnv).value();
+ }
+ boost::cnv::lexical_cast cnv;
+ };
+ struct raw_spirit_str_to_int_test : local::base
+ {
+ static int parse(char const* str)
+ {
+ char const* beg = str;
+ char const* end = beg + strlen(str);
+ int n;
+
+ if (boost::spirit::qi::parse(beg, end, boost::spirit::qi::int_, n))
+ if (beg == end)
+ return n;
+
+ return (BOOST_ASSERT(0), 0);
+ }
+ void benchmark()
+ {
+ for (size_t i = 0; i < strings_.size(); ++i)
+ this->val += parse(strings_[i].c_str());
+ }
+ };
+ struct cnv_spirit_str_to_int_test : local::base
+ {
+ void benchmark()
+ {
+ for (size_t i = 0; i < strings_.size(); ++i)
+ this->val += boost::convert<int>(strings_[i].c_str(), cnv).value();
+ }
+ boost::cnv::spirit cnv;
+ };
+}
+
+int
+main(int, char const* [])
+{
+ // This code has been adapted from libs/spirit/optimization/qi/int_parser.cpp.
+ // This code uses the performance testing framework from libs/spirit/optimization/measure.cpp.
+ // See these mentioned files for the copyright notice.
+
+ BOOST_SPIRIT_TEST_BENCHMARK(
+ 10000000, // This is the maximum repetitions to execute
+ (raw_lxcast_str_to_int_test)
+ (cnv_lxcast_str_to_int_test)
+ (raw_spirit_str_to_int_test)
+ (cnv_spirit_str_to_int_test)
+ )
+
+ // This is ultimately responsible for preventing all the test code
+ // from being optimized away. Change this to return 0 and you
+ // unplug the whole test's life support system.
+ return test::live_code != 0;
+}
+
+#endif
diff --git a/src/boost/libs/convert/test/prepare.hpp b/src/boost/libs/convert/test/prepare.hpp
new file mode 100644
index 000000000..15c4d0153
--- /dev/null
+++ b/src/boost/libs/convert/test/prepare.hpp
@@ -0,0 +1,59 @@
+// Boost.Convert test and usage example
+// Copyright (c) 2009-2016 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#ifndef BOOST_CONVERT_TEST_PREPARE_HPP
+#define BOOST_CONVERT_TEST_PREPARE_HPP
+
+#include <boost/array.hpp>
+#include <ctime>
+#include <cstdlib>
+
+// boostinspect:nounnamed
+namespace { namespace local
+{
+ // C1. 18 = 9 positive + 9 negative numbers with the number of digits from 1 to 9.
+ // Even though INT_MAX(32) = 2147483647, i.e. 10 digits (not to mention long int)
+ // we only test up to 9 digits as Spirit does not handle more than 9.
+
+ typedef boost::array<my_string, 18> strings; //C1
+ ///////////////////////////////////////////////////////////////////////////
+ // Generate a random number string with N digits
+ std::string
+ gen_int(int digits, bool negative)
+ {
+ std::string result;
+
+ if (negative) // Prepend a '-'
+ result += '-';
+
+ result += '1' + (std::rand()%9); // The first digit cannot be '0'
+
+ for (int i = 1; i < digits; ++i) // Generate the remaining digits
+ result += '0' + (std::rand()%10);
+ return result;
+ }
+
+ local::strings const&
+ get_strs()
+ {
+ static local::strings strings;
+ static bool filled;
+ static bool negative = true;
+
+ if (!filled)
+ {
+ // Seed the random generator
+ std::srand(std::time(0));
+
+ for (size_t k = 0; k < strings.size(); ++k)
+ strings[k] = local::gen_int(k/2 + 1, negative = !negative).c_str();
+
+ filled = true;
+ }
+ return strings;
+ }
+}}
+
+#endif // BOOST_CONVERT_TEST_PREPARE_HPP
diff --git a/src/boost/libs/convert/test/printf_converter.cpp b/src/boost/libs/convert/test/printf_converter.cpp
new file mode 100644
index 000000000..a56c95b55
--- /dev/null
+++ b/src/boost/libs/convert/test/printf_converter.cpp
@@ -0,0 +1,47 @@
+// Boost.Convert test and usage example
+// Copyright (c) 2009-2016 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#include "./test.hpp"
+
+#if defined(BOOST_CONVERT_IS_NOT_SUPPORTED)
+int main(int, char const* []) { return 0; }
+#else
+
+#include <boost/convert.hpp>
+#include <boost/convert/printf.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+using std::string;
+using boost::convert;
+
+namespace arg = boost::cnv::parameter;
+
+int
+main(int, char const* [])
+{
+ boost::cnv::printf cnv;
+
+ string const not_int_str = "not an int";
+ string const std_str = "-11";
+ char const* const c_str = "-12";
+
+ BOOST_TEST( -1 == convert<int>(not_int_str, cnv).value_or(-1));
+ BOOST_TEST(-11 == convert<int>(std_str, cnv).value_or(-1));
+ BOOST_TEST(-12 == convert<int>(c_str, cnv).value_or(-1));
+
+ BOOST_TEST("255" == convert<std::string>(255, cnv(arg::base = boost::cnv::base::dec)).value());
+ BOOST_TEST( "ff" == convert<std::string>(255, cnv(arg::base = boost::cnv::base::hex)).value());
+ BOOST_TEST("377" == convert<std::string>(255, cnv(arg::base = boost::cnv::base::oct)).value());
+
+ string s01 = convert<string>(12.3456, cnv(arg::precision = 6)).value();
+ string s02 = convert<string>(12.3456, cnv(arg::precision = 3)).value();
+
+ BOOST_TEST(s01 == "12.345600");
+ BOOST_TEST(s02 == "12.346");
+
+ return boost::report_errors();
+}
+
+#endif
diff --git a/src/boost/libs/convert/test/sfinae.cpp b/src/boost/libs/convert/test/sfinae.cpp
new file mode 100644
index 000000000..5236a4d6c
--- /dev/null
+++ b/src/boost/libs/convert/test/sfinae.cpp
@@ -0,0 +1,159 @@
+// Boost.Convert test and usage example
+// Copyright (c) 2009-2016 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#include "./test.hpp"
+
+#if defined(BOOST_CONVERT_IS_NOT_SUPPORTED)
+int main(int, char const* []) { return 0; }
+#else
+
+#include <boost/convert.hpp>
+#include <boost/convert/detail/is_string.hpp>
+#include <boost/convert/detail/is_callable.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+//[is_callable_declaration
+namespace { namespace local
+{
+ BOOST_DECLARE_IS_CALLABLE(can_call_funop, operator());
+ BOOST_DECLARE_IS_CALLABLE(can_call_func, func);
+}}
+//]
+
+//[is_callable_classes_tested
+namespace { namespace callable
+{
+ struct test1 { int operator()(double, std::string) { return 0; }};
+ struct test2 { void operator()(double, std::string) {}};
+ struct test3 { void operator()(int) {}};
+ struct test4 { std::string operator()(int) const { return std::string(); }};
+ struct test5 { std::string operator()(int, std::string const& =std::string()) const { return std::string(); }};
+ struct test6 { template<typename T> std::string operator()(T) const { return std::string(); }};
+ struct test7 { template<typename T> T operator()(T) const { return T(); }};
+
+ struct test11 { int func(double, std::string) { return 0; }};
+ struct test12 { void func(double, std::string) {}};
+ struct test13 { void func(int) {}};
+ struct test14 { std::string func(int) const { return std::string(); }};
+ struct test15 { std::string func(int, std::string const& =std::string()) const { return std::string(); }};
+ struct test16 { template<typename T> std::string func(T) const { return std::string(); }};
+ struct test17 { template<typename T> T func(T) const { return T(); }};
+}}
+//]
+
+static
+void
+test_is_callable()
+{
+ // C1. Unfortunately, passing 'double' where 'int' is expected returns 'true'.
+ // The same as the following (which successfully compiles):
+ // void fun(int) {}
+ // fun(double(1));
+
+ //[is_callable_usage1
+ BOOST_TEST((local::can_call_funop<callable::test1, int (double, std::string)>::value == true));
+ BOOST_TEST((local::can_call_funop<callable::test1, double (int, std::string)>::value == true));
+ BOOST_TEST((local::can_call_funop<callable::test1, void (double, std::string)>::value == true));
+ BOOST_TEST((local::can_call_funop<callable::test1, void (int, std::string)>::value == true));
+ BOOST_TEST((local::can_call_funop<callable::test1, void (int, char const*)>::value == true));
+ BOOST_TEST((local::can_call_funop<callable::test1, int (double, int)>::value == false));
+ BOOST_TEST((local::can_call_funop<callable::test1, int (double)>::value == false));
+
+ BOOST_TEST((local::can_call_funop<callable::test2, int (double, std::string)>::value == false));
+ BOOST_TEST((local::can_call_funop<callable::test2, void (double, std::string)>::value == true));
+ BOOST_TEST((local::can_call_funop<callable::test2, void ( int, std::string)>::value == true));
+ BOOST_TEST((local::can_call_funop<callable::test2, void ( int, char const*)>::value == true));
+ //]
+ BOOST_TEST((local::can_call_funop<callable::test3, void (double)>::value == true)); //C1
+ BOOST_TEST((local::can_call_funop<callable::test3, void (int)>::value == true));
+ BOOST_TEST((local::can_call_funop<callable::test3 const, void (int)>::value == false));
+
+ BOOST_TEST((local::can_call_funop<callable::test4 const, std::string (int)>::value == true));
+ BOOST_TEST((local::can_call_funop<callable::test4, std::string (int)>::value == true));
+ BOOST_TEST((local::can_call_funop<callable::test4 const, void (int)>::value == true));
+ BOOST_TEST((local::can_call_funop<callable::test4, void (int)>::value == true));
+
+ BOOST_TEST((local::can_call_funop<callable::test5, std::string (int, std::string)>::value == true));
+ BOOST_TEST((local::can_call_funop<callable::test5, std::string (int, std::string const&)>::value == true));
+ BOOST_TEST((local::can_call_funop<callable::test5, void (int, char const*)>::value == true));
+ BOOST_TEST((local::can_call_funop<callable::test5, std::string (int)>::value == true));
+ BOOST_TEST((local::can_call_funop<callable::test5 const, std::string (int)>::value == true));
+ BOOST_TEST((local::can_call_funop<callable::test5, void (int)>::value == true));
+ BOOST_TEST((local::can_call_funop<callable::test5 const, void (int)>::value == true));
+ BOOST_TEST((local::can_call_funop<callable::test5, void (char const*)>::value == false));
+ BOOST_TEST((local::can_call_funop<callable::test5 const, void (char const*)>::value == false));
+
+ BOOST_TEST((local::can_call_funop<callable::test6, std::string (int)>::value == true));
+ BOOST_TEST((local::can_call_funop<callable::test6, std::string (std::string)>::value == true));
+ BOOST_TEST((local::can_call_funop<callable::test6, void (int)>::value == true));
+ BOOST_TEST((local::can_call_funop<callable::test6, void (std::string)>::value == true));
+
+ BOOST_TEST((local::can_call_funop<callable::test7, std::string (int)>::value == false));
+ BOOST_TEST((local::can_call_funop<callable::test7, std::string (std::string)>::value == true));
+ BOOST_TEST((local::can_call_funop<callable::test7, void (int)>::value == true));
+ BOOST_TEST((local::can_call_funop<callable::test7, void (std::string)>::value == true));
+
+ //[is_callable_usage2
+ BOOST_TEST((local::can_call_func<callable::test11, int (double, std::string)>::value == true));
+ BOOST_TEST((local::can_call_func<callable::test11, double (int, std::string)>::value == true));
+ BOOST_TEST((local::can_call_func<callable::test11, void (double, std::string)>::value == true));
+ BOOST_TEST((local::can_call_func<callable::test11, void (int, std::string)>::value == true));
+ BOOST_TEST((local::can_call_func<callable::test11, void (int, char const*)>::value == true));
+ BOOST_TEST((local::can_call_func<callable::test11, int (double, int)>::value == false));
+ BOOST_TEST((local::can_call_func<callable::test11, int (double)>::value == false));
+
+ BOOST_TEST((local::can_call_func<callable::test12, int (double, std::string)>::value == false));
+ BOOST_TEST((local::can_call_func<callable::test12, void (double, std::string)>::value == true));
+ BOOST_TEST((local::can_call_func<callable::test12, void ( int, std::string)>::value == true));
+ BOOST_TEST((local::can_call_func<callable::test12, void ( int, char const*)>::value == true));
+ //]
+ BOOST_TEST((local::can_call_func<callable::test13, void (double)>::value == true)); //C1
+ BOOST_TEST((local::can_call_func<callable::test13, void (int)>::value == true));
+ BOOST_TEST((local::can_call_func<callable::test13 const, void (int)>::value == false));
+
+ BOOST_TEST((local::can_call_func<callable::test14 const, std::string (int)>::value == true));
+ BOOST_TEST((local::can_call_func<callable::test14, std::string (int)>::value == true));
+ BOOST_TEST((local::can_call_func<callable::test14 const, void (int)>::value == true));
+ BOOST_TEST((local::can_call_func<callable::test14, void (int)>::value == true));
+
+ BOOST_TEST((local::can_call_func<callable::test15, std::string (int, std::string)>::value == true));
+ BOOST_TEST((local::can_call_func<callable::test15, std::string (int, std::string const&)>::value == true));
+ BOOST_TEST((local::can_call_func<callable::test15, void (int, char const*)>::value == true));
+ BOOST_TEST((local::can_call_func<callable::test15, std::string (int)>::value == true));
+ BOOST_TEST((local::can_call_func<callable::test15 const, std::string (int)>::value == true));
+ BOOST_TEST((local::can_call_func<callable::test15, void (int)>::value == true));
+ BOOST_TEST((local::can_call_func<callable::test15 const, void (int)>::value == true));
+ BOOST_TEST((local::can_call_func<callable::test15, void (char const*)>::value == false));
+ BOOST_TEST((local::can_call_func<callable::test15 const, void (char const*)>::value == false));
+
+ BOOST_TEST((local::can_call_func<callable::test16, std::string (int)>::value == true));
+ BOOST_TEST((local::can_call_func<callable::test16, std::string (std::string)>::value == true));
+ BOOST_TEST((local::can_call_func<callable::test16, void (int)>::value == true));
+ BOOST_TEST((local::can_call_func<callable::test16, void (std::string)>::value == true));
+
+ BOOST_TEST((local::can_call_func<callable::test17, std::string (int)>::value == false));
+ BOOST_TEST((local::can_call_func<callable::test17, std::string (std::string)>::value == true));
+ BOOST_TEST((local::can_call_func<callable::test17, void (int)>::value == true));
+ BOOST_TEST((local::can_call_func<callable::test17, void (std::string)>::value == true));
+}
+
+int
+main(int, char const* [])
+{
+ //[is_callable_usage
+ //]
+
+ test_is_callable();
+
+ BOOST_TEST(boost::cnv::is_string<direction>::value == false);
+ BOOST_TEST(boost::cnv::is_string<std::string>::value == true);
+ BOOST_TEST(boost::cnv::is_string<std::wstring>::value == true);
+ BOOST_TEST(boost::cnv::is_string<my_string>::value == true);
+ BOOST_TEST(boost::cnv::is_string<int>::value == false);
+
+ return boost::report_errors();
+}
+
+#endif
diff --git a/src/boost/libs/convert/test/spirit_converter.cpp b/src/boost/libs/convert/test/spirit_converter.cpp
new file mode 100644
index 000000000..bbbc5b976
--- /dev/null
+++ b/src/boost/libs/convert/test/spirit_converter.cpp
@@ -0,0 +1,87 @@
+// Boost.Convert test and usage example
+// Copyright (c) 2009-2016 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#include "./test.hpp"
+
+#if defined(BOOST_CONVERT_IS_NOT_SUPPORTED)
+int main(int, char const* []) { return 0; }
+#else
+
+#include <boost/convert.hpp>
+#include <boost/convert/spirit.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <cstdio>
+
+using std::string;
+using std::wstring;
+using boost::convert;
+
+namespace cnv = boost::cnv;
+namespace arg = boost::cnv::parameter;
+
+struct boost::cnv::by_default : boost::cnv::spirit {};
+
+int
+main(int, char const* [])
+{
+ char const* const c_stri ("12345");
+ char const* const c_strd ("123.45");
+ wchar_t const* const c_wstri (L"12345");
+ wchar_t const* const c_wstrd (L"123.45");
+ std::string const std_stri (c_stri);
+ std::string const std_strd (c_strd);
+ std::wstring const std_wstri (c_wstri);
+ std::wstring const std_wstrd (c_wstrd);
+ my_string const my_stri (c_stri, c_stri + strlen(c_stri));
+ my_string const my_strd (c_strd, c_strd + strlen(c_strd));
+
+ boost::cnv::spirit cnv;
+
+ BOOST_TEST( 12345 == convert< int>( c_stri).value());
+ BOOST_TEST( 12345 == convert< int>( c_wstri).value());
+ BOOST_TEST( 12345 == convert< int>( std_stri).value());
+ BOOST_TEST( 12345 == convert< int>(std_wstri).value());
+ BOOST_TEST( 12345 == convert< int>( my_stri).value());
+ BOOST_TEST( 12345 == convert<unsigned int>(c_stri).value());
+ BOOST_TEST( 12345 == convert<long int>( c_stri).value());
+ BOOST_TEST( 12345 == convert<long int>( c_wstri).value());
+ BOOST_TEST( 12345 == convert<long int>( std_stri).value());
+ BOOST_TEST( 12345 == convert<long int>(std_wstri).value());
+ BOOST_TEST( 12345 == convert<long int>( my_stri).value());
+ BOOST_TEST( 12345 == convert<unsigned long int>(c_stri).value());
+ BOOST_TEST( 12345 == convert<long long int>(c_stri).value());
+ BOOST_TEST( 12345 == convert<unsigned long long int>(c_stri).value());
+ BOOST_TEST(123.45 == convert< double>( c_strd).value());
+ BOOST_TEST(123.45 == convert< double>( c_wstrd).value());
+// BOOST_TEST(123.45 == convert< double>( std_strd).value());
+// BOOST_TEST(123.45 == convert< double>(std_wstrd).value());
+ BOOST_TEST(123.45 == convert< double>( my_strd).value());
+
+ BOOST_TEST(!convert< int>("uhm"));
+ BOOST_TEST(!convert< int>(L"uhm"));
+ BOOST_TEST(!convert<double>("12.uhm"));
+ BOOST_TEST(!convert<double>("L12.uhm"));
+
+ BOOST_TEST( "1234" == convert<string>(1234).value());
+ BOOST_TEST( "1234" == convert<string>(1234u).value());
+ BOOST_TEST( "1234" == convert<string>(1234ll).value());
+ BOOST_TEST( "1234" == convert<string>(1234ull).value());
+ BOOST_TEST( L"1234" == convert<wstring>(1234).value());
+ BOOST_TEST( "12xxx" == convert<string>(12, cnv(arg::width = 5)
+ (arg::fill = 'x')
+ (arg::adjust = cnv::adjust::left)).value());
+ BOOST_TEST(L"12xxx" == convert<wstring>(12, cnv(arg::width = 5)
+ (arg::fill = 'x')
+ (arg::adjust = cnv::adjust::left)).value());
+ BOOST_TEST( "x12xx" == convert<string>(12, cnv(arg::adjust = cnv::adjust::center)).value());
+ BOOST_TEST(L"x12xx" == convert<wstring>(12, cnv(arg::adjust = cnv::adjust::center)).value());
+
+// BOOST_TEST("12.34" == convert<std::string>(12.34).value());
+// printf("%s\n", convert<std::string>(12.34).value().c_str());
+
+ return boost::report_errors();
+}
+
+#endif
diff --git a/src/boost/libs/convert/test/str_to_int.cpp b/src/boost/libs/convert/test/str_to_int.cpp
new file mode 100644
index 000000000..42951c0d1
--- /dev/null
+++ b/src/boost/libs/convert/test/str_to_int.cpp
@@ -0,0 +1,156 @@
+// Boost.Convert test and usage example
+// Copyright (c) 2009-2016 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#include "./test.hpp"
+
+#if defined(BOOST_CONVERT_IS_NOT_SUPPORTED)
+int main(int, char const* []) { return 0; }
+#else
+
+#include <boost/convert.hpp>
+#include <boost/convert/stream.hpp>
+#include <boost/convert/printf.hpp>
+#include <boost/convert/strtol.hpp>
+#include <boost/convert/lexical_cast.hpp>
+#include <boost/convert/spirit.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+using std::string;
+
+template<typename Converter>
+void
+int_to_str(Converter const& cnv)
+{
+ string const not_int_str = "not an int";
+ string const std_str = "-11";
+ char const* const c_str = "-12";
+ char const array_str[] = "-15";
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Testing int-to-string conversion with various string
+ // containers as the fallback values.
+ ////////////////////////////////////////////////////////////////////////////
+
+ string s01 = boost::convert< string>(-1, cnv).value_or(std_str);
+ string s02 = boost::convert< string>(-2, cnv).value_or(c_str);
+ string s05 = boost::convert< string>(-5, cnv).value_or(array_str);
+ boost::optional< string> rs01 = boost::convert< string>(-1, cnv);
+ boost::optional< string> rs02 = boost::convert< string>(-2, cnv);
+ boost::optional< string> rs05 = boost::convert< string>(-5, cnv);
+
+ BOOST_TEST(s01 == "-1"); BOOST_TEST(rs01 && rs01.value() == "-1");
+ BOOST_TEST(s02 == "-2"); BOOST_TEST(rs02 && rs02.value() == "-2");
+ BOOST_TEST(s05 == "-5"); BOOST_TEST(rs05 && rs05.value() == "-5");
+
+ string s11 = boost::convert< string>(-1, cnv).value();
+ boost::optional< string> rs11 = boost::convert< string>(-1, cnv);
+
+ BOOST_TEST( s11 == "-1");
+ BOOST_TEST(rs11 && rs11.value() == "-1");
+}
+
+template<typename Converter>
+void
+str_to_int(Converter const& cnv)
+{
+ string const not_int_str = "not an int";
+ string const std_str = "-11";
+ char const* const c_str = "-123";
+ char const array_str[] = "3456";
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Testing various kinds of string containers.
+ // Testing implicit conversion directly to TypeOut (int).
+ // Testing with the fallback value value provided.
+ // On failure returns the provided fallback value and DOES NOT THROW.
+ ////////////////////////////////////////////////////////////////////////////
+
+ int const a00 = boost::convert<int>(not_int_str, cnv).value_or(-1);
+ int const a01 = boost::convert<int>(std_str, cnv).value_or(-1);
+ int const a02 = boost::convert<int>(c_str, cnv).value_or(-1);
+ int const a05 = boost::convert<int>(array_str, cnv).value_or(-1);
+
+ BOOST_TEST(a00 == -1); // Failed conversion
+ BOOST_TEST(a01 == -11);
+ BOOST_TEST(a02 == -123);
+ BOOST_TEST(a05 == 3456);
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Testing "optional"
+ ////////////////////////////////////////////////////////////////////////////
+
+ boost::optional<int> const r00 = boost::convert<int>(not_int_str, cnv);
+ boost::optional<int> const r01 = boost::convert<int>(std_str, cnv);
+ boost::optional<int> const r02 = boost::convert<int>(c_str, cnv);
+ boost::optional<int> const r05 = boost::convert<int>(array_str, cnv);
+
+ BOOST_TEST(!r00); // Failed conversion
+ BOOST_TEST( r01 && r01.value() == -11);
+ BOOST_TEST( r02 && r02.value() == -123);
+ BOOST_TEST( r05 && r05.value() == 3456);
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Testing value() on invalid result.
+ ////////////////////////////////////////////////////////////////////////////
+
+ try
+ {
+ boost::convert<int>(not_int_str, cnv).value();
+ BOOST_TEST(!"failed to throw");
+ }
+ catch (std::exception&)
+ {
+ // Expected behavior: received 'boost::convert failed' exception. All well.
+ }
+ ////////////////////////////////////////////////////////////////////////////
+ // Testing value() on valid result.
+ ////////////////////////////////////////////////////////////////////////////
+
+ int a21 = boost::convert<int>(std_str, cnv).value();
+ int a22 = boost::convert<int>(c_str, cnv).value();
+ int a25 = boost::convert<int>(array_str, cnv).value();
+
+ BOOST_TEST(a21 == -11);
+ BOOST_TEST(a22 == -123);
+ BOOST_TEST(a25 == 3456);
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Testing empty string.
+ ////////////////////////////////////////////////////////////////////////////
+
+ int a31 = boost::convert<int>(std::string(), cnv).value_or(-1);
+ int a32 = boost::convert<int>(std::string(""), cnv).value_or(-1);
+ int a33 = boost::convert<int>("", cnv).value_or(-1);
+
+ BOOST_ASSERT(a31 == -1);
+ BOOST_ASSERT(a32 == -1);
+ BOOST_ASSERT(a33 == -1);
+}
+
+int
+main(int, char const* [])
+{
+ boost::cnv::lexical_cast lxcast_cnv;
+ boost::cnv::cstream stream_cnv;
+ boost::cnv::strtol strtol_cnv;
+ boost::cnv::printf printf_cnv;
+ boost::cnv::spirit spirit_cnv;
+
+ str_to_int(lxcast_cnv);
+ str_to_int(stream_cnv);
+ str_to_int(strtol_cnv);
+ str_to_int(printf_cnv);
+ str_to_int(spirit_cnv);
+
+ int_to_str(lxcast_cnv);
+ int_to_str(stream_cnv);
+ int_to_str(strtol_cnv);
+ int_to_str(printf_cnv);
+ int_to_str(spirit_cnv);
+
+ return boost::report_errors();
+}
+
+#endif
diff --git a/src/boost/libs/convert/test/stream_converter.cpp b/src/boost/libs/convert/test/stream_converter.cpp
new file mode 100644
index 000000000..fcab03da3
--- /dev/null
+++ b/src/boost/libs/convert/test/stream_converter.cpp
@@ -0,0 +1,381 @@
+// Boost.Convert test and usage example
+// Copyright (c) 2009-2016 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#include "./test.hpp"
+
+#if defined(BOOST_CONVERT_IS_NOT_SUPPORTED)
+int main(int, char const* []) { return 0; }
+#else
+
+#include <boost/convert.hpp>
+#include <boost/convert/stream.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <cstdio>
+#include <cstdlib>
+#include <stdlib.h>
+
+//[stream_using
+using std::string;
+using std::wstring;
+using boost::convert;
+//]
+//[stream_cnv_namespace_shortcut
+namespace cnv = boost::cnv;
+namespace arg = boost::cnv::parameter;
+//]
+
+static
+void
+test_dbl_to_str()
+{
+ boost::cnv::cstream cnv;
+
+ cnv(std::fixed);
+
+ BOOST_TEST(convert<string>( 99.999, cnv(arg::precision = 2)).value_or("bad") == "100.00");
+ BOOST_TEST(convert<string>( 99.949, cnv(arg::precision = 2)).value_or("bad") == "99.95");
+ BOOST_TEST(convert<string>(-99.949, cnv(arg::precision = 2)).value_or("bad") == "-99.95");
+ BOOST_TEST(convert<string>( 99.949, cnv(arg::precision = 1)).value_or("bad") == "99.9");
+ BOOST_TEST(convert<string>( 0.999, cnv(arg::precision = 2)).value_or("bad") == "1.00");
+ BOOST_TEST(convert<string>( -0.999, cnv(arg::precision = 2)).value_or("bad") == "-1.00");
+ BOOST_TEST(convert<string>( 0.949, cnv(arg::precision = 2)).value_or("bad") == "0.95");
+ BOOST_TEST(convert<string>( -0.949, cnv(arg::precision = 2)).value_or("bad") == "-0.95");
+ BOOST_TEST(convert<string>( 1.949, cnv(arg::precision = 1)).value_or("bad") == "1.9");
+ BOOST_TEST(convert<string>( -1.949, cnv(arg::precision = 1)).value_or("bad") == "-1.9");
+}
+
+static
+void
+test_numbase()
+{
+ //[stream_numbase_example1
+ /*`The following example demonstrates the deployment of `std::dec`, `std::oct` `std::hex`
+ manipulators:
+ */
+ boost::cnv::cstream ccnv;
+
+ BOOST_TEST(convert<int>( "11", ccnv(std::hex)).value_or(0) == 17); // 11(16) = 17(10)
+ BOOST_TEST(convert<int>( "11", ccnv(std::oct)).value_or(0) == 9); // 11(8) = 9(10)
+ BOOST_TEST(convert<int>( "11", ccnv(std::dec)).value_or(0) == 11);
+
+ BOOST_TEST(convert<string>( 18, ccnv(std::hex)).value_or("bad") == "12"); // 18(10) = 12(16)
+ BOOST_TEST(convert<string>( 10, ccnv(std::oct)).value_or("bad") == "12"); // 10(10) = 12(8)
+ BOOST_TEST(convert<string>( 12, ccnv(std::dec)).value_or("bad") == "12");
+ BOOST_TEST(convert<string>(255, ccnv(arg::base = boost::cnv::base::oct)).value_or("bad") == "377");
+ BOOST_TEST(convert<string>(255, ccnv(arg::base = boost::cnv::base::hex)).value_or("bad") == "ff");
+ BOOST_TEST(convert<string>(255, ccnv(arg::base = boost::cnv::base::dec)).value_or("bad") == "255");
+
+ ccnv(std::showbase);
+
+ BOOST_TEST(convert<string>(18, ccnv(std::hex)).value_or("bad") == "0x12");
+ BOOST_TEST(convert<string>(10, ccnv(std::oct)).value_or("bad") == "012");
+
+ ccnv(std::uppercase);
+
+ BOOST_TEST(convert<string>(18, ccnv(std::hex)).value_or("bad") == "0X12");
+ //]
+ //[stream_numbase_example2
+ BOOST_TEST(convert<int>("11", ccnv(arg::base = cnv::base::hex)).value_or(0) == 17);
+ BOOST_TEST(convert<int>("11", ccnv(arg::base = cnv::base::oct)).value_or(0) == 9);
+ BOOST_TEST(convert<int>("11", ccnv(arg::base = cnv::base::dec)).value_or(0) == 11);
+ //]
+ //[wide_stream_numeric_base
+ boost::cnv::wstream wcnv;
+
+ BOOST_TEST(convert<int>(L"11", wcnv(std::hex)).value_or(0) == 17); // 11(16) = 17(10)
+ BOOST_TEST(convert<int>(L"11", wcnv(std::oct)).value_or(0) == 9); // 11(8) = 9(10)
+ BOOST_TEST(convert<int>(L"11", wcnv(std::dec)).value_or(0) == 11);
+
+ BOOST_TEST(convert<wstring>(254, wcnv(arg::base = cnv::base::dec)).value_or(L"bad") == L"254");
+ BOOST_TEST(convert<wstring>(254, wcnv(arg::base = cnv::base::hex)).value_or(L"bad") == L"fe");
+ BOOST_TEST(convert<wstring>(254, wcnv(arg::base = cnv::base::oct)).value_or(L"bad") == L"376");
+ //]
+}
+
+static
+void
+test_boolalpha()
+{
+ boost::cnv::cstream cnv;
+ //[stream_boolalpha_example
+ BOOST_TEST(convert<string>( true, cnv(std::boolalpha)).value_or("bad") == "true");
+ BOOST_TEST(convert<string>(false, cnv(std::boolalpha)).value_or("bad") == "false");
+
+ BOOST_TEST(convert<bool>( "true", cnv(std::boolalpha)).value_or(false) == true);
+ BOOST_TEST(convert<bool>("false", cnv(std::boolalpha)).value_or( true) == false);
+
+ BOOST_TEST(convert<string>( true, cnv(std::noboolalpha)).value_or("bad") == "1");
+ BOOST_TEST(convert<string>(false, cnv(std::noboolalpha)).value_or("bad") == "0");
+
+ BOOST_TEST(convert<bool>("1", cnv(std::noboolalpha)).value_or(false) == true);
+ BOOST_TEST(convert<bool>("0", cnv(std::noboolalpha)).value_or( true) == false);
+ //]
+}
+
+static
+void
+test_skipws_char()
+{
+ //[stream_skipws_example
+ boost::cnv::cstream ccnv;
+ char const* const cstr_good = " 123";
+ char const* const cstr_bad = " 123 "; // std::skipws only affects leading spaces.
+
+ ccnv(std::skipws); // Ignore leading whitespaces
+// ccnv(arg::skipws = true); // Ignore leading whitespaces. Alternative interface
+
+ BOOST_TEST(convert<int>(cstr_good, ccnv).value_or(0) == 123);
+ BOOST_TEST(convert<string>(" 123", ccnv).value_or("bad") == "123");
+
+ BOOST_TEST(!convert<int>(cstr_bad, ccnv));
+
+ ccnv(std::noskipws); // Do not ignore leading whitespaces
+// ccnv(arg::skipws = false); // Do not ignore leading whitespaces. Alternative interface
+
+ // All conversions fail.
+ BOOST_TEST(!convert<int>(cstr_good, ccnv));
+ BOOST_TEST(!convert<int>( cstr_bad, ccnv));
+ //]
+}
+
+static
+void
+test_skipws_wchar()
+{
+ //[wide_stream_skipws
+ boost::cnv::wstream wcnv;
+
+ wcnv(std::noskipws); // Do not ignore leading whitespaces
+
+ BOOST_TEST( convert<int>( L"123", wcnv).value_or(0) == 123);
+ BOOST_TEST(!convert<int>( L" 123", wcnv));
+ BOOST_TEST(!convert<int>(L" 123 ", wcnv));
+
+ wcnv(std::skipws); // Ignore leading whitespaces
+// wcnv(arg::skipws = true); // Ignore leading whitespaces. Alternative interface
+
+ BOOST_TEST( convert<int>( L" 123", wcnv).value_or(0) == 123);
+ BOOST_TEST(!convert<int>(L" 123 ", wcnv));
+ //]
+}
+
+static
+void
+test_width()
+{
+ //[stream_width_example
+ boost::cnv::cstream cnv;
+
+ boost::optional<string> s01 = convert<string>(12, cnv(std::setw(4)));
+ boost::optional<string> s02 = convert<string>(12, cnv(std::setw(5))(std::setfill('*')));
+ boost::optional<string> s03 = convert<string>(12, cnv(std::setw(5))(std::setfill('*'))(std::left));
+
+ BOOST_TEST(s01 && s01.value() == " 12"); // Field width = 4.
+ BOOST_TEST(s02 && s02.value() == "***12"); // Field width = 5, filler = '*'.
+ BOOST_TEST(s03 && s03.value() == "12***"); // Field width = 5, filler = '*', left adjustment
+
+ /*`It needs to be remembered that `boost::cnv::stream` converter uses `std::stream` as its underlying
+ conversion engine. Consequently, formatting-related behavior are driven by the `std::stream`. Namely,
+ after every operation is performed, the ['default field width is restored]. The values of
+ the fill character and the adjustment remain unchanged until they are modified explicitly.
+ */
+
+ // The fill and adjustment remain '*' and 'left'.
+ boost::optional<string> s11 = convert<string>(12, cnv(arg::width = 4));
+ boost::optional<string> s12 = convert<string>(12, cnv(arg::width = 5)
+ (arg::fill = ' ')
+ (arg::adjust = cnv::adjust::right));
+
+ BOOST_TEST(s11 && s11.value() == "12**"); // Field width was set to 4.
+ BOOST_TEST(s12 && s12.value() == " 12"); // Field width was set to 5 with the ' ' filler.
+ //]
+}
+
+static
+void
+test_manipulators()
+{
+ boost::cnv::cstream ccnv;
+ boost::cnv::wstream wcnv;
+
+ int const hex_v01 = boost::convert<int>("FF", ccnv(std::hex)).value_or(0);
+ int const hex_v02 = boost::convert<int>(L"F", wcnv(std::hex)).value_or(0);
+ int const hex_v03 = boost::convert<int>("FF", ccnv(std::dec)).value_or(-5);
+ int const hex_v04 = boost::convert<int>(L"F", wcnv(std::dec)).value_or(-6);
+
+ BOOST_TEST(hex_v01 == 255); // "FF"
+ BOOST_TEST(hex_v02 == 15); // L"F"
+ BOOST_TEST(hex_v03 == -5); // Failed conversion
+ BOOST_TEST(hex_v04 == -6); // Failed conversion
+
+ ccnv(std::noshowbase)(std::nouppercase)(std::oct);
+
+ BOOST_TEST(boost::convert<string>(255, ccnv).value_or("bad") == "377");
+ BOOST_TEST(boost::convert<string>( 15, ccnv).value_or("bad") == "17");
+
+ ccnv(std::showbase);
+
+ BOOST_TEST(boost::convert<string>(255, ccnv).value_or("bad") == "0377");
+ BOOST_TEST(boost::convert<string>( 15, ccnv).value_or("bad") == "017");
+
+ ccnv(std::uppercase)(std::hex);
+
+ BOOST_TEST(boost::convert<string>(255, ccnv).value_or("bad") == "0XFF");
+ BOOST_TEST(boost::convert<string>( 15, ccnv).value_or("bad") == "0XF");
+
+ ccnv(std::noshowbase)(std::nouppercase)(std::oct);
+
+ BOOST_TEST(boost::convert<string>(255, ccnv).value_or("bad") == "377");
+ BOOST_TEST(boost::convert<string>( 15, ccnv).value_or("bad") == "17");
+
+ ccnv(std::showbase)(arg::uppercase = true)(arg::base = cnv::base::hex);
+
+ BOOST_TEST(boost::convert<string>(255, ccnv).value_or("bad") == "0XFF");
+ BOOST_TEST(boost::convert<string>( 15, ccnv).value_or("bad") == "0XF");
+}
+
+void
+test_locale_example()
+{
+ //[stream_locale_example1
+ boost::cnv::cstream cnv;
+ std::locale rus_locale;
+ std::locale eng_locale;
+
+ char const* eng_locale_name = test::cnv::is_msc ? "English_United States.1251" : "en_US.UTF-8";
+ char const* rus_locale_name = test::cnv::is_msc ? "Russian_Russia.1251" : "ru_RU.UTF-8";
+ char const* rus_expected = test::cnv::is_msc ? "1,235e-002" : "1,235e-02";
+ char const* eng_expected = test::cnv::is_msc ? "1.235e-002" : "1.235e-02";
+ char const* dbl_expected = test::cnv::is_msc ? "1.2345E-002" : "1.2345E-02";
+
+// cnv(std::setprecision(4))(std::uppercase)(std::scientific);
+ cnv(arg::precision = 4)
+ (arg::uppercase = true)
+ (arg::notation = cnv::notation::scientific);
+
+ double double_v01 = convert<double>(dbl_expected, cnv).value_or(0);
+ string double_s02 = convert<string>(double_v01, cnv).value_or("bad");
+
+ BOOST_TEST(dbl_expected == double_s02);
+
+ try { rus_locale = std::locale(rus_locale_name); }
+ catch (...) { printf("Bad locale %s.\n", rus_locale_name); exit(1); }
+
+ try { eng_locale = std::locale(eng_locale_name); }
+ catch (...) { printf("Bad locale %s.\n", eng_locale_name); exit(1); }
+
+// cnv(std::setprecision(3))(std::nouppercase);
+ cnv(arg::precision = 3)(arg::uppercase = false);
+
+ string double_rus = convert<string>(double_v01, cnv(rus_locale)).value_or("bad double_rus");
+ string double_eng = convert<string>(double_v01, cnv(eng_locale)).value_or("bad double_eng");
+
+ BOOST_TEST(double_rus == rus_expected);
+ BOOST_TEST(double_eng == eng_expected);
+ //]
+}
+
+void
+test_locale(double v, boost::cnv::cstream const& cnv, char const* expected)
+{
+ boost::optional<string> res = convert<string>(v, cnv);
+ std::string str = res ? *res : "conversion failed";
+
+ BOOST_TEST(res);
+ BOOST_TEST(str == expected);
+
+ if (str != expected)
+ printf("%s [%d]: result=<%s>, expected=<%s>\n", __FILE__, __LINE__, str.c_str(), expected);
+}
+
+static
+void
+test_locale()
+{
+ boost::cnv::cstream cnv;
+ std::locale rus_locale;
+ std::locale eng_locale;
+ bool eng_ignore = false;
+ bool rus_ignore = false;
+ char const* eng_locale_name = test::cnv::is_msc ? "English_United States.1251" : "en_US.UTF-8";
+ char const* rus_locale_name = test::cnv::is_msc ? "Russian_Russia.1251" : "ru_RU.UTF-8";
+ char const* eng_expected = test::cnv::is_old_msc ? "1.235e-002" : "1.235e-02";
+ char const* rus_expected = test::cnv::is_old_msc ? "1,235e-002" : "1,235e-02";
+ char const* dbl_expected = test::cnv::is_old_msc ? "1.2345E-002" : "1.2345E-02";
+
+ cnv(arg::precision = 4)
+ (arg::uppercase = true)
+ (arg::notation = cnv::notation::scientific);
+
+ double const double_v01 = convert<double>(dbl_expected, cnv).value_or(0);
+ string const double_s02 = convert<string>(double_v01, cnv).value_or("bad");
+
+ BOOST_TEST(double_v01 != 0);
+ BOOST_TEST(dbl_expected == double_s02);
+
+ if (dbl_expected != double_s02)
+ printf("%s [%d]: <%s> != <%s>\n", __FILE__, __LINE__, dbl_expected, double_s02.c_str());
+
+ try { eng_locale = std::locale(eng_locale_name); }
+ catch (...) { printf("Bad locale %s. Ignored.\n", eng_locale_name); eng_ignore = true; }
+
+ try { rus_locale = std::locale(rus_locale_name); }
+ catch (...) { printf("Bad locale %s. Ignored.\n", rus_locale_name); rus_ignore = true; }
+
+// cnv(std::setprecision(3))(std::nouppercase);
+ cnv(arg::precision = 3)(arg::uppercase = false);
+
+ if (!eng_ignore) test_locale(double_v01, cnv(eng_locale), eng_expected);
+ if (!rus_ignore) test_locale(double_v01, cnv(rus_locale), rus_expected);
+}
+
+static
+void
+test_user_str()
+{
+ //[stream_my_string
+ boost::cnv::cstream cnv;
+ my_string my_str("123");
+
+ cnv(std::setprecision(2))(std::fixed);
+
+ BOOST_TEST(convert<int>(my_str, cnv).value_or(0) == 123);
+
+ BOOST_TEST(convert<my_string>( 99.999, cnv).value_or("bad") == "100.00");
+ BOOST_TEST(convert<my_string>( 99.949, cnv).value_or("bad") == "99.95");
+ BOOST_TEST(convert<my_string>(-99.949, cnv).value_or("bad") == "-99.95");
+ //]
+}
+
+int
+main(int, char const* [])
+{
+ try
+ {
+ // QNX fails to handle std::skipws for wchat_t.
+ // Excluding from tests so that I do not have to stare on the yellow box (regression failure)
+ /*********************/ test_skipws_char();
+ if (!test::cnv::is_qnx) test_skipws_wchar();
+
+ test_numbase();
+ test_boolalpha();
+ test_width();
+ test_manipulators();
+ test_locale();
+ test_dbl_to_str();
+ test_user_str();
+ }
+ catch(boost::bad_optional_access const&)
+ {
+ BOOST_TEST(!"Caught boost::bad_optional_access exception");
+ }
+ catch(...)
+ {
+ BOOST_TEST(!"Caught an unknown exception");
+ }
+ return boost::report_errors();
+}
+
+#endif
diff --git a/src/boost/libs/convert/test/strtol_converter.cpp b/src/boost/libs/convert/test/strtol_converter.cpp
new file mode 100644
index 000000000..69e33e345
--- /dev/null
+++ b/src/boost/libs/convert/test/strtol_converter.cpp
@@ -0,0 +1,407 @@
+// Boost.Convert test and usage example
+// Copyright (c) 2009-2016 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#include "./test.hpp"
+
+#if defined(BOOST_CONVERT_IS_NOT_SUPPORTED)
+int main(int, char const* []) { return 0; }
+#else
+
+#include <boost/convert.hpp>
+#include <boost/convert/printf.hpp>
+#include <boost/convert/stream.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/uniform_int_distribution.hpp>
+#include <boost/random/uniform_01.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/utility/string_view.hpp>
+
+//[strtol_basic_deployment_header
+#include <boost/convert.hpp>
+#include <boost/convert/strtol.hpp>
+
+using std::string;
+using std::wstring;
+using boost::convert;
+
+struct boost::cnv::by_default : boost::cnv::strtol {};
+//]
+
+static
+void
+test_str_to_uint()
+{
+ string const bad_str = "not an int";
+ string const neg_str = "-11";
+ string const std_str = "11";
+ char const* const c_str = "12";
+ boost::string_view v_str = boost::string_view(c_str, 1);
+ unsigned int const imax = (std::numeric_limits<unsigned int>::max)();
+ unsigned long int const lmax = (std::numeric_limits<unsigned long int>::max)();
+ std::string const imax_str = boost::lexical_cast<std::string>(imax);
+ std::string const lmax_str = boost::lexical_cast<std::string>(lmax);
+
+ BOOST_TEST( 0 == convert<unsigned int>(bad_str).value_or(0));
+ BOOST_TEST( 0 == convert<unsigned int>(neg_str).value_or(0));
+ BOOST_TEST( 0 == convert<unsigned long int>(neg_str).value_or(0));
+ BOOST_TEST( 0 == convert<unsigned long int>(neg_str).value_or(0));
+ BOOST_TEST(11 == convert<unsigned int>(std_str).value());
+ BOOST_TEST(12 == convert<unsigned int>( c_str).value());
+ BOOST_TEST( 1 == convert<unsigned int>( v_str).value_or(0));
+ BOOST_TEST(11 == convert<unsigned long int>(std_str).value());
+ BOOST_TEST(12 == convert<unsigned long int>( c_str).value());
+ BOOST_TEST(imax == convert< unsigned int>(imax_str).value());
+ BOOST_TEST(lmax == convert<unsigned long int>(lmax_str).value());
+}
+
+static
+void
+test_str_to_int()
+{
+ //[strtol_basic_deployment
+ string const bad_str = "not an int";
+ string const std_str = "-11";
+ char const* const c_str = "-12";
+ boost::string_view v_str = boost::string_view(c_str, 2);
+
+ BOOST_TEST( -1 == convert<int>(bad_str).value_or(-1));
+ BOOST_TEST(-11 == convert<int>(std_str).value());
+ BOOST_TEST(-12 == convert<int>( c_str).value());
+ BOOST_TEST( -1 == convert<int>( v_str).value_or(0));
+ //]
+ wstring const bad_wstr = L"not an int";
+ wstring const wstd_str = L"-11";
+ wchar_t const* const wc_str = L"-12";
+
+ BOOST_TEST( -1 == convert<int>(bad_wstr).value_or(-1));
+ BOOST_TEST(-11 == convert<int>(wstd_str).value());
+ BOOST_TEST(-12 == convert<int>( wc_str).value());
+}
+
+static
+void
+test_int_to_str()
+{
+ short const s_int = -123;
+ int const i_int = -123;
+ long const l_int = -123;
+ long long const ll_int = -123;
+
+ BOOST_TEST( "-123" == convert< std::string> ( s_int).value());
+ BOOST_TEST( "-123" == convert< std::string> ( i_int).value());
+ BOOST_TEST( "-123" == convert< std::string> ( l_int).value());
+ BOOST_TEST( "-123" == convert< std::string> (ll_int).value());
+
+ BOOST_TEST(L"-123" == convert<std::wstring> ( s_int).value());
+ BOOST_TEST(L"-123" == convert<std::wstring> ( i_int).value());
+ BOOST_TEST(L"-123" == convert<std::wstring> ( l_int).value());
+ BOOST_TEST(L"-123" == convert<std::wstring> (ll_int).value());
+
+ int const imin = (std::numeric_limits<int>::min)();
+ int const imax = (std::numeric_limits<int>::max)();
+ long int const lmin = (std::numeric_limits<long int>::min)();
+ long int const lmax = (std::numeric_limits<long int>::max)();
+ long long int const llmin = (std::numeric_limits<long long int>::min)();
+ long long int const llmax = (std::numeric_limits<long long int>::max)();
+
+ std::string const imin_str = boost::lexical_cast<std::string>(imin);
+ std::string const imax_str = boost::lexical_cast<std::string>(imax);
+ std::string const lmin_str = boost::lexical_cast<std::string>(lmin);
+ std::string const lmax_str = boost::lexical_cast<std::string>(lmax);
+ std::string const llmin_str = boost::lexical_cast<std::string>(llmin);
+ std::string const llmax_str = boost::lexical_cast<std::string>(llmax);
+
+ BOOST_TEST( imin_str == convert<std::string>( imin).value());
+ BOOST_TEST( imax_str == convert<std::string>( imax).value());
+ BOOST_TEST( lmin_str == convert<std::string>( lmin).value());
+ BOOST_TEST( lmax_str == convert<std::string>( lmax).value());
+ BOOST_TEST(llmin_str == convert<std::string>(llmin).value());
+ BOOST_TEST(llmax_str == convert<std::string>(llmax).value());
+}
+
+static
+void
+test_uint_to_str()
+{
+ unsigned short const us_int = 123;
+ unsigned int const ui_int = 123;
+ unsigned long const ul_int = 123;
+ unsigned long long const ull_int = 123;
+
+ BOOST_TEST( "123" == convert< std::string> ( us_int).value());
+ BOOST_TEST( "123" == convert< std::string> ( ui_int).value());
+ BOOST_TEST( "123" == convert< std::string> ( ul_int).value());
+ BOOST_TEST( "123" == convert< std::string> (ull_int).value());
+
+ BOOST_TEST(L"123" == convert<std::wstring> ( us_int).value());
+ BOOST_TEST(L"123" == convert<std::wstring> ( ui_int).value());
+ BOOST_TEST(L"123" == convert<std::wstring> ( ul_int).value());
+ BOOST_TEST(L"123" == convert<std::wstring> (ull_int).value());
+
+ unsigned int const uimax = (std::numeric_limits<unsigned int>::max)();
+ unsigned long int const ulmax = (std::numeric_limits<unsigned long int>::max)();
+ unsigned long long int const ullmax = (std::numeric_limits<unsigned long long int>::max)();
+
+ std::string const uimax_str = boost::lexical_cast<std::string>( uimax);
+ std::string const ulmax_str = boost::lexical_cast<std::string>( ulmax);
+ std::string const ullmax_str = boost::lexical_cast<std::string>(ullmax);
+
+ BOOST_TEST( uimax_str == convert<std::string>( uimax).value());
+ BOOST_TEST( ulmax_str == convert<std::string>( ulmax).value());
+ BOOST_TEST(ullmax_str == convert<std::string>(ullmax).value());
+}
+
+//[strtol_numeric_base_header
+#include <boost/convert.hpp>
+#include <boost/convert/strtol.hpp>
+
+using std::string;
+using std::wstring;
+using boost::convert;
+
+namespace cnv = boost::cnv;
+namespace arg = boost::cnv::parameter;
+//]
+static
+void
+test_width()
+{
+ //[strtol_width
+ boost::cnv::strtol cnv;
+
+ string s01 = convert<string>( 12, cnv(arg::width = 4)).value();
+ string s02 = convert<string>( 12, cnv(arg::width = 5)
+ (arg::fill = '*')).value();
+ string s03 = convert<string>( 12, cnv(arg::width = 5)
+ (arg::fill = 'x')
+ (arg::adjust = cnv::adjust::left)).value();
+ string s04 = convert<string>(-98, cnv(arg::width = 6)
+ (arg::fill = 'Z')
+ (arg::adjust = cnv::adjust::right)).value();
+
+ string s05 = convert<string>(-12.3451, cnv(arg::precision = 2)
+ (arg::width = 10)
+ (arg::fill = '*')
+ (arg::adjust = cnv::adjust::left)).value();
+ string s06 = convert<string>(-12.3450, cnv(arg::adjust = cnv::adjust::right)).value();
+ string s07 = convert<string>(-12.3450, cnv(arg::adjust = cnv::adjust::center)).value();
+
+ BOOST_TEST(s01 == " 12");
+ BOOST_TEST(s02 == "***12");
+ BOOST_TEST(s03 == "12xxx");
+ BOOST_TEST(s04 == "ZZZ-98");
+ BOOST_TEST(s05 == "-12.35****");
+ BOOST_TEST(s06 == "****-12.35");
+ BOOST_TEST(s07 == "**-12.35**");
+ //]
+}
+
+static
+void
+test_base()
+{
+ //[strtol_numeric_base
+ boost::cnv::strtol cnv;
+
+ BOOST_TEST( "11111110" == convert< string>(254, cnv(arg::base = cnv::base::bin)).value());
+ BOOST_TEST( "254" == convert< string>(254, cnv(arg::base = cnv::base::dec)).value());
+ BOOST_TEST( "FE" == convert< string>(254, cnv(arg::base = cnv::base::hex)).value());
+ BOOST_TEST( "376" == convert< string>(254, cnv(arg::base = cnv::base::oct)).value());
+ //]
+ //[wide_strtol_numeric_base
+ BOOST_TEST(L"11111110" == convert<wstring>(254, cnv(arg::base = cnv::base::bin)).value());
+ BOOST_TEST( L"254" == convert<wstring>(254, cnv(arg::base = cnv::base::dec)).value());
+ BOOST_TEST( L"FE" == convert<wstring>(254, cnv(arg::base = cnv::base::hex)).value());
+ BOOST_TEST( L"376" == convert<wstring>(254, cnv(arg::base = cnv::base::oct)).value());
+ //]
+}
+
+static
+void
+test_upper()
+{
+// boost::cnv::strtol cnv;
+// char const* c_lcase = "abcde";
+// char const* c_ucase = "ABCDE";
+// wchar_t const* w_lcase = L"abcde";
+// wchar_t const* w_ucase = L"ABCDE";
+//
+// BOOST_TEST(c_lcase == convert< string>(c_lcase, cnv(arg::uppercase = false)).value_or(""));
+// BOOST_TEST(c_ucase == convert< string>(c_lcase, cnv(arg::uppercase = true)).value_or(""));
+// BOOST_TEST(w_ucase == convert<wstring>(w_lcase, cnv(arg::uppercase = false)).value_or(""));
+// BOOST_TEST(w_ucase == convert<wstring>(w_lcase, cnv(arg::uppercase = true)).value_or(""));
+}
+
+static
+void
+test_skipws()
+{
+ //[strtol_skipws
+ boost::cnv::strtol cnv;
+
+ BOOST_TEST(-1 == convert<int>( " 12", cnv(arg::skipws = false)).value_or(-1));
+ BOOST_TEST(12 == convert<int>( " 12", cnv(arg::skipws = true)).value_or(-1));
+ //]
+ //[wide_strtol_skipws
+ BOOST_TEST(-1 == convert<int>(L" 12", cnv(arg::skipws = false)).value_or(-1));
+ BOOST_TEST(12 == convert<int>(L" 12", cnv(arg::skipws = true)).value_or(-1));
+ //]
+}
+
+static
+void
+dbl_to_str_example()
+{
+ //[strtol_precision
+ boost::cnv::strtol cnv;
+
+ BOOST_TEST( "12.3" == convert<string>(12.3456, cnv(arg::precision = 1)).value());
+ BOOST_TEST( "12.35" == convert<string>(12.3456, cnv(arg::precision = 2)).value());
+ BOOST_TEST("12.346" == convert<string>(12.3456, cnv(arg::precision = 3)).value());
+
+ BOOST_TEST( "-12.3" == convert<string>(-12.3456, cnv(arg::precision = 1)).value());
+ BOOST_TEST( "-12.35" == convert<string>(-12.3456, cnv(arg::precision = 2)).value());
+ BOOST_TEST("-12.346" == convert<string>(-12.3456, cnv(arg::precision = 3)).value());
+ //]
+}
+
+static
+std::pair<double, int>
+get_random()
+{
+ namespace rdm = boost::random;
+
+ static rdm::mt19937 gen (::time(0));
+ static rdm::uniform_int_distribution<> precision (0, 6);
+ static rdm::uniform_int_distribution<> int_part (0, SHRT_MAX);
+ static rdm::uniform_01<double> fraction; // uniform double in [0,1)
+ static bool sign;
+
+ double dbl = (int_part(gen) + fraction(gen)) * ((sign = !sign) ? 1 : -1);
+
+// printf("%.12f\n", dbl);
+
+ return std::make_pair(dbl, precision(gen));
+}
+
+static
+void
+compare(std::pair<double, int const> pair)
+{
+ boost::cnv::strtol cnv1;
+ boost::cnv::printf cnv2;
+
+ string s1 = convert<string>(pair.first, cnv1(arg::precision = pair.second)).value();
+ string s2 = convert<string>(pair.first, cnv2(arg::precision = pair.second)).value();
+
+ if (s1 != s2)
+ printf("dbl=%.12f(%d).strtol/printf=%s/%s.\n", pair.first, pair.second, s1.c_str(), s2.c_str());
+}
+
+static
+void
+test_str_to_dbl()
+{
+ char const* const c_str = "1.23456";
+
+ BOOST_TEST(1.2 == convert<double>(boost::string_view(c_str, 3)).value_or(0));
+ BOOST_TEST(1.23 == convert<double>(boost::string_view(c_str, 4)).value_or(0));
+}
+
+static
+void
+test_dbl_to_str()
+{
+// double round_up_abs01 = ::rint(-0.5);
+// double round_up_abs02 = ::round(-0.5);
+// double round_up_abs11 = ::rint(0.5);
+// double round_up_abs12 = ::round(0.5);
+
+// double huge_v = 987654321098765432109.123;
+//
+// printf("%f\n", huge_v);
+// string huge = convert<string>(huge_v, cnv1(arg::precision = 2)).value();
+// printf("%s\n", huge.c_str());
+
+ int const num_tries = 1000000;
+ double const dbls[] = { 0.90, 1.0, 1.1, 0.94, 0.96, 1.04, 1.05, 1.06, 9.654, 999.888 };
+ int const num_dbls = sizeof(dbls) / sizeof(dbls[0]);
+
+ printf("cnv::strtol::%s: started with %d random numbers...\n", __FUNCTION__, num_tries);
+
+ BOOST_TEST( "0" == convert<string>( 0.0, cnv::strtol()(arg::precision = 0)).value());
+ BOOST_TEST( "0.0" == convert<string>( 0.0, cnv::strtol()(arg::precision = 1)).value());
+ BOOST_TEST("0.00" == convert<string>( 0.0, cnv::strtol()(arg::precision = 2)).value());
+ BOOST_TEST( "1" == convert<string>(0.95, cnv::strtol()(arg::precision = 0)).value());
+ BOOST_TEST( "1.0" == convert<string>(0.95, cnv::strtol()(arg::precision = 1)).value());
+ BOOST_TEST("0.95" == convert<string>(0.95, cnv::strtol()(arg::precision = 2)).value());
+
+ for (int k = 0; k < num_tries; ++k)
+ compare(get_random());
+
+ for (int k = 0; k < num_dbls; ++k)
+ for (int precision = 0; precision < 3; ++precision)
+ {
+ compare(std::make_pair( dbls[k], precision));
+ compare(std::make_pair(-dbls[k], precision));
+ }
+
+ printf("cnv::strtol::%s: finished.\n", __FUNCTION__);
+}
+
+static
+void
+test_user_string()
+{
+ //[strtol_user_string
+ boost::cnv::strtol cnv;
+
+ BOOST_TEST( "12" == convert<my_string>(12, cnv).value());
+ BOOST_TEST("0.95" == convert<my_string>(0.95, cnv(arg::precision = 2)).value());
+ //]
+}
+
+static
+void
+test_user_type()
+{
+ //[strtol_user_type
+ boost::cnv::strtol cnv;
+ change up_chg = change::up;
+ change dn_chg = change::dn;
+
+ BOOST_TEST(convert<std::string>(up_chg, cnv, "bad") == "up");
+ BOOST_TEST(convert<std::string>(dn_chg, cnv, "bad") == "dn");
+ BOOST_TEST(convert<std::string>( 12, cnv, "bad") == "12");
+
+ BOOST_TEST(convert<change>("up", cnv, change::no) == change::up);
+ BOOST_TEST(convert<change>("dn", cnv, change::no) == change::dn);
+ BOOST_TEST(convert< int>("12", cnv, -1) == 12);
+ //]
+}
+
+int
+main(int, char const* [])
+{
+ dbl_to_str_example();
+
+ test_str_to_int();
+ test_str_to_uint();
+ test_int_to_str();
+ test_uint_to_str();
+ test_base();
+ test_upper();
+ test_skipws();
+ test_str_to_dbl();
+ test_dbl_to_str();
+ test_width();
+ test_user_string();
+ test_user_type();
+
+ return boost::report_errors();
+}
+
+#endif
diff --git a/src/boost/libs/convert/test/test.hpp b/src/boost/libs/convert/test/test.hpp
new file mode 100644
index 000000000..e2fbbc6e6
--- /dev/null
+++ b/src/boost/libs/convert/test/test.hpp
@@ -0,0 +1,187 @@
+// Copyright (c) 2009-2016 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#ifndef BOOST_CONVERT_TEST_HPP
+#define BOOST_CONVERT_TEST_HPP
+
+#include <boost/convert/detail/config.hpp>
+#include <boost/make_default.hpp>
+#include <boost/static_assert.hpp>
+#include <string>
+#include <istream>
+#include <string.h> // For strlen, strcmp, memcpy
+#include <memory.h> // Is needed for 'memset'
+#include <stdio.h>
+#include <time.h>
+
+#if defined(_MSC_VER)
+# pragma warning(disable: 4189) // local variable is initialized but not referenced.
+# pragma warning(disable: 4127) // conditional expression is constant.
+# pragma warning(disable: 4100) // unreferenced formal parameter.
+# pragma warning(disable: 4714) // marked as __forceinline not #endif
+# pragma warning(disable: 4706)
+# pragma warning(disable: 4005)
+# pragma warning(disable: 4459) // declaration hides global declaration
+# pragma warning(disable: 4456) // declaration hides previous local declaration
+#endif
+
+//[change_declaration
+struct change
+{
+ enum value_type { no, up, dn };
+
+ change(value_type v =no) : value_(v) {}
+ bool operator==(change v) const { return value_ == v.value_; }
+ value_type value() const { return value_; }
+
+ private: value_type value_;
+};
+//]
+//[change_stream_operators
+std::istream& operator>>(std::istream& stream, change& chg)
+{
+ std::string str; stream >> str;
+
+ /**/ if (str == "up") chg = change::up;
+ else if (str == "dn") chg = change::dn;
+ else if (str == "no") chg = change::no;
+ else stream.setstate(std::ios_base::failbit);
+
+ return stream;
+}
+
+std::ostream& operator<<(std::ostream& stream, change const& chg)
+{
+ return stream << (chg == change::up ? "up" : chg == change::dn ? "dn" : "no");
+}
+//]
+//[change_convert_operators
+inline void operator>>(change chg, boost::optional<std::string>& str)
+{
+ str = chg == change::up ? "up" : chg == change::dn ? "dn" : "no";
+}
+
+inline void operator>>(std::string const& str, boost::optional<change>& chg)
+{
+ /**/ if (str == "up") chg = change::up;
+ else if (str == "dn") chg = change::dn;
+ else if (str == "no") chg = change::no;
+}
+//]
+//[direction_declaration
+struct direction
+{
+ // Note: the class does NOT have the default constructor.
+
+ enum value_type { up, dn };
+
+ direction(value_type value) : value_(value) {}
+ bool operator==(direction that) const { return value_ == that.value_; }
+ value_type value() const { return value_; }
+
+ private: value_type value_;
+};
+//]
+//[direction_stream_operators
+std::istream& operator>>(std::istream& stream, direction& dir)
+{
+ std::string str; stream >> str;
+
+ /**/ if (str == "up") dir = direction::up;
+ else if (str == "dn") dir = direction::dn;
+ else stream.setstate(std::ios_base::failbit);
+
+ return stream;
+}
+std::ostream& operator<<(std::ostream& stream, direction const& dir)
+{
+ return stream << (dir.value() == direction::up ? "up" : "dn");
+}
+//]
+//[direction_declaration_make_default
+namespace boost
+{
+ template<> inline direction make_default<direction>()
+ {
+ return direction(direction::up);
+ }
+}
+//]
+// Quick and dirty small-string implementation for performance tests.
+//[my_string_declaration
+struct my_string
+{
+ typedef my_string this_type;
+ typedef char value_type;
+ typedef value_type* iterator;
+ typedef value_type const* const_iterator;
+
+ my_string ();
+ my_string (const_iterator, const_iterator =0);
+
+ char const* c_str () const { return storage_; }
+ const_iterator begin () const { return storage_; }
+ const_iterator end () const { return storage_ + strlen(storage_); }
+ this_type& operator= (char const*);
+
+ private:
+
+ static size_t const size_ = 12;
+ char storage_[size_];
+};
+//]
+inline
+my_string::my_string()
+{
+ storage_[0] = 0;
+}
+
+inline
+my_string::my_string(const_iterator beg, const_iterator end)
+{
+ std::size_t const sz = end ? (end - beg) : strlen(beg);
+
+ BOOST_ASSERT(sz < size_);
+ memcpy(storage_, beg, sz); storage_[sz] = 0;
+}
+
+inline
+my_string&
+my_string::operator=(char const* str)
+{
+ BOOST_ASSERT(strlen(str) < size_);
+ strcpy(storage_, str);
+ return *this;
+}
+
+inline bool operator==(char const* s1, my_string const& s2) { return strcmp(s1, s2.c_str()) == 0; }
+inline bool operator==(my_string const& s1, char const* s2) { return strcmp(s2, s1.c_str()) == 0; }
+
+namespace test
+{
+ struct cnv
+ {
+#if defined(__QNXNTO__)
+ static bool const is_qnx = true;
+#else
+ static bool const is_qnx = false;
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER < 1900
+ static bool const is_msc = true;
+ static bool const is_old_msc = true;
+#elif defined(_MSC_VER)
+ static bool const is_msc = true;
+ static bool const is_old_msc = false;
+#elif defined(__MINGW32__)
+ static bool const is_msc = true;
+ static bool const is_old_msc = true;
+#else
+ static bool const is_msc = false;
+ static bool const is_old_msc = false;
+#endif
+ };
+}
+
+#endif // BOOST_CONVERT_TEST_HPP
diff --git a/src/boost/libs/convert/test/user_type.cpp b/src/boost/libs/convert/test/user_type.cpp
new file mode 100644
index 000000000..bd2bb545f
--- /dev/null
+++ b/src/boost/libs/convert/test/user_type.cpp
@@ -0,0 +1,101 @@
+// Boost.Convert test and usage example
+// Copyright (c) 2009-2016 Vladimir Batov.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
+
+#include "./test.hpp"
+
+#if defined(BOOST_CONVERT_IS_NOT_SUPPORTED)
+int main(int, char const* []) { return 0; }
+#else
+
+#include <boost/convert.hpp>
+#include <boost/convert/stream.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/array.hpp>
+#include <vector>
+
+using std::string;
+using std::wstring;
+
+static
+void
+test_user_type()
+{
+ boost::cnv::cstream cnv; // stringstream-based char converter
+
+ direction const up_dir1 = direction::up;
+ direction const dn_dir1 = direction::dn;
+// string const up_dir0_str = boost::convert<string, direction>(direction::up, cnv).value();
+// string const dn_dir0_str = boost::convert<string, direction>(direction::dn, cnv).value();
+ string const up_dir1_str = boost::convert<string>(up_dir1, cnv).value();
+ string const dn_dir1_str = boost::convert<string>(dn_dir1, cnv).value();
+ direction const up_dir2 = boost::convert<direction>(up_dir1_str, cnv).value();
+ direction const dn_dir2 = boost::convert<direction>(dn_dir1_str, cnv).value();
+ direction const up_dir3 = boost::convert<direction>(up_dir1_str, cnv).value();
+ direction const dn_dir3 = boost::convert<direction>(dn_dir1_str, cnv).value();
+ direction const dn_dir4 = boost::convert<direction>("junk", cnv).value_or(direction::dn);
+ boost::optional<direction> up_dir4 = boost::convert<direction>("junk", cnv);
+
+// BOOST_TEST(up_dir0_str == "up");
+// BOOST_TEST(dn_dir0_str == "dn");
+ BOOST_TEST(up_dir1_str == "up");
+ BOOST_TEST(dn_dir1_str == "dn");
+ BOOST_TEST(up_dir2 == up_dir1);
+ BOOST_TEST(dn_dir2 == dn_dir1);
+ BOOST_TEST(up_dir3 == direction::up);
+ BOOST_TEST(dn_dir3 == direction::dn);
+ BOOST_TEST(dn_dir4 == direction::dn);
+ BOOST_TEST(!up_dir4); // Failed conversion
+}
+
+static
+void
+test_algorithms()
+{
+//[algorithm_example6
+ boost::array<change, 3> chgs1 = {{ change::no, change::up, change::dn }};
+ boost::array<change::value_type, 3> chgs2 = {{ change::no, change::up, change::dn }};
+ std::vector<std::string> strs1;
+ std::vector<std::string> strs2;
+ std::vector<std::string> strs3;
+ boost::cnv::cstream cnv;
+
+ std::transform(chgs1.begin(), chgs1.end(), std::back_inserter(strs1),
+ boost::cnv::apply<string>(boost::cref(cnv))); // Deduced TypeIn is 'change'
+
+ std::transform(chgs2.begin(), chgs2.end(), std::back_inserter(strs2),
+ boost::cnv::apply<string>(boost::cref(cnv))); // Deduced TypeIn is 'change::value_type'
+
+ BOOST_TEST(strs1.size() == 3);
+ BOOST_TEST(strs1[0] == "no");
+ BOOST_TEST(strs1[1] == "up");
+ BOOST_TEST(strs1[2] == "dn");
+
+ BOOST_TEST(strs2.size() == 3);
+ BOOST_TEST(strs2[0] == "0");
+ BOOST_TEST(strs2[1] == "1");
+ BOOST_TEST(strs2[2] == "2");
+//]
+//[algorithm_example7
+
+ std::transform(chgs2.begin(), chgs2.end(), std::back_inserter(strs3),
+ boost::cnv::apply<string, change>(boost::cref(cnv)));
+
+ BOOST_TEST(strs3.size() == 3);
+ BOOST_TEST(strs3[0] == "no");
+ BOOST_TEST(strs3[1] == "up");
+ BOOST_TEST(strs3[2] == "dn");
+//]
+}
+
+int
+main(int, char const* [])
+{
+ test_user_type();
+ test_algorithms();
+
+ return boost::report_errors();
+}
+
+#endif
diff --git a/src/boost/libs/convert/todo.txt b/src/boost/libs/convert/todo.txt
new file mode 100644
index 000000000..7bf36d540
--- /dev/null
+++ b/src/boost/libs/convert/todo.txt
@@ -0,0 +1,12 @@
+boost-no-inspect
+
+* Adding Doxygen comments to describe briefly the files, functions etc (so users can find which include files may be needed?)
+* I don't understand the timing figures given in Performance section. Some items refer to MSVC express 10, other detailed tables in Boost 1.55 to 11? No Clang results?
+
+* You are not using links to take from the text to the appropriate functions etc
+in the reference section. Users will find this helpful too.
+
+* The reference section could be much improved by adding brief Doxygen comments to
+the files, functions etc.
+
+