From d5970f8ed49a15d19265c71c8618e32a9534eeee Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 3 Jan 2020 13:10:02 +0100 Subject: new_type: implement support for derivation of Hash --- include/newtype/derivable.hpp | 7 +++++ include/newtype/impl/type_traits_extensions.hpp | 38 +++++++++++++++++++++++++ include/newtype/new_type.hpp | 16 +++++++++++ 3 files changed, 61 insertions(+) (limited to 'include') diff --git a/include/newtype/derivable.hpp b/include/newtype/derivable.hpp index 95353eb..38a2375 100644 --- a/include/newtype/derivable.hpp +++ b/include/newtype/derivable.hpp @@ -35,6 +35,13 @@ namespace nt */ auto constexpr EqBase = derivable{}; + /** + * @brief A tag to enable derivation of a specialization of std::hash + * + * @since 1.0.0 + */ + auto constexpr Hash = derivable{}; + /** * @brief A tag to enable derivation of the implicit "conversion to base type" operator * diff --git a/include/newtype/impl/type_traits_extensions.hpp b/include/newtype/impl/type_traits_extensions.hpp index 10dbc07..d773d40 100644 --- a/include/newtype/impl/type_traits_extensions.hpp +++ b/include/newtype/impl/type_traits_extensions.hpp @@ -1,6 +1,8 @@ #ifndef NEWTYPE_IMPL_TYPE_TRAITS_EXTENSIONS_HPP #define NEWTYPE_IMPL_TYPE_TRAITS_EXTENSIONS_HPP +#include +#include #include #include @@ -1011,6 +1013,42 @@ namespace nt::impl } // namespace compound_arithmetic + inline namespace std_support + { + + /** + * @brief A trait to test if a given type is hashable + * + * @tparam T The type to test + * @note This specialization forms the base case for non-hashable T + */ + template + struct is_hashable : std::false_type + { + }; + + /** + * @brief A trait to test if a given type is hashable + * + * @tparam T The type to test + * @note This specialization forms the case for hashable T + */ + template + struct is_hashable const &>()(std::declval()))>> + : std::is_same const &>()(std::declval()))> + { + }; + + /** + * @brief A variable template to test if a given type is hashable + * + * @tparam T The type to test + */ + template + auto constexpr is_hashable_v = is_hashable::value; + + } // namespace std_support + } // namespace nt::impl #endif \ No newline at end of file diff --git a/include/newtype/new_type.hpp b/include/newtype/new_type.hpp index a59a074..1477c95 100644 --- a/include/newtype/new_type.hpp +++ b/include/newtype/new_type.hpp @@ -6,6 +6,7 @@ #include "newtype/impl/new_type_storage.hpp" #include "newtype/impl/type_traits_extensions.hpp" +#include #include #include #include @@ -569,4 +570,19 @@ namespace nt } // namespace nt +namespace std +{ + template + struct hash> + { + template + auto constexpr operator()(nt::new_type const & object, + std::enable_if_t> * = nullptr) const + -> std::size_t + { + return std::hash{}(object.decay()); + } + }; +} // namespace std + #endif -- cgit v1.2.3