diff options
author | Anas Nashif <anas.nashif@intel.com> | 2012-10-30 12:57:26 -0700 |
---|---|---|
committer | Anas Nashif <anas.nashif@intel.com> | 2012-10-30 12:57:26 -0700 |
commit | 1a78a62555be32868418fe52f8e330c9d0f95d5a (patch) | |
tree | d3765a80e7d3b9640ec2e930743630cd6b9fce2b /libs/detail | |
download | boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.gz boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.bz2 boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.zip |
Imported Upstream version 1.49.0upstream/1.49.0
Diffstat (limited to 'libs/detail')
-rw-r--r-- | libs/detail/test/Jamfile | 23 | ||||
-rw-r--r-- | libs/detail/test/container_fwd/Jamfile | 29 | ||||
-rw-r--r-- | libs/detail/test/container_fwd/container_fwd_test.cpp | 112 | ||||
-rw-r--r-- | libs/detail/test/container_fwd/container_no_fwd_test.cpp | 14 | ||||
-rw-r--r-- | libs/detail/test/container_fwd/correctly_disable_fail.cpp | 43 | ||||
-rw-r--r-- | libs/detail/test/is_sorted_test.cpp | 130 | ||||
-rw-r--r-- | libs/detail/utf8_codecvt_facet.cpp | 285 |
7 files changed, 636 insertions, 0 deletions
diff --git a/libs/detail/test/Jamfile b/libs/detail/test/Jamfile new file mode 100644 index 0000000000..59c0a8d55e --- /dev/null +++ b/libs/detail/test/Jamfile @@ -0,0 +1,23 @@ +################################################################*# 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>darwin:<cxxflags>-ftemplate-depth-300 + ; + +for tests in [ glob *.cpp ] { + run $(tests) : : : : $(tests:B) ; +} + + diff --git a/libs/detail/test/container_fwd/Jamfile b/libs/detail/test/container_fwd/Jamfile new file mode 100644 index 0000000000..ab55bc2b75 --- /dev/null +++ b/libs/detail/test/container_fwd/Jamfile @@ -0,0 +1,29 @@ + +# 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 ; + +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 ; diff --git a/libs/detail/test/container_fwd/container_fwd_test.cpp b/libs/detail/test/container_fwd/container_fwd_test.cpp new file mode 100644 index 0000000000..55c2e04a95 --- /dev/null +++ b/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/functional/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/libs/detail/test/container_fwd/container_no_fwd_test.cpp b/libs/detail/test/container_fwd/container_no_fwd_test.cpp new file mode 100644 index 0000000000..9da09da164 --- /dev/null +++ b/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/libs/detail/test/container_fwd/correctly_disable_fail.cpp b/libs/detail/test/container_fwd/correctly_disable_fail.cpp new file mode 100644 index 0000000000..2301686298 --- /dev/null +++ b/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/libs/detail/test/is_sorted_test.cpp b/libs/detail/test/is_sorted_test.cpp new file mode 100644 index 0000000000..036c10a0a2 --- /dev/null +++ b/libs/detail/test/is_sorted_test.cpp @@ -0,0 +1,130 @@ +/*============================================================================== + 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 <ios> +#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: std::binary_function <T, T, bool> { + typedef bool result_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: std::binary_function <T, T, bool> { + typedef bool result_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: std::binary_function <T, T, bool> { + typedef bool result_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: std::binary_function <T, T, bool> { + typedef bool result_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), *a.rend()); + BOOST_TEST_EQ(*IS_SORTED_UNTIL(a.rbegin(), a.rend(), gte), *a.rend()); + + 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), *b.rend()); + BOOST_TEST_EQ(*IS_SORTED_UNTIL(b.rbegin(), b.rend(), gte), 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), c[7]); + BOOST_TEST_EQ(*IS_SORTED_UNTIL(c.rbegin(), c.rend(), gte), c[7]); + + 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/libs/detail/utf8_codecvt_facet.cpp b/libs/detail/utf8_codecvt_facet.cpp new file mode 100644 index 0000000000..7ea5eebbf0 --- /dev/null +++ b/libs/detail/utf8_codecvt_facet.cpp @@ -0,0 +1,285 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// utf8_codecvt_facet.cpp + +// Copyright (c) 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu) +// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu). +// 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) + +// Please see the comments in <boost/detail/utf8_codecvt_facet.hpp> to +// learn how this file should be used. + +#include <boost/detail/utf8_codecvt_facet.hpp> + +#include <cstdlib> // for multi-byte converson routines +#include <cassert> + +#include <boost/limits.hpp> +#include <boost/config.hpp> + +// If we don't have wstring, then Unicode support +// is not available anyway, so we don't need to even +// compiler this file. This also fixes the problem +// with mingw, which can compile this file, but will +// generate link error when building DLL. +#ifndef BOOST_NO_STD_WSTRING + +BOOST_UTF8_BEGIN_NAMESPACE + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implementation for wchar_t + +// Translate incoming UTF-8 into UCS-4 +std::codecvt_base::result utf8_codecvt_facet::do_in( + std::mbstate_t& /*state*/, + const char * from, + const char * from_end, + const char * & from_next, + wchar_t * to, + wchar_t * to_end, + wchar_t * & to_next +) const { + // Basic algorithm: The first octet determines how many + // octets total make up the UCS-4 character. The remaining + // "continuing octets" all begin with "10". To convert, subtract + // the amount that specifies the number of octets from the first + // octet. Subtract 0x80 (1000 0000) from each continuing octet, + // then mash the whole lot together. Note that each continuing + // octet only uses 6 bits as unique values, so only shift by + // multiples of 6 to combine. + while (from != from_end && to != to_end) { + + // Error checking on the first octet + if (invalid_leading_octet(*from)){ + from_next = from; + to_next = to; + return std::codecvt_base::error; + } + + // The first octet is adjusted by a value dependent upon + // the number of "continuing octets" encoding the character + const int cont_octet_count = get_cont_octet_count(*from); + const wchar_t octet1_modifier_table[] = { + 0x00, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc + }; + + // The unsigned char conversion is necessary in case char is + // signed (I learned this the hard way) + wchar_t ucs_result = + (unsigned char)(*from++) - octet1_modifier_table[cont_octet_count]; + + // Invariants : + // 1) At the start of the loop, 'i' continuing characters have been + // processed + // 2) *from points to the next continuing character to be processed. + int i = 0; + while(i != cont_octet_count && from != from_end) { + + // Error checking on continuing characters + if (invalid_continuing_octet(*from)) { + from_next = from; + to_next = to; + return std::codecvt_base::error; + } + + ucs_result *= (1 << 6); + + // each continuing character has an extra (10xxxxxx)b attached to + // it that must be removed. + ucs_result += (unsigned char)(*from++) - 0x80; + ++i; + } + + // If the buffer ends with an incomplete unicode character... + if (from == from_end && i != cont_octet_count) { + // rewind "from" to before the current character translation + from_next = from - (i+1); + to_next = to; + return std::codecvt_base::partial; + } + *to++ = ucs_result; + } + from_next = from; + to_next = to; + + // Were we done converting or did we run out of destination space? + if(from == from_end) return std::codecvt_base::ok; + else return std::codecvt_base::partial; +} + +std::codecvt_base::result utf8_codecvt_facet::do_out( + std::mbstate_t& /*state*/, + const wchar_t * from, + const wchar_t * from_end, + const wchar_t * & from_next, + char * to, + char * to_end, + char * & to_next +) const +{ + // RG - consider merging this table with the other one + const wchar_t octet1_modifier_table[] = { + 0x00, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc + }; + + wchar_t max_wchar = (std::numeric_limits<wchar_t>::max)(); + while (from != from_end && to != to_end) { + + // Check for invalid UCS-4 character + if (*from > max_wchar) { + from_next = from; + to_next = to; + return std::codecvt_base::error; + } + + int cont_octet_count = get_cont_octet_out_count(*from); + + // RG - comment this formula better + int shift_exponent = (cont_octet_count) * 6; + + // Process the first character + *to++ = static_cast<char>(octet1_modifier_table[cont_octet_count] + + (unsigned char)(*from / (1 << shift_exponent))); + + // Process the continuation characters + // Invariants: At the start of the loop: + // 1) 'i' continuing octets have been generated + // 2) '*to' points to the next location to place an octet + // 3) shift_exponent is 6 more than needed for the next octet + int i = 0; + while (i != cont_octet_count && to != to_end) { + shift_exponent -= 6; + *to++ = static_cast<char>(0x80 + ((*from / (1 << shift_exponent)) % (1 << 6))); + ++i; + } + // If we filled up the out buffer before encoding the character + if(to == to_end && i != cont_octet_count) { + from_next = from; + to_next = to - (i+1); + return std::codecvt_base::partial; + } + ++from; + } + from_next = from; + to_next = to; + // Were we done or did we run out of destination space + if(from == from_end) return std::codecvt_base::ok; + else return std::codecvt_base::partial; +} + +// How many char objects can I process to get <= max_limit +// wchar_t objects? +int utf8_codecvt_facet::do_length( + BOOST_CODECVT_DO_LENGTH_CONST std::mbstate_t &, + const char * from, + const char * from_end, + std::size_t max_limit +#if BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) +) const throw() +#else +) const +#endif +{ + // RG - this code is confusing! I need a better way to express it. + // and test cases. + + // Invariants: + // 1) last_octet_count has the size of the last measured character + // 2) char_count holds the number of characters shown to fit + // within the bounds so far (no greater than max_limit) + // 3) from_next points to the octet 'last_octet_count' before the + // last measured character. + int last_octet_count=0; + std::size_t char_count = 0; + const char* from_next = from; + // Use "<" because the buffer may represent incomplete characters + while (from_next+last_octet_count <= from_end && char_count <= max_limit) { + from_next += last_octet_count; + last_octet_count = (get_octet_count(*from_next)); + ++char_count; + } + return static_cast<int>(from_next-from_end); +} + +unsigned int utf8_codecvt_facet::get_octet_count( + unsigned char lead_octet +){ + // if the 0-bit (MSB) is 0, then 1 character + if (lead_octet <= 0x7f) return 1; + + // Otherwise the count number of consecutive 1 bits starting at MSB +// assert(0xc0 <= lead_octet && lead_octet <= 0xfd); + + if (0xc0 <= lead_octet && lead_octet <= 0xdf) return 2; + else if (0xe0 <= lead_octet && lead_octet <= 0xef) return 3; + else if (0xf0 <= lead_octet && lead_octet <= 0xf7) return 4; + else if (0xf8 <= lead_octet && lead_octet <= 0xfb) return 5; + else return 6; +} +BOOST_UTF8_END_NAMESPACE + +namespace { +template<std::size_t s> +int get_cont_octet_out_count_impl(wchar_t word){ + if (word < 0x80) { + return 0; + } + if (word < 0x800) { + return 1; + } + return 2; +} + +template<> +int get_cont_octet_out_count_impl<4>(wchar_t word){ + if (word < 0x80) { + return 0; + } + if (word < 0x800) { + return 1; + } + + // Note that the following code will generate warnings on some platforms + // where wchar_t is defined as UCS2. The warnings are superfluous as the + // specialization is never instantitiated with such compilers, but this + // can cause problems if warnings are being treated as errors, so we guard + // against that. Including <boost/detail/utf8_codecvt_facet.hpp> as we do + // should be enough to get WCHAR_MAX defined. +#if !defined(WCHAR_MAX) +# error WCHAR_MAX not defined! +#endif + // cope with VC++ 7.1 or earlier having invalid WCHAR_MAX +#if defined(_MSC_VER) && _MSC_VER <= 1310 // 7.1 or earlier + return 2; +#elif WCHAR_MAX > 0x10000 + + if (word < 0x10000) { + return 2; + } + if (word < 0x200000) { + return 3; + } + if (word < 0x4000000) { + return 4; + } + return 5; + +#else + return 2; +#endif +} + +} // namespace anonymous + +BOOST_UTF8_BEGIN_NAMESPACE +// How many "continuing octets" will be needed for this word +// == total octets - 1. +int utf8_codecvt_facet::get_cont_octet_out_count( + wchar_t word +) const { + return get_cont_octet_out_count_impl<sizeof(wchar_t)>(word); +} +BOOST_UTF8_END_NAMESPACE + +#endif |