diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
commit | 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch) | |
tree | e5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/boost/libs/detail | |
parent | Initial commit. (diff) | |
download | ceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.tar.xz ceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.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')
-rw-r--r-- | src/boost/libs/detail/CMakeLists.txt | 25 | ||||
-rw-r--r-- | src/boost/libs/detail/index.html | 14 | ||||
-rw-r--r-- | src/boost/libs/detail/meta/libraries.json | 27 | ||||
-rw-r--r-- | src/boost/libs/detail/test/Jamfile | 32 | ||||
-rw-r--r-- | src/boost/libs/detail/test/allocator_utilities_test.cpp | 40 | ||||
-rw-r--r-- | src/boost/libs/detail/test/binary_search_test.cpp | 260 | ||||
-rw-r--r-- | src/boost/libs/detail/test/blank_test.cpp | 32 | ||||
-rw-r--r-- | src/boost/libs/detail/test/container_fwd/Jamfile | 39 | ||||
-rw-r--r-- | src/boost/libs/detail/test/container_fwd/container_fwd_test.cpp | 112 | ||||
-rw-r--r-- | src/boost/libs/detail/test/container_fwd/container_no_fwd_test.cpp | 14 | ||||
-rw-r--r-- | src/boost/libs/detail/test/container_fwd/correctly_disable_fail.cpp | 43 | ||||
-rw-r--r-- | src/boost/libs/detail/test/is_sorted_test.cpp | 137 | ||||
-rw-r--r-- | src/boost/libs/detail/test/is_xxx_test.cpp | 23 | ||||
-rw-r--r-- | src/boost/libs/detail/test/numeric_traits_test.cpp | 416 | ||||
-rw-r--r-- | src/boost/libs/detail/test/reference_content_test.cpp | 16 | ||||
-rw-r--r-- | src/boost/libs/detail/test/test_utf8_codecvt.cpp | 302 |
16 files changed, 1532 insertions, 0 deletions
diff --git a/src/boost/libs/detail/CMakeLists.txt b/src/boost/libs/detail/CMakeLists.txt new file mode 100644 index 00000000..3e122d42 --- /dev/null +++ b/src/boost/libs/detail/CMakeLists.txt @@ -0,0 +1,25 @@ +# Copyright 2018 Peter Dimov +# Copyright 2018 Andrey Semashev +# Distributed under the Boost Software License, Version 1.0. +# See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt + +# Partial (add_subdirectory only) and experimental CMake support +# Subject to change; please do not rely on the contents of this file yet. + +cmake_minimum_required(VERSION 3.5) + +project(BoostDetail LANGUAGES CXX) + +add_library(boost_detail INTERFACE) +add_library(Boost::detail ALIAS boost_detail) + +target_include_directories(boost_detail INTERFACE include) + +target_link_libraries(boost_detail + INTERFACE + Boost::config + Boost::core + Boost::preprocessor + Boost::static_assert + Boost::type_traits +) diff --git a/src/boost/libs/detail/index.html b/src/boost/libs/detail/index.html new file mode 100644 index 00000000..e888798a --- /dev/null +++ b/src/boost/libs/detail/index.html @@ -0,0 +1,14 @@ +<!-- +Copyright 2016 Rene Rivera +Distributed under the Boost Software License, Version 1.0. (See the accompanying +file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt) +--> +<html> +<head> +<meta http-equiv="refresh" content="0; URL=./doc/html/index.html"> +</head> +<body> +<p>Automatic redirection failed, please go to +<a href="./doc/html/index.html">./doc/html/index.html</a>.</p> +</body> +</html> diff --git a/src/boost/libs/detail/meta/libraries.json b/src/boost/libs/detail/meta/libraries.json new file mode 100644 index 00000000..5c1aa004 --- /dev/null +++ b/src/boost/libs/detail/meta/libraries.json @@ -0,0 +1,27 @@ +{ + "key": "detail", + "name": "Detail", + "status": "hidden", + "authors": [ + "David Abrahams", + "Beman Dawes", + "Eric Friedman", + "Ronald Garcia", + "Howard Hinnant", + "Daniel James", + "Bryce Lelbach", + "Joaquin M Lopez Munoz", + "Jeremy Siek", + "Matthias Troyerk" + ], + "description": "This library contains a set of header only utilities used internally by Boost C++ Libraries to facilitate their implementation.", + "category": [ + "Miscellaneous" + ], + "maintainers": [ + "Beman Dawes <bdawes -at- acm.org>", + "Robert Ramey <ramey -at- rrsd.com>", + "Rene Rivera <grafikrobot -at- gmail.com>", + "Andrey Semashev <andrey.semashev -at- gmail.com>" + ] +} 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; +} + |