summaryrefslogtreecommitdiff
path: root/libs/detail
diff options
context:
space:
mode:
authorAnas Nashif <anas.nashif@intel.com>2012-10-30 12:57:26 -0700
committerAnas Nashif <anas.nashif@intel.com>2012-10-30 12:57:26 -0700
commit1a78a62555be32868418fe52f8e330c9d0f95d5a (patch)
treed3765a80e7d3b9640ec2e930743630cd6b9fce2b /libs/detail
downloadboost-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/Jamfile23
-rw-r--r--libs/detail/test/container_fwd/Jamfile29
-rw-r--r--libs/detail/test/container_fwd/container_fwd_test.cpp112
-rw-r--r--libs/detail/test/container_fwd/container_no_fwd_test.cpp14
-rw-r--r--libs/detail/test/container_fwd/correctly_disable_fail.cpp43
-rw-r--r--libs/detail/test/is_sorted_test.cpp130
-rw-r--r--libs/detail/utf8_codecvt_facet.cpp285
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