forked from boostorg/container_hash
std::optional support
This commit is contained in:
@@ -230,6 +230,11 @@ namespace boost
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
typename boost::hash_detail::float_numbers<T>::type hash_value(T);
|
typename boost::hash_detail::float_numbers<T>::type hash_value(T);
|
||||||
|
|
||||||
|
#if BOOST_HASH_HAS_OPTIONAL
|
||||||
|
template <typename T>
|
||||||
|
std::size_t hash_value(std::optional<T> const&);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
|
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
|
||||||
std::size_t hash_value(std::type_index);
|
std::size_t hash_value(std::type_index);
|
||||||
#endif
|
#endif
|
||||||
@@ -481,6 +486,19 @@ namespace boost
|
|||||||
return boost::hash_detail::float_hash_value(v);
|
return boost::hash_detail::float_hash_value(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if BOOST_HASH_HAS_OPTIONAL
|
||||||
|
template <typename T>
|
||||||
|
inline std::size_t hash_value(std::optional<T> const& v) {
|
||||||
|
if (!v) {
|
||||||
|
// Arbitray value for empty optional.
|
||||||
|
return 0x12345678;
|
||||||
|
} else {
|
||||||
|
boost::hash<T> hf;
|
||||||
|
return hf(*v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
|
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
|
||||||
inline std::size_t hash_value(std::type_index v)
|
inline std::size_t hash_value(std::type_index v)
|
||||||
{
|
{
|
||||||
@@ -540,6 +558,16 @@ namespace boost
|
|||||||
} \
|
} \
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define BOOST_HASH_SPECIALIZE_TEMPLATE_REF(type) \
|
||||||
|
struct hash<type> \
|
||||||
|
: public boost::hash_detail::hash_base<type> \
|
||||||
|
{ \
|
||||||
|
std::size_t operator()(type const& v) const \
|
||||||
|
{ \
|
||||||
|
return boost::hash_value(v); \
|
||||||
|
} \
|
||||||
|
};
|
||||||
|
|
||||||
BOOST_HASH_SPECIALIZE(bool)
|
BOOST_HASH_SPECIALIZE(bool)
|
||||||
BOOST_HASH_SPECIALIZE(char)
|
BOOST_HASH_SPECIALIZE(char)
|
||||||
BOOST_HASH_SPECIALIZE(signed char)
|
BOOST_HASH_SPECIALIZE(signed char)
|
||||||
@@ -598,12 +626,18 @@ namespace boost
|
|||||||
BOOST_HASH_SPECIALIZE(boost::uint128_type)
|
BOOST_HASH_SPECIALIZE(boost::uint128_type)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if BOOST_HASH_HAS_OPTIONAL
|
||||||
|
template <typename T>
|
||||||
|
BOOST_HASH_SPECIALIZE_TEMPLATE_REF(std::optional<T>)
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
|
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
|
||||||
BOOST_HASH_SPECIALIZE(std::type_index)
|
BOOST_HASH_SPECIALIZE(std::type_index)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#undef BOOST_HASH_SPECIALIZE
|
#undef BOOST_HASH_SPECIALIZE
|
||||||
#undef BOOST_HASH_SPECIALIZE_REF
|
#undef BOOST_HASH_SPECIALIZE_REF
|
||||||
|
#undef BOOST_HASH_SPECIALIZE_TEMPLATE_REF
|
||||||
|
|
||||||
// Specializing boost::hash for pointers.
|
// Specializing boost::hash for pointers.
|
||||||
|
|
||||||
|
@@ -43,6 +43,7 @@ test-suite container_hash/hash
|
|||||||
[ run hash_set_test.cpp ]
|
[ run hash_set_test.cpp ]
|
||||||
[ run hash_map_test.cpp ]
|
[ run hash_map_test.cpp ]
|
||||||
[ run hash_complex_test.cpp ]
|
[ run hash_complex_test.cpp ]
|
||||||
|
[ run hash_optional_test.cpp ]
|
||||||
[ run hash_type_index_test.cpp ]
|
[ run hash_type_index_test.cpp ]
|
||||||
[ run hash_system_error_test.cpp ]
|
[ run hash_system_error_test.cpp ]
|
||||||
[ run hash_std_array_test.cpp ]
|
[ run hash_std_array_test.cpp ]
|
||||||
|
70
test/hash_optional_test.cpp
Normal file
70
test/hash_optional_test.cpp
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
|
||||||
|
// 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 "./config.hpp"
|
||||||
|
|
||||||
|
#ifndef BOOST_HASH_TEST_STD_INCLUDES
|
||||||
|
# include <boost/container_hash/hash.hpp>
|
||||||
|
#endif
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
|
#if BOOST_HASH_HAS_OPTIONAL
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
void test_optional_int()
|
||||||
|
{
|
||||||
|
std::optional<int> x1a;
|
||||||
|
std::optional<int> x1b;
|
||||||
|
std::optional<int> x2a(10);
|
||||||
|
std::optional<int> x2b(x2a);
|
||||||
|
std::optional<int> x3(20);
|
||||||
|
|
||||||
|
boost::hash<std::optional<int> > hasher;
|
||||||
|
|
||||||
|
BOOST_TEST(hasher(x1a) == hasher(x1a));
|
||||||
|
BOOST_TEST(hasher(x1a) == hasher(x1b));
|
||||||
|
BOOST_TEST(hasher(x1a) != hasher(x2a));
|
||||||
|
BOOST_TEST(hasher(x1a) != hasher(x3));
|
||||||
|
BOOST_TEST(hasher(x2a) == hasher(x2a));
|
||||||
|
BOOST_TEST(hasher(x2b) == hasher(x2b));
|
||||||
|
BOOST_TEST(hasher(x2a) != hasher(x3));
|
||||||
|
BOOST_TEST(hasher(x3) == hasher(x3));
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_optional_string()
|
||||||
|
{
|
||||||
|
std::optional<std::string> x1a;
|
||||||
|
std::optional<std::string> x1b;
|
||||||
|
std::optional<std::string> x2a("10");
|
||||||
|
std::optional<std::string> x2b(x2a);
|
||||||
|
std::optional<std::string> x3("20");
|
||||||
|
|
||||||
|
boost::hash<std::optional<std::string> > hasher;
|
||||||
|
|
||||||
|
BOOST_TEST(hasher(x1a) == hasher(x1a));
|
||||||
|
BOOST_TEST(hasher(x1a) == hasher(x1b));
|
||||||
|
BOOST_TEST(hasher(x1a) != hasher(x2a));
|
||||||
|
BOOST_TEST(hasher(x1a) != hasher(x3));
|
||||||
|
BOOST_TEST(hasher(x2a) == hasher(x2a));
|
||||||
|
BOOST_TEST(hasher(x2b) == hasher(x2b));
|
||||||
|
BOOST_TEST(hasher(x2a) != hasher(x3));
|
||||||
|
BOOST_TEST(hasher(x3) == hasher(x3));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
#if BOOST_HASH_HAS_OPTIONAL
|
||||||
|
test_optional_int();
|
||||||
|
test_optional_string();
|
||||||
|
#else
|
||||||
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "<optional> not available." << std::endl;
|
||||||
|
#endif
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
Reference in New Issue
Block a user