Support std::string_view

This commit is contained in:
Daniel James
2018-01-20 17:30:33 +00:00
parent f460c21dd0
commit 8b77644ea0
2 changed files with 92 additions and 0 deletions

View File

@@ -58,6 +58,33 @@
# define BOOST_FUNCTIONAL_HASH_ROTL32(x, r) (x << r) | (x >> (32 - r))
#endif
// Detect whether standard library has <string_view>.
#if !defined(BOOST_HASH_HAS_STRING_VIEW) && defined(__has_include)
# if __has_include(<string_view>)
# if defined(BOOST_MSVC)
// On Visual C++ the header exists, but causes an
// error if it isn't in C++17 mode.
# if defined(_HAS_CXX17) && _HAS_CXX17
# define BOOST_HASH_HAS_STRING_VIEW 1
# include <string_view>
# endif
# else
# include <string_view>
# if defined(__cpp_lib_string_view) && __cpp_lib_string_view >= 201603
# define BOOST_HASH_HAS_STRING_VIEW 1
# endif
# endif
# endif
#endif
#if !defined(BOOST_HASH_HAS_STRING_VIEW)
# define BOOST_HASH_HAS_STRING_VIEW 0
#endif
#if BOOST_HASH_HAS_STRING_VIEW
#endif
namespace boost
{
namespace hash_detail
@@ -176,6 +203,12 @@ namespace boost
std::size_t hash_value(
std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const&);
#if BOOST_HASH_HAS_STRING_VIEW
template <class Ch>
std::size_t hash_value(
std::basic_string_view<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch> > const&);
#endif
template <typename T>
typename boost::hash_detail::float_numbers<T>::type hash_value(T);
@@ -410,6 +443,15 @@ namespace boost
return hash_range(v.begin(), v.end());
}
#if BOOST_HASH_HAS_STRING_VIEW
template <class Ch>
inline std::size_t hash_value(
std::basic_string_view<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch> > const& v)
{
return hash_range(v.begin(), v.end());
}
#endif
template <typename T>
typename boost::hash_detail::float_numbers<T>::type hash_value(T v)
{
@@ -494,6 +536,19 @@ namespace boost
BOOST_HASH_SPECIALIZE_REF(std::basic_string<char32_t>)
#endif
#if BOOST_HASH_HAS_STRING_VIEW
BOOST_HASH_SPECIALIZE_REF(std::string_view)
# if !defined(BOOST_NO_STD_WSTRING) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
BOOST_HASH_SPECIALIZE_REF(std::wstring_view)
# endif
# if !defined(BOOST_NO_CXX11_CHAR16_T)
BOOST_HASH_SPECIALIZE_REF(std::basic_string_view<char16_t>)
# endif
# if !defined(BOOST_NO_CXX11_CHAR32_T)
BOOST_HASH_SPECIALIZE_REF(std::basic_string_view<char32_t>)
# endif
#endif
#if !defined(BOOST_NO_LONG_LONG)
BOOST_HASH_SPECIALIZE(boost::long_long_type)
BOOST_HASH_SPECIALIZE(boost::ulong_long_type)

View File

@@ -130,6 +130,37 @@ void u32string_tests()
}
#endif
template <typename StringType>
void generic_string_tests(StringType*)
{
std::string x1(1, '\0');
std::string x2(2, '\0');
std::string x3(3, '\0');
std::string x4(10, '\0');
std::string x5 = x2 + "hello" + x2;
StringType strings[] = {
"",
"hello",
x1,
x2,
x3,
x4,
x5
};
std::size_t const strings_length = sizeof(strings) / sizeof(StringType);
boost::hash<StringType> hash;
for (std::size_t i = 0; i < strings_length; ++i) {
std::size_t hash_i = hash(strings[i]);
for (std::size_t j = 0; j < strings_length; ++j) {
std::size_t hash_j = hash(strings[j]);
BOOST_TEST((hash_i == hash_j) == (i == j));
}
}
}
int main()
{
string_tests();
@@ -143,5 +174,11 @@ int main()
#if !defined(BOOST_NO_CXX11_CHAR32_T)
u32string_tests();
#endif
generic_string_tests((std::string*) 0);
#if BOOST_HASH_HAS_STRING_VIEW
generic_string_tests((std::string_view*) 0);
#endif
return boost::report_errors();
}