diff --git a/hash/doc/changes.qbk b/hash/doc/changes.qbk
index 8918e0e..5ee6cb6 100644
--- a/hash/doc/changes.qbk
+++ b/hash/doc/changes.qbk
@@ -189,6 +189,10 @@
[h2 Boost 1.64.0]
* Fix for recent versions of Visual C++ which have removed `std::unary_function`
- and `std::binary_function`.
+ and `std::binary_function` ([ticket 12353]).
+
+[h2 Boost 1.65.0]
+
+* Support for `char16_t`, `char32_t`, `u16string`, `u32string`
[endsect]
diff --git a/hash/doc/ref.xml b/hash/doc/ref.xml
index 5fcd43b..f5fd185 100644
--- a/hash/doc/ref.xml
+++ b/hash/doc/ref.xml
@@ -162,6 +162,42 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+
+
+ char16_t
+
+
+ std::size_t
+
+ char16_t
+
+
+ Unspecified in TR1, except that equal arguments yield the same result.
+ hash_value(val) in Boost.
+
+ Doesn't throw
+
+
+
+
+
+
+ char32_t
+
+
+ std::size_t
+
+ char32_t
+
+
+ Unspecified in TR1, except that equal arguments yield the same result.
+ hash_value(val) in Boost.
+
+ Doesn't throw
+
+
+
@@ -396,6 +432,42 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+
+
+ std::u16string
+
+
+ std::size_t
+
+ std::u16string const&
+
+
+ Unspecified in TR1, except that equal arguments yield the same result.
+ hash_value(val) in Boost.
+
+ Doesn't throw
+
+
+
+
+
+
+ std::u32string
+
+
+ std::size_t
+
+ std::u32string const&
+
+
+ Unspecified in TR1, except that equal arguments yield the same result.
+ hash_value(val) in Boost.
+
+ Doesn't throw
+
+
+
@@ -597,6 +669,16 @@ for(; first != last; ++first)
wchar_t
+
+ std::size_t
+ char16_t
+
+
+
+ std::size_t
+ char32_t
+
+
std::size_t
short
@@ -833,7 +915,8 @@ for(; first != last; ++first)
bool
,
- char
, signed char
, unsigned char
, wchar_t
,
+ char
, signed char
, unsigned char
,
+ wchar_t
, char16_t
, char32_t
,
short
, unsigned short
,
int
, unsigned int
, long
, unsigned long
diff --git a/hash/test/hash_number_test.cpp b/hash/test/hash_number_test.cpp
index ebfe4d4..18756c3 100644
--- a/hash/test/hash_number_test.cpp
+++ b/hash/test/hash_number_test.cpp
@@ -164,6 +164,12 @@ int main()
NUMERIC_TEST(unsigned char, uchar)
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
NUMERIC_TEST(wchar_t, wchar)
+#endif
+#ifndef BOOST_NO_CXX11_CHAR16_T
+ NUMERIC_TEST(char16_t, char16)
+#endif
+#ifndef BOOST_NO_CXX11_CHAR32_T
+ NUMERIC_TEST(char32_t, char32)
#endif
NUMERIC_TEST(short, short)
NUMERIC_TEST(unsigned short, ushort)
diff --git a/hash/test/hash_string_test.cpp b/hash/test/hash_string_test.cpp
index 3c83007..7088d67 100644
--- a/hash/test/hash_string_test.cpp
+++ b/hash/test/hash_string_test.cpp
@@ -80,12 +80,68 @@ void wstring_tests()
}
#endif
+#if !defined(BOOST_NO_CXX11_CHAR16_T)
+void u16string_tests()
+{
+ compile_time_tests((std::u16string*) 0);
+
+ BOOST_HASH_TEST_NAMESPACE::hash x1;
+ BOOST_HASH_TEST_NAMESPACE::hash x2;
+
+ BOOST_TEST(x1(u"Hello") == x2(std::u16string(u"Hel") + u"lo"));
+ BOOST_TEST(x1(u"") == x2(std::u16string()));
+
+#if defined(BOOST_HASH_TEST_EXTENSIONS)
+ std::u16string value1;
+ std::u16string value2(u"Hello");
+
+ BOOST_TEST(x1(value1) == BOOST_HASH_TEST_NAMESPACE::hash_value(value1));
+ BOOST_TEST(x1(value2) == BOOST_HASH_TEST_NAMESPACE::hash_value(value2));
+ BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(value1) ==
+ BOOST_HASH_TEST_NAMESPACE::hash_range(value1.begin(), value1.end()));
+ BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(value2) ==
+ BOOST_HASH_TEST_NAMESPACE::hash_range(value2.begin(), value2.end()));
+#endif
+}
+#endif
+
+#if !defined(BOOST_NO_CXX11_CHAR32_T)
+void u32string_tests()
+{
+ compile_time_tests((std::u32string*) 0);
+
+ BOOST_HASH_TEST_NAMESPACE::hash x1;
+ BOOST_HASH_TEST_NAMESPACE::hash x2;
+
+ BOOST_TEST(x1(U"Hello") == x2(std::u32string(U"Hel") + U"lo"));
+ BOOST_TEST(x1(U"") == x2(std::u32string()));
+
+#if defined(BOOST_HASH_TEST_EXTENSIONS)
+ std::u32string value1;
+ std::u32string value2(U"Hello");
+
+ BOOST_TEST(x1(value1) == BOOST_HASH_TEST_NAMESPACE::hash_value(value1));
+ BOOST_TEST(x1(value2) == BOOST_HASH_TEST_NAMESPACE::hash_value(value2));
+ BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(value1) ==
+ BOOST_HASH_TEST_NAMESPACE::hash_range(value1.begin(), value1.end()));
+ BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(value2) ==
+ BOOST_HASH_TEST_NAMESPACE::hash_range(value2.begin(), value2.end()));
+#endif
+}
+#endif
+
int main()
{
string_tests();
string0_tests();
#if !defined(BOOST_NO_STD_WSTRING) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
wstring_tests();
+#endif
+#if !defined(BOOST_NO_CXX11_CHAR16_T)
+ u16string_tests();
+#endif
+#if !defined(BOOST_NO_CXX11_CHAR32_T)
+ u32string_tests();
#endif
return boost::report_errors();
}
diff --git a/include/boost/functional/hash/hash.hpp b/include/boost/functional/hash/hash.hpp
index 76c4897..b461f5f 100644
--- a/include/boost/functional/hash/hash.hpp
+++ b/include/boost/functional/hash/hash.hpp
@@ -107,6 +107,16 @@ namespace boost
boost::hash_detail::enable_hash_value {};
#endif
+#if !defined(BOOST_NO_CXX11_CHAR16_T)
+ template <> struct basic_numbers :
+ boost::hash_detail::enable_hash_value {};
+#endif
+
+#if !defined(BOOST_NO_CXX11_CHAR32_T)
+ template <> struct basic_numbers :
+ boost::hash_detail::enable_hash_value {};
+#endif
+
// long_numbers is defined like this to allow for separate
// specialization for long_long and int128_type, in case
// they conflict.
@@ -455,6 +465,12 @@ namespace boost
BOOST_HASH_SPECIALIZE(unsigned char)
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
BOOST_HASH_SPECIALIZE(wchar_t)
+#endif
+#if !defined(BOOST_NO_CXX11_CHAR16_T)
+ BOOST_HASH_SPECIALIZE(char16_t)
+#endif
+#if !defined(BOOST_NO_CXX11_CHAR32_T)
+ BOOST_HASH_SPECIALIZE(char32_t)
#endif
BOOST_HASH_SPECIALIZE(short)
BOOST_HASH_SPECIALIZE(unsigned short)
@@ -471,6 +487,12 @@ namespace boost
#if !defined(BOOST_NO_STD_WSTRING) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
BOOST_HASH_SPECIALIZE_REF(std::wstring)
#endif
+#if !defined(BOOST_NO_CXX11_CHAR16_T)
+ BOOST_HASH_SPECIALIZE_REF(std::basic_string)
+#endif
+#if !defined(BOOST_NO_CXX11_CHAR32_T)
+ BOOST_HASH_SPECIALIZE_REF(std::basic_string)
+#endif
#if !defined(BOOST_NO_LONG_LONG)
BOOST_HASH_SPECIALIZE(boost::long_long_type)