Add support for described classes to hash.hpp

This commit is contained in:
Peter Dimov
2022-10-28 19:35:10 +03:00
parent 7568176bfa
commit 018fc4e1fa
3 changed files with 209 additions and 0 deletions
+51
View File
@@ -26,7 +26,15 @@
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/type_traits/enable_if.hpp>
#include <boost/type_traits/conjunction.hpp>
#include <boost/type_traits/is_union.hpp>
#include <boost/describe/bases.hpp>
#include <boost/describe/members.hpp>
#include <boost/cstdint.hpp>
#if defined(BOOST_DESCRIBE_CXX14)
# include <boost/mp11/algorithm.hpp>
#endif
#include <string>
#include <iterator>
#include <complex>
@@ -384,6 +392,49 @@ namespace boost
return boost::hash_unordered_range( v.begin(), v.end() );
}
#endif
// described classes
#if defined(BOOST_DESCRIBE_CXX14)
#if defined(_MSC_VER) && _MSC_VER == 1900
# pragma warning(push)
# pragma warning(disable: 4100) // unreferenced formal parameter
#endif
template <typename T>
typename boost::enable_if_<container_hash::is_described_class<T>::value, std::size_t>::type
hash_value( T const& v )
{
static_assert( !boost::is_union<T>::value, "described unions are not supported" );
std::size_t r = 0;
using Bd = describe::describe_bases<T, describe::mod_any_access>;
mp11::mp_for_each<Bd>([&](auto D){
using B = typename decltype(D)::type;
boost::hash_combine( r, (B const&)v );
});
using Md = describe::describe_members<T, describe::mod_any_access>;
mp11::mp_for_each<Md>([&](auto D){
boost::hash_combine( r, v.*D.pointer );
});
return r;
}
#if defined(_MSC_VER) && _MSC_VER == 1900
# pragma warning(pop)
#endif
#endif
// std::unique_ptr, std::shared_ptr