From 3e90982d29b54523c3a617cfff7ec6bcc42ba1e8 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 8 Jun 2023 13:49:36 +0200 Subject: concepts: replace is_hashable_v --- source/lib/include/newtype/concepts.hpp | 19 +++++++++++++++++++ .../include/newtype/impl/type_traits_extensions.hpp | 19 ------------------- source/lib/include/newtype/newtype.hpp | 7 +++---- source/tests/src/hash.cpp | 19 +++++++++++++------ 4 files changed, 35 insertions(+), 29 deletions(-) create mode 100644 source/lib/include/newtype/concepts.hpp diff --git a/source/lib/include/newtype/concepts.hpp b/source/lib/include/newtype/concepts.hpp new file mode 100644 index 0000000..a29ba37 --- /dev/null +++ b/source/lib/include/newtype/concepts.hpp @@ -0,0 +1,19 @@ +#ifndef NEWTYPE_CONCEPTS_HPP +#define NEWTYPE_CONCEPTS_HPP + +#include +#include +#include + +namespace nt::concepts +{ + template + concept hashable = requires(SubjectType subject) { + { + std::hash{}(subject) + } -> std::convertible_to; + }; + +} // namespace nt::concepts + +#endif \ No newline at end of file diff --git a/source/lib/include/newtype/impl/type_traits_extensions.hpp b/source/lib/include/newtype/impl/type_traits_extensions.hpp index dc41649..bdd1cba 100644 --- a/source/lib/include/newtype/impl/type_traits_extensions.hpp +++ b/source/lib/include/newtype/impl/type_traits_extensions.hpp @@ -469,25 +469,6 @@ namespace nt::impl } // namespace compound_arithmetic - inline namespace std_support - { - - template - struct is_hashable : std::false_type - { - }; - - template - struct is_hashable const &>()(std::declval()))>> - : std::is_same const &>()(std::declval()))> - { - }; - - template - auto constexpr is_hashable_v = is_hashable::value; - - } // namespace std_support - inline namespace iterable_begin { template diff --git a/source/lib/include/newtype/newtype.hpp b/source/lib/include/newtype/newtype.hpp index 2e71553..b833c10 100644 --- a/source/lib/include/newtype/newtype.hpp +++ b/source/lib/include/newtype/newtype.hpp @@ -1,6 +1,7 @@ #ifndef NEWTYPE_NEWTYPE_HPP #define NEWTYPE_NEWTYPE_HPP +#include "newtype/concepts.hpp" #include "newtype/derivable.hpp" #include "newtype/deriving.hpp" #include "newtype/impl/new_type_iterator_types.hpp" @@ -535,12 +536,10 @@ namespace nt namespace std { template + requires(nt::concepts::hashable && DerivationClause(nt::Hash)) struct hash> { - template - auto constexpr operator()(nt::new_type const & object, - std::enable_if_t> * = nullptr) const - -> std::size_t + auto constexpr operator()(nt::new_type const & object) const { return std::hash{}(object.decay()); } diff --git a/source/tests/src/hash.cpp b/source/tests/src/hash.cpp index e3f624f..bcf793c 100644 --- a/source/tests/src/hash.cpp +++ b/source/tests/src/hash.cpp @@ -1,31 +1,36 @@ +#include "newtype/concepts.hpp" #include "newtype/derivable.hpp" #include "newtype/deriving.hpp" #include "newtype/impl/type_traits_extensions.hpp" #include "newtype/newtype.hpp" +#include #include +#include #include -SCENARIO("Hash", "[hash]") +TEMPLATE_TEST_CASE("Hash", "[hash]", std::string, int) { GIVEN("A new_type not deriving nt::Hash") { - using type_alias = nt::new_type; + using type_alias = nt::new_type; + static_assert(nt::concepts::hashable); THEN("it is not hashable") { - STATIC_REQUIRE_FALSE(nt::impl::is_hashable_v); + STATIC_REQUIRE_FALSE(nt::concepts::hashable); } } GIVEN("A new_type over a hashable type deriving nt::Hash") { - using type_alias = nt::new_type; + using type_alias = nt::new_type; + static_assert(nt::concepts::hashable); THEN("it is hashable") { - STATIC_REQUIRE(nt::impl::is_hashable_v); + STATIC_REQUIRE(nt::concepts::hashable); } } @@ -35,16 +40,18 @@ SCENARIO("Hash", "[hash]") { }; using type_alias = nt::new_type; + static_assert(!nt::concepts::hashable); THEN("it is not hashable") { - STATIC_REQUIRE_FALSE(nt::impl::is_hashable_v); + STATIC_REQUIRE_FALSE(nt::concepts::hashable); } } GIVEN("A hashable new_type") { using type_alias = nt::new_type; + static_assert(nt::concepts::hashable); THEN("it can be used a the key in an unordered_map") { -- cgit v1.2.3