summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/detail/test
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
commit483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch)
treee5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/boost/libs/detail/test
parentInitial commit. (diff)
downloadceph-upstream.tar.xz
ceph-upstream.zip
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/detail/test')
-rw-r--r--src/boost/libs/detail/test/Jamfile32
-rw-r--r--src/boost/libs/detail/test/allocator_utilities_test.cpp40
-rw-r--r--src/boost/libs/detail/test/binary_search_test.cpp260
-rw-r--r--src/boost/libs/detail/test/blank_test.cpp32
-rw-r--r--src/boost/libs/detail/test/container_fwd/Jamfile39
-rw-r--r--src/boost/libs/detail/test/container_fwd/container_fwd_test.cpp112
-rw-r--r--src/boost/libs/detail/test/container_fwd/container_no_fwd_test.cpp14
-rw-r--r--src/boost/libs/detail/test/container_fwd/correctly_disable_fail.cpp43
-rw-r--r--src/boost/libs/detail/test/is_sorted_test.cpp137
-rw-r--r--src/boost/libs/detail/test/is_xxx_test.cpp23
-rw-r--r--src/boost/libs/detail/test/numeric_traits_test.cpp416
-rw-r--r--src/boost/libs/detail/test/reference_content_test.cpp16
-rw-r--r--src/boost/libs/detail/test/test_utf8_codecvt.cpp302
13 files changed, 1466 insertions, 0 deletions
diff --git a/src/boost/libs/detail/test/Jamfile b/src/boost/libs/detail/test/Jamfile
new file mode 100644
index 00000000..b3899255
--- /dev/null
+++ b/src/boost/libs/detail/test/Jamfile
@@ -0,0 +1,32 @@
+################################################################*# Jam #*#######
+# Copyright (C) 2010 Bryce Lelbach
+#
+# Distributed under the Boost Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+################################################################################
+
+build-project container_fwd ;
+
+project detail/test
+ : requirements
+ <toolset>clang:<cxxflags>-Wno-unused
+ <toolset>clang:<cxxflags>-Wno-tautological-compare
+ <toolset>clang:<cxxflags>-ftemplate-depth-300
+ <toolset>gcc:<cxxflags>-ftemplate-depth-300
+ <toolset>gcc:<define>_STLP_DEBUG
+ <toolset>gcc:<define>_GLIBCXX_DEBUG
+ <toolset>darwin:<cxxflags>-ftemplate-depth-300
+ ;
+
+# import rules for testing conditional on config file variables
+import ../../config/checks/config : requires ;
+
+run binary_search_test.cpp ;
+run blank_test.cpp ;
+run is_sorted_test.cpp ;
+run numeric_traits_test.cpp ;
+run is_xxx_test.cpp ;
+# run test_utf8_codecvt.cpp : : : [ requires std_wstreambuf ] ;
+run test_utf8_codecvt.cpp ;
+run allocator_utilities_test.cpp ;
+run reference_content_test.cpp ;
diff --git a/src/boost/libs/detail/test/allocator_utilities_test.cpp b/src/boost/libs/detail/test/allocator_utilities_test.cpp
new file mode 100644
index 00000000..2b06720c
--- /dev/null
+++ b/src/boost/libs/detail/test/allocator_utilities_test.cpp
@@ -0,0 +1,40 @@
+
+// Copyright 2018 Daniel James.
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/detail/allocator_utilities.hpp>
+#include <boost/static_assert.hpp>
+#include <cassert>
+
+typedef std::allocator<int> std_int_allocator;
+typedef boost::detail::allocator::rebind_to<std_int_allocator, char>::type char_allocator;
+typedef boost::detail::allocator::rebind_to<char_allocator, int>::type int_allocator;
+typedef boost::detail::allocator::rebind_to<int_allocator, char>::type char_allocator2;
+
+int main() {
+ BOOST_STATIC_ASSERT((!boost::is_same<char_allocator, int_allocator>::value));
+ BOOST_STATIC_ASSERT((boost::is_same<char_allocator, char_allocator2>::value));
+
+ // Check the constructors works okay
+ std_int_allocator a1;
+ char_allocator a2(a1);
+ char_allocator a2a(a2);
+ int_allocator a3(a2);
+
+ // Check allocate works okay
+ {
+ char_allocator::pointer p = a2.allocate(10);
+ assert(p);
+ a2.deallocate(p, 10);
+ }
+
+ // Try using the standalone construct/destroy
+ {
+ int_allocator::pointer p2 = a3.allocate(1);
+ boost::detail::allocator::construct(p2, 25);
+ assert(*p2 == 25);
+ boost::detail::allocator::destroy(p2);
+ a3.deallocate(p2, 1);
+ }
+}
diff --git a/src/boost/libs/detail/test/binary_search_test.cpp b/src/boost/libs/detail/test/binary_search_test.cpp
new file mode 100644
index 00000000..aeecfc08
--- /dev/null
+++ b/src/boost/libs/detail/test/binary_search_test.cpp
@@ -0,0 +1,260 @@
+// (C) Copyright David Abrahams 2000.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <vector>
+#include <string>
+#include <memory>
+#include <climits>
+#include <iostream>
+#include <cassert>
+#include <stdlib.h> // for rand(). Would use cstdlib but VC6.4 doesn't put it in std::
+#include <list>
+#include <algorithm>
+#include <boost/detail/binary_search.hpp>
+#include <boost/detail/workaround.hpp>
+#include <cstddef>
+
+#if defined(__SGI_STL_PORT) ? defined(__SGI_STL_OWN_IOSTREAMS) : (!defined(__GNUC__) || __GNUC__ > 2)
+# define USE_SSTREAM
+#endif
+
+#ifdef USE_SSTREAM
+# include <sstream>
+#else
+# include <strstream>
+#endif
+
+namespace {
+
+// In order to get ADL to find the comparison operators defined below, they have
+struct mystring : std::string
+{
+ typedef std::string base;
+
+ mystring(std::string const& x)
+ : base(x) {}
+};
+
+typedef std::vector<mystring> string_vector;
+
+const std::size_t sequence_length = 1000;
+
+unsigned random_number()
+{
+ return static_cast<unsigned>(::rand()) % sequence_length;
+}
+
+# ifndef USE_SSTREAM
+class unfreezer {
+ public:
+ unfreezer(std::ostrstream& s) : m_stream(s) {}
+ ~unfreezer() { m_stream.freeze(false); }
+ private:
+ std::ostrstream& m_stream;
+};
+# endif
+
+template <class T>
+void push_back_random_number_string(T& seq)
+{
+ unsigned value = random_number();
+# if defined(__SGI_STL_PORT) ? defined(__SGI_STL_OWN_IOSTREAMS) : (!defined(__GNUC__) || __GNUC__ > 2)
+ std::ostringstream s;
+ s << value;
+ seq.push_back(s.str());
+# else
+ std::ostrstream s;
+ auto unfreezer unfreeze(s);
+ s << value << char(0);
+ seq.push_back(std::string(s.str()));
+# endif
+}
+
+inline unsigned to_int(unsigned x) { return x; }
+inline unsigned to_int(const std::string& x) { return atoi(x.c_str()); }
+
+struct cmp
+{
+ template <class A1, class A2>
+ inline bool operator()(const A1& a1, const A2& a2) const
+ {
+ return to_int(a1) < to_int(a2);
+ }
+};
+
+inline bool operator<(const mystring& x, const unsigned y)
+{
+ return to_int(x) < y;
+}
+
+inline bool operator<(const unsigned y, const mystring& x)
+{
+ return y < to_int(x);
+}
+
+template <class T>
+void sort_by_value(T& x);
+
+template <class T>
+void sort_by_value_(T& v, long)
+{
+ std::sort(v.begin(), v.end(), cmp());
+}
+
+template <class T>
+void random_sorted_sequence(T& seq)
+{
+ seq.clear();
+ for (std::size_t i = 0; i < sequence_length; ++i)
+ {
+ push_back_random_number_string(seq);
+ }
+ sort_by_value(seq);
+}
+
+template <class T, class A>
+void sort_by_value_(std::list<T,A>& l, int)
+{
+# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) && !defined(__SGI_STL_PORT)
+// VC6's standard lib doesn't have a template member function for list::sort()
+ std::vector<T> seq;
+ seq.reserve(sequence_length);
+ std::copy(l.begin(), l.end(), std::back_inserter(seq));
+ sort_by_value(seq);
+ std::copy(seq.begin(), seq.end(), l.begin());
+# else
+ l.sort(cmp());
+# endif
+}
+
+template <class T>
+void sort_by_value(T& x)
+{
+ (sort_by_value_)(x, 1);
+}
+
+// A way to select the comparisons with/without a Compare parameter for testing.
+template <class Compare> struct searches
+{
+ template <class Iterator, class Key>
+ static Iterator lower_bound(Iterator start, Iterator finish, Key key, Compare cmp)
+ { return boost::detail::lower_bound(start, finish, key, cmp); }
+
+ template <class Iterator, class Key>
+ static Iterator upper_bound(Iterator start, Iterator finish, Key key, Compare cmp)
+ { return boost::detail::upper_bound(start, finish, key, cmp); }
+
+ template <class Iterator, class Key>
+ static std::pair<Iterator, Iterator> equal_range(Iterator start, Iterator finish, Key key, Compare cmp)
+ { return boost::detail::equal_range(start, finish, key, cmp); }
+
+ template <class Iterator, class Key>
+ static bool binary_search(Iterator start, Iterator finish, Key key, Compare cmp)
+ { return boost::detail::binary_search(start, finish, key, cmp); }
+};
+
+struct no_compare {};
+
+template <> struct searches<no_compare>
+{
+ template <class Iterator, class Key>
+ static Iterator lower_bound(Iterator start, Iterator finish, Key key, no_compare)
+ { return boost::detail::lower_bound(start, finish, key); }
+
+ template <class Iterator, class Key>
+ static Iterator upper_bound(Iterator start, Iterator finish, Key key, no_compare)
+ { return boost::detail::upper_bound(start, finish, key); }
+
+ template <class Iterator, class Key>
+ static std::pair<Iterator, Iterator> equal_range(Iterator start, Iterator finish, Key key, no_compare)
+ { return boost::detail::equal_range(start, finish, key); }
+
+ template <class Iterator, class Key>
+ static bool binary_search(Iterator start, Iterator finish, Key key, no_compare)
+ { return boost::detail::binary_search(start, finish, key); }
+};
+
+template <class Sequence, class Compare>
+void test_loop(Sequence& x, Compare cmp, unsigned long test_count)
+{
+ typedef typename Sequence::const_iterator const_iterator;
+
+ for (unsigned long i = 0; i < test_count; ++i)
+ {
+ random_sorted_sequence(x);
+ const const_iterator start = x.begin();
+ const const_iterator finish = x.end();
+
+ unsigned key = random_number();
+ const const_iterator l = searches<Compare>::lower_bound(start, finish, key, cmp);
+ const const_iterator u = searches<Compare>::upper_bound(start, finish, key, cmp);
+
+ bool found_l = false;
+ bool found_u = false;
+ std::size_t index = 0;
+ std::size_t count = 0;
+ unsigned last_value = 0;
+ (void)last_value;
+ for (const_iterator p = start; p != finish; ++p)
+ {
+ if (p == l)
+ found_l = true;
+
+ if (p == u)
+ {
+ assert(found_l);
+ found_u = true;
+ }
+
+ unsigned value = to_int(*p);
+ assert(value >= last_value);
+ last_value = value;
+
+ if (!found_l)
+ {
+ ++index;
+ assert(to_int(*p) < key);
+ }
+ else if (!found_u)
+ {
+ ++count;
+ assert(to_int(*p) == key);
+ }
+ else
+ assert(to_int(*p) > key);
+ }
+ assert(found_l || l == finish);
+ assert(found_u || u == finish);
+
+ std::pair<const_iterator, const_iterator>
+ range = searches<Compare>::equal_range(start, finish, key, cmp);
+ assert(range.first == l);
+ assert(range.second == u);
+
+ bool found = searches<Compare>::binary_search(start, finish, key, cmp);
+ (void)found;
+ assert(found == (u != l));
+ std::cout << "found " << count << " copies of " << key << " at index " << index << "\n";
+ }
+}
+
+}
+
+int main()
+{
+ string_vector x;
+ std::cout << "=== testing random-access iterators with <: ===\n";
+ test_loop(x, no_compare(), 25);
+ std::cout << "=== testing random-access iterators with compare: ===\n";
+ test_loop(x, cmp(), 25);
+
+ std::list<mystring> y;
+ std::cout << "=== testing bidirectional iterators with <: ===\n";
+ test_loop(y, no_compare(), 25);
+ std::cout << "=== testing bidirectional iterators with compare: ===\n";
+ test_loop(y, cmp(), 25);
+ std::cerr << "******TEST PASSED******\n";
+ return 0;
+}
diff --git a/src/boost/libs/detail/test/blank_test.cpp b/src/boost/libs/detail/test/blank_test.cpp
new file mode 100644
index 00000000..c1cf0331
--- /dev/null
+++ b/src/boost/libs/detail/test/blank_test.cpp
@@ -0,0 +1,32 @@
+
+// Copyright 2018 Daniel James.
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/blank.hpp>
+#include <boost/static_assert.hpp>
+#include <cassert>
+
+#if !defined(BOOST_NO_IOSTREAM)
+#include <sstream>
+#endif
+
+int main() {
+ BOOST_STATIC_ASSERT((boost::is_pod<boost::blank>::value));
+ BOOST_STATIC_ASSERT((boost::is_empty<boost::blank>::value));
+ BOOST_STATIC_ASSERT((boost::is_stateless<boost::blank>::value));
+
+ boost::blank b1,b2;
+ assert(b1 == b2);
+ assert(b1 <= b2);
+ assert(b1 >= b2);
+ assert(!(b1 != b2));
+ assert(!(b1 < b2));
+ assert(!(b1 > b2));
+
+#if !defined(BOOST_NO_IOSTREAM)
+ std::stringstream s;
+ s << "(" << b1 << ")";
+ assert(s.str() == "()");
+#endif
+}
diff --git a/src/boost/libs/detail/test/container_fwd/Jamfile b/src/boost/libs/detail/test/container_fwd/Jamfile
new file mode 100644
index 00000000..1c0906e7
--- /dev/null
+++ b/src/boost/libs/detail/test/container_fwd/Jamfile
@@ -0,0 +1,39 @@
+
+# Copyright 2011 Daniel James.
+# Distributed under the Boost Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+import testing ;
+
+project detail/test/container_fwd
+ : requirements
+ <warnings>all
+ <toolset>intel:<warnings>on
+ <toolset>gcc:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion"
+ <toolset>darwin:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion"
+ <toolset>clang:<cxxflags>"-pedantic -Wextra -Wmismatched-tags"
+ <warnings-as-errors>on
+ ;
+
+run container_no_fwd_test.cpp ;
+run container_fwd_test.cpp : : : : container_fwd ;
+run container_fwd_test.cpp : :
+ : <define>_STLP_DEBUG <define>_GLIBCXX_DEBUG
+ : container_fwd_debug ;
+
+# The 'correctly_disable' tests fail if forward declaring standard types
+# could work, but is currently not being done. Unfortunately, this if often
+# the case - but we can't detect it, so the tests fail and there's not much
+# we can do. There are also problems because some compilers don't support
+# the debug version of their libraries. So I felt it was best to stop these
+# tests from running in a normal test run..
+
+compile-fail correctly_disable_fail.cpp
+ : <warnings-as-errors>off
+ : correctly_disable ;
+compile-fail correctly_disable_fail.cpp
+ : <warnings-as-errors>off <define>_STLP_DEBUG <define>_GLIBCXX_DEBUG
+ : correctly_disable_debug ;
+
+explicit correctly_disable ;
+explicit correctly_disable_debug ;
diff --git a/src/boost/libs/detail/test/container_fwd/container_fwd_test.cpp b/src/boost/libs/detail/test/container_fwd/container_fwd_test.cpp
new file mode 100644
index 00000000..f12c7c37
--- /dev/null
+++ b/src/boost/libs/detail/test/container_fwd/container_fwd_test.cpp
@@ -0,0 +1,112 @@
+
+// Copyright 2005-2009 Daniel James.
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/detail/container_fwd.hpp>
+
+#if BOOST_WORKAROUND(__GNUC__, < 3) && \
+ !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
+template <class charT, class Allocator>
+static void test(
+ std::basic_string<charT, std::string_char_traits<charT>, Allocator> const&)
+{
+}
+#else
+template <class charT, class Allocator>
+static void test(
+ std::basic_string<charT, std::char_traits<charT>, Allocator> const&)
+{
+}
+#endif
+
+template <class T, class Allocator>
+static void test(std::deque<T, Allocator> const&)
+{
+}
+
+template <class T, class Allocator>
+static void test(std::list<T, Allocator> const&)
+{
+}
+
+template <class T, class Allocator>
+static void test(std::vector<T, Allocator> const&)
+{
+}
+
+template <class Key, class T, class Compare, class Allocator>
+static void test(std::map<Key, T, Compare, Allocator> const&)
+{
+}
+
+template <class Key, class T, class Compare, class Allocator>
+static void test(std::multimap<Key, T, Compare, Allocator> const&)
+{
+}
+
+template <class Key, class Compare, class Allocator>
+static void test(std::set<Key, Compare, Allocator> const&)
+{
+}
+
+template <class Key, class Compare, class Allocator>
+static void test(std::multiset<Key, Compare, Allocator> const&)
+{
+}
+
+template <std::size_t N>
+static void test(std::bitset<N> const&)
+{
+}
+
+template <class T>
+static void test(std::complex<T> const&)
+{
+}
+
+template <class X, class Y>
+static void test(std::pair<X, Y> const&)
+{
+}
+
+#include <deque>
+#include <list>
+#include <vector>
+#include <map>
+#include <set>
+#include <bitset>
+#include <string>
+#include <complex>
+#include <utility>
+
+int main()
+{
+ std::deque<int> x1;
+ std::list<std::string> x2;
+ std::vector<float> x3;
+ std::vector<bool> x4;
+ std::map<int, int> x5;
+ std::multimap<float, int*> x6;
+ std::set<std::string> x7;
+ std::multiset<std::vector<int> > x8;
+ std::bitset<10> x9;
+ std::string x10;
+ std::complex<double> x11;
+ std::pair<std::list<int>, char***> x12;
+
+ test(x1);
+ test(x2);
+ test(x3);
+ test(x4);
+ test(x5);
+ test(x6);
+ test(x7);
+ test(x8);
+ test(x9);
+ test(x10);
+ test(x11);
+ test(x12);
+
+ return 0;
+}
diff --git a/src/boost/libs/detail/test/container_fwd/container_no_fwd_test.cpp b/src/boost/libs/detail/test/container_fwd/container_no_fwd_test.cpp
new file mode 100644
index 00000000..9da09da1
--- /dev/null
+++ b/src/boost/libs/detail/test/container_fwd/container_no_fwd_test.cpp
@@ -0,0 +1,14 @@
+
+// Copyright 2010 Daniel James.
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_DETAIL_NO_CONTAINER_FWD
+
+#include <boost/detail/container_fwd.hpp>
+
+int main()
+{
+ std::set<int> x;
+ std::vector<std::string> y;
+}
diff --git a/src/boost/libs/detail/test/container_fwd/correctly_disable_fail.cpp b/src/boost/libs/detail/test/container_fwd/correctly_disable_fail.cpp
new file mode 100644
index 00000000..23016862
--- /dev/null
+++ b/src/boost/libs/detail/test/container_fwd/correctly_disable_fail.cpp
@@ -0,0 +1,43 @@
+
+// Copyright 2011 Daniel James.
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// This tests if container forwarding is correctly disabled. If it isn't
+// disabled it causes a compile error (which causes the test to pass).
+// If it is disabled it tries container forwarding. If it doesn't work
+// then there will be a compile error, indicating that it is correctly
+// disabled. But if there isn't a compile error that indicates that
+// container forwarding might work.
+//
+// Since this test only tries std::vector, it might get it wrong but I didn't
+// want it to fail because of some incompatibility with a trickier class.
+
+#define BOOST_DETAIL_TEST_CONFIG_ONLY
+#include <boost/detail/container_fwd.hpp>
+
+#if !defined(BOOST_DETAIL_NO_CONTAINER_FWD)
+#error "Failing in order to pass test"
+#else
+#define BOOST_DETAIL_TEST_FORCE_CONTAINER_FWD
+
+#undef BOOST_DETAIL_CONTAINER_FWD_HPP
+#undef BOOST_DETAIL_TEST_CONFIG_ONLY
+
+#include <boost/detail/container_fwd.hpp>
+
+template <class T, class Allocator>
+void test(std::vector<T, Allocator> const&)
+{
+}
+
+#include <vector>
+
+int main ()
+{
+ std::vector<int> x;
+ test(x);
+}
+
+#endif
+
diff --git a/src/boost/libs/detail/test/is_sorted_test.cpp b/src/boost/libs/detail/test/is_sorted_test.cpp
new file mode 100644
index 00000000..f88d91c8
--- /dev/null
+++ b/src/boost/libs/detail/test/is_sorted_test.cpp
@@ -0,0 +1,137 @@
+/*==============================================================================
+ Copyright (c) 2010-2011 Bryce Lelbach
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#include <iostream>
+#include <boost/config.hpp>
+#include <boost/array.hpp>
+#include <boost/detail/is_sorted.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+template<class T>
+struct tracking_less {
+ typedef bool result_type;
+ typedef T first_argument_type;
+ typedef T second_argument_type;
+
+ #if defined(__PATHSCALE__)
+ tracking_less (void) { }
+ ~tracking_less (void) { }
+ #endif
+
+ bool operator() (T const& x, T const& y) const {
+ std::cout << x << " < " << y << " == " << (x < y) << "\n";
+ return x < y;
+ }
+};
+
+template<class T>
+struct tracking_less_equal {
+ typedef bool result_type;
+ typedef T first_argument_type;
+ typedef T second_argument_type;
+
+ #if defined(__PATHSCALE__)
+ tracking_less_equal (void) { }
+ ~tracking_less_equal (void) { }
+ #endif
+
+ bool operator() (T const& x, T const& y) const {
+ std::cout << x << " <= " << y << " == " << (x <= y) << "\n";
+ return x <= y;
+ }
+};
+
+template<class T>
+struct tracking_greater {
+ typedef bool result_type;
+ typedef T first_argument_type;
+ typedef T second_argument_type;
+
+ #if defined(__PATHSCALE__)
+ tracking_greater (void) { }
+ ~tracking_greater (void) { }
+ #endif
+
+ bool operator() (T const& x, T const& y) const {
+ std::cout << x << " > " << y << " == " << (x > y) << "\n";
+ return x > y;
+ }
+};
+
+template<class T>
+struct tracking_greater_equal {
+ typedef bool result_type;
+ typedef T first_argument_type;
+ typedef T second_argument_type;
+
+ #if defined(__PATHSCALE__)
+ tracking_greater_equal (void) { }
+ ~tracking_greater_equal (void) { }
+ #endif
+
+ bool operator() (T const& x, T const& y) const {
+ std::cout << x << " >= " << y << " == " << (x >= y) << "\n";
+ return x >= y;
+ }
+};
+
+
+int main (void) {
+ #define IS_SORTED ::boost::detail::is_sorted
+ #define IS_SORTED_UNTIL ::boost::detail::is_sorted_until
+ using boost::array;
+ using boost::report_errors;
+
+ std::cout << std::boolalpha;
+
+ array<int, 10> a = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } };
+ array<int, 10> b = { { 0, 1, 1, 2, 5, 8, 13, 34, 55, 89 } };
+ array<int, 10> c = { { 0, 1, -1, 2, -3, 5, -8, 13, -21, 34 } };
+
+ tracking_less<int> lt;
+ tracking_less_equal<int> lte;
+ tracking_greater<int> gt;
+ tracking_greater_equal<int> gte;
+
+ BOOST_TEST_EQ(IS_SORTED_UNTIL(a.begin(), a.end()), a.end());
+ BOOST_TEST_EQ(IS_SORTED_UNTIL(a.begin(), a.end(), lt), a.end());
+ BOOST_TEST_EQ(IS_SORTED_UNTIL(a.begin(), a.end(), lte), a.end());
+ BOOST_TEST_EQ(IS_SORTED_UNTIL(a.rbegin(), a.rend(), gt).base(), a.rend().base());
+ BOOST_TEST_EQ(IS_SORTED_UNTIL(a.rbegin(), a.rend(), gte).base(), a.rend().base());
+
+ BOOST_TEST_EQ(IS_SORTED(a.begin(), a.end()), true);
+ BOOST_TEST_EQ(IS_SORTED(a.begin(), a.end(), lt), true);
+ BOOST_TEST_EQ(IS_SORTED(a.begin(), a.end(), lte), true);
+ BOOST_TEST_EQ(IS_SORTED(a.rbegin(), a.rend(), gt), true);
+ BOOST_TEST_EQ(IS_SORTED(a.rbegin(), a.rend(), gte), true);
+
+ BOOST_TEST_EQ(IS_SORTED_UNTIL(b.begin(), b.end()), b.end());
+ BOOST_TEST_EQ(IS_SORTED_UNTIL(b.begin(), b.end(), lt), b.end());
+ BOOST_TEST_EQ(IS_SORTED_UNTIL(b.begin(), b.end(), lte), &b[2]);
+ BOOST_TEST_EQ(IS_SORTED_UNTIL(b.rbegin(), b.rend(), gt).base(), b.rend().base());
+ BOOST_TEST_EQ(IS_SORTED_UNTIL(b.rbegin(), b.rend(), gte).base(), &b[2]);
+
+ BOOST_TEST_EQ(IS_SORTED(b.begin(), b.end()), true);
+ BOOST_TEST_EQ(IS_SORTED(b.begin(), b.end(), lt), true);
+ BOOST_TEST_EQ(IS_SORTED(b.begin(), b.end(), lte), false);
+ BOOST_TEST_EQ(IS_SORTED(b.rbegin(), b.rend(), gt), true);
+ BOOST_TEST_EQ(IS_SORTED(b.rbegin(), b.rend(), gte), false);
+
+ BOOST_TEST_EQ(IS_SORTED_UNTIL(c.begin(), c.end()), &c[2]);
+ BOOST_TEST_EQ(IS_SORTED_UNTIL(c.begin(), c.end(), lt), &c[2]);
+ BOOST_TEST_EQ(IS_SORTED_UNTIL(c.begin(), c.end(), lte), &c[2]);
+ BOOST_TEST_EQ(IS_SORTED_UNTIL(c.rbegin(), c.rend(), gt).base(), &c[8]);
+ BOOST_TEST_EQ(IS_SORTED_UNTIL(c.rbegin(), c.rend(), gte).base(), &c[8]);
+
+ BOOST_TEST_EQ(IS_SORTED(c.begin(), c.end()), false);
+ BOOST_TEST_EQ(IS_SORTED(c.begin(), c.end(), lt), false);
+ BOOST_TEST_EQ(IS_SORTED(c.begin(), c.end(), lte), false);
+ BOOST_TEST_EQ(IS_SORTED(c.rbegin(), c.rend(), gt), false);
+ BOOST_TEST_EQ(IS_SORTED(c.rbegin(), c.rend(), gte), false);
+
+ return report_errors();
+}
diff --git a/src/boost/libs/detail/test/is_xxx_test.cpp b/src/boost/libs/detail/test/is_xxx_test.cpp
new file mode 100644
index 00000000..2f2959c4
--- /dev/null
+++ b/src/boost/libs/detail/test/is_xxx_test.cpp
@@ -0,0 +1,23 @@
+
+// Copyright 2018 Daniel James.
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/detail/is_xxx.hpp>
+#include <boost/static_assert.hpp>
+
+namespace is_xxx_test {
+ template <typename T> struct thing1 {};
+ template <typename T1, typename T2 = int> struct thing2 {};
+}
+
+BOOST_DETAIL_IS_XXX_DEF(thing1, is_xxx_test::thing1, 1);
+BOOST_DETAIL_IS_XXX_DEF(thing2, is_xxx_test::thing2, 2);
+
+BOOST_STATIC_ASSERT((is_thing1<is_xxx_test::thing1<int> >::value));
+BOOST_STATIC_ASSERT((!is_thing1<is_xxx_test::thing2<int> >::value));
+BOOST_STATIC_ASSERT((!is_thing2<is_xxx_test::thing1<int> >::value));
+BOOST_STATIC_ASSERT((is_thing2<is_xxx_test::thing2<int> >::value));
+BOOST_STATIC_ASSERT((is_thing2<is_xxx_test::thing2<int, float> >::value));
+
+int main() {}
diff --git a/src/boost/libs/detail/test/numeric_traits_test.cpp b/src/boost/libs/detail/test/numeric_traits_test.cpp
new file mode 100644
index 00000000..c22cc6f3
--- /dev/null
+++ b/src/boost/libs/detail/test/numeric_traits_test.cpp
@@ -0,0 +1,416 @@
+// (C) Copyright David Abrahams 2001.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for most recent version including documentation.
+
+// Revision History
+// 1 Apr 2001 Fixes for ICL; use BOOST_STATIC_CONSTANT
+// 11 Feb 2001 Fixes for Borland (David Abrahams)
+// 23 Jan 2001 Added test for wchar_t (David Abrahams)
+// 23 Jan 2001 Now statically selecting a test for signed numbers to avoid
+// warnings with fancy compilers. Added commentary and
+// additional dumping of traits data for tested types (David
+// Abrahams).
+// 21 Jan 2001 Initial version (David Abrahams)
+
+#include <boost/detail/numeric_traits.hpp>
+#include <cassert>
+#include <boost/type_traits/conditional.hpp>
+#include <boost/type_traits/is_signed.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/cstdint.hpp>
+#include <climits>
+#include <typeinfo>
+#include <iostream>
+#include <sstream>
+#include <string>
+#ifndef BOOST_NO_LIMITS
+#include <limits>
+#endif
+
+// =================================================================================
+// template class complement_traits<Number> --
+//
+// statically computes the max and min for 1s and 2s-complement binary
+// numbers. This helps on platforms without <limits> support. It also shows
+// an example of a recursive template that works with MSVC!
+//
+
+template <unsigned size> struct complement; // forward
+
+// The template complement, below, does all the real work, using "poor man's
+// partial specialization". We need complement_traits_aux<> so that MSVC doesn't
+// complain about undefined min/max as we're trying to recursively define them.
+template <class Number, unsigned size>
+struct complement_traits_aux
+{
+ BOOST_STATIC_CONSTANT(Number, max = complement<size>::template traits<Number>::max);
+ BOOST_STATIC_CONSTANT(Number, min = complement<size>::template traits<Number>::min);
+};
+
+template <unsigned size>
+struct complement
+{
+ template <class Number>
+ struct traits
+ {
+ private:
+ // indirection through complement_traits_aux necessary to keep MSVC happy
+ typedef complement_traits_aux<Number, size - 1> prev;
+ public:
+#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 2
+ // GCC 4.0.2 ICEs on these C-style casts
+ BOOST_STATIC_CONSTANT(Number, max =
+ Number((prev::max) << CHAR_BIT)
+ + Number(UCHAR_MAX));
+ BOOST_STATIC_CONSTANT(Number, min = Number((prev::min) << CHAR_BIT));
+#else
+ // Avoid left shifting negative integers, use multiplication instead
+ BOOST_STATIC_CONSTANT(Number, shift = 1u << CHAR_BIT);
+ BOOST_STATIC_CONSTANT(Number, max =
+ Number(Number(prev::max) * shift)
+ + Number(UCHAR_MAX));
+ BOOST_STATIC_CONSTANT(Number, min = Number(Number(prev::min) * shift));
+#endif
+ };
+};
+
+// Template class complement_base<> -- defines values for min and max for
+// complement<1>, at the deepest level of recursion. Uses "poor man's partial
+// specialization" again.
+template <bool is_signed> struct complement_base;
+
+template <> struct complement_base<false>
+{
+ template <class Number>
+ struct values
+ {
+ BOOST_STATIC_CONSTANT(Number, min = 0);
+ BOOST_STATIC_CONSTANT(Number, max = UCHAR_MAX);
+ };
+};
+
+template <> struct complement_base<true>
+{
+ template <class Number>
+ struct values
+ {
+ BOOST_STATIC_CONSTANT(Number, min = SCHAR_MIN);
+ BOOST_STATIC_CONSTANT(Number, max = SCHAR_MAX);
+ };
+};
+
+// Base specialization of complement, puts an end to the recursion.
+template <>
+struct complement<1>
+{
+ template <class Number>
+ struct traits
+ {
+ BOOST_STATIC_CONSTANT(bool, is_signed = boost::is_signed<Number>::value);
+ BOOST_STATIC_CONSTANT(Number, min =
+ complement_base<is_signed>::template values<Number>::min);
+ BOOST_STATIC_CONSTANT(Number, max =
+ complement_base<is_signed>::template values<Number>::max);
+ };
+};
+
+// Now here's the "pretty" template you're intended to actually use.
+// complement_traits<Number>::min, complement_traits<Number>::max are the
+// minimum and maximum values of Number if Number is a built-in integer type.
+template <class Number>
+struct complement_traits
+{
+ BOOST_STATIC_CONSTANT(Number, max = (complement_traits_aux<Number, sizeof(Number)>::max));
+ BOOST_STATIC_CONSTANT(Number, min = (complement_traits_aux<Number, sizeof(Number)>::min));
+};
+
+// =================================================================================
+
+// Support for streaming various numeric types in exactly the format I want. I
+// needed this in addition to all the assertions so that I could see exactly
+// what was going on.
+//
+// Numbers go through a 2-stage conversion process (by default, though, no real
+// conversion).
+//
+template <class T> struct stream_as {
+ typedef T t1;
+ typedef T t2;
+};
+
+// char types first get converted to unsigned char, then to unsigned.
+template <> struct stream_as<char> {
+ typedef unsigned char t1;
+ typedef unsigned t2;
+};
+template <> struct stream_as<unsigned char> {
+ typedef unsigned char t1; typedef unsigned t2;
+};
+template <> struct stream_as<signed char> {
+ typedef unsigned char t1; typedef unsigned t2;
+};
+
+#if defined(BOOST_MSVC_STD_ITERATOR) // No intmax streaming built-in
+
+// With this library implementation, __int64 and __uint64 get streamed as strings
+template <> struct stream_as<boost::uintmax_t> {
+ typedef std::string t1;
+ typedef std::string t2;
+};
+
+template <> struct stream_as<boost::intmax_t> {
+ typedef std::string t1;
+ typedef std::string t2;
+};
+#endif
+
+// Standard promotion process for streaming
+template <class T> struct promote
+{
+ static typename stream_as<T>::t1 from(T x) {
+ typedef typename stream_as<T>::t1 t1;
+ return t1(x);
+ }
+};
+
+#if defined(BOOST_MSVC_STD_ITERATOR) // No intmax streaming built-in
+
+// On this platform, stream them as long/unsigned long if they fit.
+// Otherwise, write a string.
+template <> struct promote<boost::uintmax_t> {
+ std::string static from(const boost::uintmax_t x) {
+ if (x > ULONG_MAX)
+ return std::string("large unsigned value");
+ else {
+ std::ostringstream strm;
+ strm << (unsigned long)x;
+ return strm.str();
+ }
+ }
+};
+template <> struct promote<boost::intmax_t> {
+ std::string static from(const boost::intmax_t x) {
+ if (x > boost::intmax_t(ULONG_MAX))
+ return std::string("large positive signed value");
+ else if (x >= 0) {
+ std::ostringstream strm;
+ strm << (unsigned long)x;
+ return strm.str();
+ }
+
+ if (x < boost::intmax_t(LONG_MIN))
+ return std::string("large negative signed value");
+ else {
+ std::ostringstream strm;
+ strm << (long)x;
+ return strm.str();
+ }
+ }
+};
+#endif
+
+// This is the function which converts types to the form I want to stream them in.
+template <class T>
+typename stream_as<T>::t2 stream_number(T x)
+{
+ return promote<T>::from(x);
+}
+// =================================================================================
+
+//
+// Tests for built-in signed and unsigned types
+//
+
+// Tag types for selecting tests
+struct unsigned_tag {};
+struct signed_tag {};
+
+// Tests for unsigned numbers. The extra default Number parameter works around
+// an MSVC bug.
+template <class Number>
+void test_aux(unsigned_tag, Number*)
+{
+ typedef typename boost::detail::numeric_traits<Number>::difference_type difference_type;
+ BOOST_STATIC_ASSERT(!boost::is_signed<Number>::value);
+ BOOST_STATIC_ASSERT(
+ (sizeof(Number) < sizeof(boost::intmax_t))
+ | (boost::is_same<difference_type, boost::intmax_t>::value));
+
+#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 2
+ // GCC 4.0.2 ICEs on this C-style cases
+ BOOST_STATIC_ASSERT((complement_traits<Number>::max) > Number(0));
+ BOOST_STATIC_ASSERT((complement_traits<Number>::min) == Number(0));
+#else
+ // Force casting to Number here to work around the fact that it's an enum on MSVC
+ BOOST_STATIC_ASSERT(Number(complement_traits<Number>::max) > Number(0));
+ BOOST_STATIC_ASSERT(Number(complement_traits<Number>::min) == Number(0));
+#endif
+
+ const Number max = complement_traits<Number>::max;
+ const Number min = complement_traits<Number>::min;
+
+ const Number test_max = (sizeof(Number) < sizeof(boost::intmax_t))
+ ? max
+ : max / 2 - 1;
+
+ std::cout << std::hex << "(unsigned) min = " << stream_number(min) << ", max = "
+ << stream_number(max) << "..." << std::flush;
+ std::cout << "difference_type = " << typeid(difference_type).name() << "..."
+ << std::flush;
+
+ difference_type d1 = boost::detail::numeric_distance(Number(0), test_max);
+ difference_type d2 = boost::detail::numeric_distance(test_max, Number(0));
+
+ std::cout << "0->" << stream_number(test_max) << "==" << std::dec << stream_number(d1) << "; "
+ << std::hex << stream_number(test_max) << "->0==" << std::dec << stream_number(d2) << "..." << std::flush;
+
+ assert(d1 == difference_type(test_max));
+ assert(d2 == -difference_type(test_max));
+}
+
+// Tests for signed numbers. The extra default Number parameter works around an
+// MSVC bug.
+struct out_of_range_tag {};
+struct in_range_tag {};
+
+// This test morsel gets executed for numbers whose difference will always be
+// representable in intmax_t
+template <class Number>
+void signed_test(in_range_tag, Number*)
+{
+ BOOST_STATIC_ASSERT(boost::is_signed<Number>::value);
+ typedef typename boost::detail::numeric_traits<Number>::difference_type difference_type;
+ const Number max = complement_traits<Number>::max;
+ const Number min = complement_traits<Number>::min;
+
+ difference_type d1 = boost::detail::numeric_distance(min, max);
+ difference_type d2 = boost::detail::numeric_distance(max, min);
+
+ std::cout << stream_number(min) << "->" << stream_number(max) << "==";
+ std::cout << std::dec << stream_number(d1) << "; ";
+ std::cout << std::hex << stream_number(max) << "->" << stream_number(min)
+ << "==" << std::dec << stream_number(d2) << "..." << std::flush;
+ assert(d1 == difference_type(max) - difference_type(min));
+ assert(d2 == difference_type(min) - difference_type(max));
+}
+
+// This test morsel gets executed for numbers whose difference may exceed the
+// capacity of intmax_t.
+template <class Number>
+void signed_test(out_of_range_tag, Number*)
+{
+ BOOST_STATIC_ASSERT(boost::is_signed<Number>::value);
+ typedef typename boost::detail::numeric_traits<Number>::difference_type difference_type;
+ const Number max = complement_traits<Number>::max;
+ const Number min = complement_traits<Number>::min;
+
+ difference_type min_distance = complement_traits<difference_type>::min;
+ difference_type max_distance = complement_traits<difference_type>::max;
+
+ const Number n1 = Number(min + max_distance);
+ const Number n2 = Number(max + min_distance);
+ difference_type d1 = boost::detail::numeric_distance(min, n1);
+ difference_type d2 = boost::detail::numeric_distance(max, n2);
+
+ std::cout << stream_number(min) << "->" << stream_number(n1) << "==";
+ std::cout << std::dec << stream_number(d1) << "; ";
+ std::cout << std::hex << stream_number(max) << "->" << stream_number(n2)
+ << "==" << std::dec << stream_number(d2) << "..." << std::flush;
+ assert(d1 == max_distance);
+ assert(d2 == min_distance);
+}
+
+template <class Number>
+void test_aux(signed_tag, Number*)
+{
+ typedef typename boost::detail::numeric_traits<Number>::difference_type difference_type;
+ BOOST_STATIC_ASSERT(boost::is_signed<Number>::value);
+ BOOST_STATIC_ASSERT(
+ (sizeof(Number) < sizeof(boost::intmax_t))
+ | (boost::is_same<difference_type, Number>::value));
+
+#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 2
+ // GCC 4.0.2 ICEs on this cast
+ BOOST_STATIC_ASSERT((complement_traits<Number>::max) > Number(0));
+ BOOST_STATIC_ASSERT((complement_traits<Number>::min) < Number(0));
+#else
+ // Force casting to Number here to work around the fact that it's an enum on MSVC
+ BOOST_STATIC_ASSERT(Number(complement_traits<Number>::max) > Number(0));
+ BOOST_STATIC_ASSERT(Number(complement_traits<Number>::min) < Number(0));
+#endif
+ const Number max = complement_traits<Number>::max;
+ const Number min = complement_traits<Number>::min;
+
+ std::cout << std::hex << "min = " << stream_number(min) << ", max = "
+ << stream_number(max) << "..." << std::flush;
+ std::cout << "difference_type = " << typeid(difference_type).name() << "..."
+ << std::flush;
+
+ typedef typename boost::conditional<
+ (sizeof(Number) < sizeof(boost::intmax_t)),
+ in_range_tag,
+ out_of_range_tag
+ >::type range_tag;
+ signed_test<Number>(range_tag(), 0);
+}
+
+
+// Test for all numbers. The extra default Number parameter works around an MSVC
+// bug.
+template <class Number>
+void test(Number* = 0)
+{
+ std::cout << "testing " << typeid(Number).name() << ":\n"
+#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
+ << "is_signed: " << (std::numeric_limits<Number>::is_signed ? "true\n" : "false\n")
+ << "is_bounded: " << (std::numeric_limits<Number>::is_bounded ? "true\n" : "false\n")
+ << "digits: " << std::numeric_limits<Number>::digits << "\n"
+#endif
+ << "..." << std::flush;
+
+ // factoring out difference_type for the assert below confused Borland :(
+ typedef boost::is_signed<
+#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
+ typename
+#endif
+ boost::detail::numeric_traits<Number>::difference_type
+ > is_signed;
+ BOOST_STATIC_ASSERT(is_signed::value);
+
+ typedef typename boost::conditional<
+ boost::is_signed<Number>::value,
+ signed_tag,
+ unsigned_tag
+ >::type signedness;
+
+ test_aux<Number>(signedness(), 0);
+ std::cout << "passed" << std::endl;
+}
+
+int main()
+{
+ test<char>();
+ test<unsigned char>();
+ test<signed char>();
+ test<wchar_t>();
+ test<short>();
+ test<unsigned short>();
+ test<int>();
+ test<unsigned int>();
+ test<long>();
+ test<unsigned long>();
+#if defined(BOOST_HAS_LONG_LONG) && !defined(BOOST_NO_INTEGRAL_INT64_T)
+ test< ::boost::long_long_type>();
+ test< ::boost::ulong_long_type>();
+#elif defined(BOOST_MSVC)
+ // The problem of not having compile-time static class constants other than
+ // enums prevents this from working, since values get truncated.
+ // test<boost::uintmax_t>();
+ // test<boost::intmax_t>();
+#endif
+ return 0;
+}
diff --git a/src/boost/libs/detail/test/reference_content_test.cpp b/src/boost/libs/detail/test/reference_content_test.cpp
new file mode 100644
index 00000000..4fb812e4
--- /dev/null
+++ b/src/boost/libs/detail/test/reference_content_test.cpp
@@ -0,0 +1,16 @@
+
+// Copyright 2018 Daniel James.
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/detail/reference_content.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+BOOST_STATIC_ASSERT((boost::is_same<int, boost::detail::make_reference_content<int>::type>::value));
+BOOST_STATIC_ASSERT((boost::is_same<boost::detail::reference_content<int&>, boost::detail::make_reference_content<int&>::type>::value));
+BOOST_STATIC_ASSERT((boost::is_same<int, boost::detail::make_reference_content<>::apply<int>::type>::value));
+BOOST_STATIC_ASSERT((boost::is_same<boost::detail::reference_content<int&>, boost::detail::make_reference_content<>::apply<int&>::type>::value));
+BOOST_STATIC_ASSERT((boost::has_nothrow_copy<boost::detail::make_reference_content<int&>::type>::value));
+
+int main() {}
diff --git a/src/boost/libs/detail/test/test_utf8_codecvt.cpp b/src/boost/libs/detail/test/test_utf8_codecvt.cpp
new file mode 100644
index 00000000..f92706c6
--- /dev/null
+++ b/src/boost/libs/detail/test/test_utf8_codecvt.cpp
@@ -0,0 +1,302 @@
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+// test_utf8_codecvt.cpp
+
+// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <algorithm> // std::copy
+#include <fstream>
+#include <iostream>
+#include <iterator>
+#include <locale>
+#include <vector>
+#include <string>
+
+#include <cstddef> // size_t
+#include <cwchar>
+#include <boost/config.hpp>
+#include <boost/core/no_exceptions_support.hpp>
+
+#define BOOST_UTF8_BEGIN_NAMESPACE namespace boost { namespace detail {
+#define BOOST_UTF8_END_NAMESPACE } }
+#include <boost/detail/utf8_codecvt_facet.hpp>
+#include <boost/detail/utf8_codecvt_facet.ipp>
+
+#if defined(BOOST_NO_STDC_NAMESPACE)
+namespace std{
+ using ::size_t;
+ using ::wcslen;
+#if !defined(UNDER_CE) && !defined(__PGIC__)
+ using ::w_int;
+#endif
+} // namespace std
+#endif
+
+// Note: copied from boost/iostreams/char_traits.hpp
+//
+// Dinkumware that comes with QNX Momentics 6.3.0, 4.0.2, incorrectly defines
+// the EOF and WEOF macros to not std:: qualify the wint_t type (and so does
+// Sun C++ 5.8 + STLport 4). Fix by placing the def in this scope.
+// NOTE: Use BOOST_WORKAROUND?
+#if (defined(__QNX__) && defined(BOOST_DINKUMWARE_STDLIB)) \
+ || defined(__SUNPRO_CC)
+ using ::std::wint_t;
+#endif
+
+#include <boost/core/lightweight_test.hpp>
+
+template<std::size_t s>
+struct test_data
+{
+ static unsigned char utf8_encoding[];
+ static wchar_t wchar_encoding[];
+};
+
+template<>
+unsigned char test_data<2>::utf8_encoding[] = {
+ 0x01,
+ 0x7f,
+ 0xc2, 0x80,
+ 0xdf, 0xbf,
+ 0xe0, 0xa0, 0x80,
+ 0xe7, 0xbf, 0xbf
+};
+
+template<>
+wchar_t test_data<2>::wchar_encoding[] = {
+ 0x0001,
+ 0x007f,
+ 0x0080,
+ 0x07ff,
+ 0x0800,
+ 0x7fff
+};
+
+template<>
+unsigned char test_data<4>::utf8_encoding[] = {
+ 0x01,
+ 0x7f,
+ 0xc2, 0x80,
+ 0xdf, 0xbf,
+ 0xe0, 0xa0, 0x80,
+ 0xef, 0xbf, 0xbf,
+ 0xf0, 0x90, 0x80, 0x80,
+ 0xf4, 0x8f, 0xbf, 0xbf,
+ /* codecvt implementations for clang and gcc don't handle more than 21 bits and
+ * return eof accordlingly. So don't test the whole 32 range
+ */
+ /*
+ 0xf7, 0xbf, 0xbf, 0xbf,
+ 0xf8, 0x88, 0x80, 0x80, 0x80,
+ 0xfb, 0xbf, 0xbf, 0xbf, 0xbf,
+ 0xfc, 0x84, 0x80, 0x80, 0x80, 0x80,
+ 0xfd, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf
+ */
+};
+
+template<>
+wchar_t test_data<4>::wchar_encoding[] = {
+ (wchar_t)0x00000001,
+ (wchar_t)0x0000007f,
+ (wchar_t)0x00000080,
+ (wchar_t)0x000007ff,
+ (wchar_t)0x00000800,
+ (wchar_t)0x0000ffff,
+ (wchar_t)0x00010000,
+ (wchar_t)0x0010ffff,
+ /* codecvt implementations for clang and gcc don't handle more than 21 bits and
+ * return eof accordlingly. So don't test the whole 32 range
+ */
+ /*
+ (wchar_t)0x001fffff,
+ (wchar_t)0x00200000,
+ (wchar_t)0x03ffffff,
+ (wchar_t)0x04000000,
+ (wchar_t)0x7fffffff
+ */
+};
+
+int
+test_main(int /* argc */, char * /* argv */[]) {
+ std::locale utf8_locale
+ = std::locale(
+ std::locale::classic(),
+ new boost::detail::utf8_codecvt_facet
+ );
+
+ typedef char utf8_t;
+ // define test data compatible with the wchar_t implementation
+ // as either ucs-2 or ucs-4 depending on the compiler/library.
+ typedef test_data<sizeof(wchar_t)> td;
+
+ // Send our test UTF-8 data to file
+ {
+ std::ofstream ofs;
+ ofs.open("test.dat");
+ std::copy(
+ td::utf8_encoding,
+ td::utf8_encoding + sizeof(td::utf8_encoding) / sizeof(unsigned char),
+ std::ostream_iterator<utf8_t>(ofs)
+ );
+ }
+
+ // Read the test data back in, converting to UCS-4 on the way in
+ std::vector<wchar_t> from_file;
+ {
+ std::wifstream ifs;
+ ifs.imbue(utf8_locale);
+ ifs.open("test.dat");
+
+ std::wint_t item = 0;
+ // note can't use normal vector from iterator constructor because
+ // dinkumware doesn't have it.
+ for(;;){
+ item = ifs.get();
+ if(item == WEOF)
+ break;
+ //ifs >> item;
+ //if(ifs.eof())
+ // break;
+ from_file.push_back(item);
+ }
+ }
+
+ BOOST_TEST(std::equal(from_file.begin(), from_file.end(), td::wchar_encoding));
+
+ // Send the UCS4_data back out, converting to UTF-8
+ {
+ std::wofstream ofs;
+ ofs.imbue(utf8_locale);
+ ofs.open("test2.dat");
+ std::copy(
+ from_file.begin(),
+ from_file.end(),
+ std::ostream_iterator<wchar_t, wchar_t>(ofs)
+ );
+ }
+
+ // Make sure that both files are the same
+ {
+ typedef std::istream_iterator<utf8_t> is_iter;
+ is_iter end_iter;
+
+ std::ifstream ifs1("test.dat");
+ is_iter it1(ifs1);
+ std::vector<utf8_t> data1;
+ std::copy(it1, end_iter, std::back_inserter(data1));
+
+ std::ifstream ifs2("test2.dat");
+ is_iter it2(ifs2);
+ std::vector<utf8_t> data2;
+ std::copy(it2, end_iter, std::back_inserter(data2));
+
+ BOOST_TEST(data1 == data2);
+ }
+
+ // some libraries have trouble that only shows up with longer strings
+
+ const wchar_t * test3_data = L"\
+ <?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>\
+ <!DOCTYPE boost_serialization>\
+ <boost_serialization signature=\"serialization::archive\" version=\"3\">\
+ <a class_id=\"0\" tracking_level=\"0\">\
+ <b>1</b>\
+ <f>96953204</f>\
+ <g>177129195</g>\
+ <l>1</l>\
+ <m>5627</m>\
+ <n>23010</n>\
+ <o>7419</o>\
+ <p>16212</p>\
+ <q>4086</q>\
+ <r>2749</r>\
+ <c>-33</c>\
+ <s>124</s>\
+ <t>28</t>\
+ <u>32225</u>\
+ <v>17543</v>\
+ <w>0.84431422</w>\
+ <x>1.0170664757130923</x>\
+ <y>tjbx</y>\
+ <z>cuwjentqpkejp</z>\
+ </a>\
+ </boost_serialization>\
+ ";
+
+ // Send the UCS4_data back out, converting to UTF-8
+ std::size_t l = std::wcslen(test3_data);
+ {
+ std::wofstream ofs;
+ ofs.imbue(utf8_locale);
+ ofs.open("test3.dat");
+ std::copy(
+ test3_data,
+ test3_data + l,
+ std::ostream_iterator<wchar_t, wchar_t>(ofs)
+ );
+ }
+
+ // Make sure that both files are the same
+ {
+ std::wifstream ifs;
+ ifs.imbue(utf8_locale);
+ ifs.open("test3.dat");
+ ifs >> std::noskipws;
+ BOOST_TEST(
+ std::equal(
+ test3_data,
+ test3_data + l,
+ std::istream_iterator<wchar_t, wchar_t>(ifs)
+ )
+ );
+ }
+
+ // Test length calculation
+ {
+ std::codecvt<wchar_t, char, std::mbstate_t> const& fac = std::use_facet< std::codecvt<wchar_t, char, std::mbstate_t> >(utf8_locale);
+ std::mbstate_t mbs = std::mbstate_t();
+ const int utf8_len = sizeof(td::utf8_encoding) / sizeof(*td::utf8_encoding);
+ int res = fac.length(mbs, reinterpret_cast< const char* >(td::utf8_encoding), reinterpret_cast< const char* >(td::utf8_encoding + utf8_len), ~static_cast< std::size_t >(0u));
+ BOOST_TEST_EQ(utf8_len, res);
+ }
+
+ // Test that length calculation detects character boundaries
+ {
+ std::codecvt<wchar_t, char, std::mbstate_t> const& fac = std::use_facet< std::codecvt<wchar_t, char, std::mbstate_t> >(utf8_locale);
+ std::mbstate_t mbs = std::mbstate_t();
+ // The first 5 bytes of utf8_encoding contain 3 complete UTF-8 characters (taking 4 bytes in total) and 1 byte of an incomplete character.
+ // This last byte should not be accounted by length().
+ const int input_len = 5;
+ const int utf8_len = 4;
+ int res = fac.length(mbs, reinterpret_cast< const char* >(td::utf8_encoding), reinterpret_cast< const char* >(td::utf8_encoding + input_len), ~static_cast< std::size_t >(0u));
+ BOOST_TEST_EQ(utf8_len, res);
+ }
+
+ return EXIT_SUCCESS;
+}
+
+int
+main(int argc, char * argv[]){
+
+ int retval = 1;
+ BOOST_TRY{
+ retval = test_main(argc, argv);
+ }
+ #ifndef BOOST_NO_EXCEPTION_STD_NAMESPACE
+ BOOST_CATCH(const std::exception & e){
+ BOOST_ERROR(e.what());
+ }
+ #endif
+ BOOST_CATCH(...){
+ BOOST_ERROR("failed with uncaught exception:");
+ }
+ BOOST_CATCH_END
+
+ int error_count = boost::report_errors();
+ if(error_count > 0)
+ retval = error_count;
+ return retval;
+}
+