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 (limited to 'source') 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 From 2b92a0db8c3f171b6f947b749fa3a3c14e309d62 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 8 Jun 2023 14:47:01 +0200 Subject: concepts: replace is_*_*equality_comparable --- source/lib/include/newtype/concepts.hpp | 31 ++++++++++++ .../newtype/impl/type_traits_extensions.hpp | 59 ---------------------- source/lib/include/newtype/newtype.hpp | 34 ++++++------- source/tests/src/equality_comparison.cpp | 15 +++--- 4 files changed, 55 insertions(+), 84 deletions(-) (limited to 'source') diff --git a/source/lib/include/newtype/concepts.hpp b/source/lib/include/newtype/concepts.hpp index a29ba37..6db528c 100644 --- a/source/lib/include/newtype/concepts.hpp +++ b/source/lib/include/newtype/concepts.hpp @@ -7,6 +7,37 @@ namespace nt::concepts { + + template + concept equality_comparable = requires(SubjectType lhs, SubjectType rhs) { + { + lhs == rhs + } -> std::convertible_to; + }; + + template + concept nothrow_equality_comparable = requires(SubjectType lhs, SubjectType rhs) { + requires equality_comparable; + { + lhs == rhs + } noexcept; + }; + + template + concept inequality_comparable = requires(SubjectType lhs, SubjectType rhs) { + { + lhs != rhs + } -> std::convertible_to; + }; + + template + concept nothrow_inequality_comparable = requires(SubjectType lhs, SubjectType rhs) { + requires inequality_comparable; + { + lhs != rhs + } noexcept; + }; + template concept hashable = requires(SubjectType subject) { { diff --git a/source/lib/include/newtype/impl/type_traits_extensions.hpp b/source/lib/include/newtype/impl/type_traits_extensions.hpp index bdd1cba..c4b9bee 100644 --- a/source/lib/include/newtype/impl/type_traits_extensions.hpp +++ b/source/lib/include/newtype/impl/type_traits_extensions.hpp @@ -11,65 +11,6 @@ namespace nt::impl { - inline namespace equality_comparable - { - - template - struct is_equality_comparable : std::false_type - { - }; - - template - struct is_equality_comparable() == std::declval())>> : std::true_type - { - }; - - template - auto constexpr is_equality_comparable_v = is_equality_comparable::value; - - template - struct is_nothrow_equality_comparable : std::false_type - { - }; - - template - struct is_nothrow_equality_comparable() == std::declval())>> - : std::bool_constant() == std::declval())> - { - }; - - template - auto constexpr is_nothrow_equality_comparable_v = is_nothrow_equality_comparable::value; - - template - struct is_inequality_comparable : std::false_type - { - }; - - template - struct is_inequality_comparable() != std::declval())>> : std::true_type - { - }; - - template - auto constexpr is_inequality_comparable_v = is_inequality_comparable::value; - - template - struct is_nothrow_inequality_comparable : std::false_type - { - }; - - template - struct is_nothrow_inequality_comparable() != std::declval())>> - : std::bool_constant() != std::declval())> - { - }; - - template - auto constexpr is_nothrow_inequality_comparable_v = is_nothrow_inequality_comparable::value; - - } // namespace equality_comparable - inline namespace relationally_comparable { diff --git a/source/lib/include/newtype/newtype.hpp b/source/lib/include/newtype/newtype.hpp index b833c10..126c439 100644 --- a/source/lib/include/newtype/newtype.hpp +++ b/source/lib/include/newtype/newtype.hpp @@ -251,54 +251,52 @@ namespace nt } }; - template + template auto constexpr operator==(new_type const & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_equality_comparable_v) - -> std::enable_if_t, bool> + new_type const & rhs) noexcept(nt::concepts::nothrow_equality_comparable) -> bool { return lhs.decay() == rhs.decay(); } - template + template + requires(DerivationClause(nt::EqBase)) auto constexpr operator==(new_type const & lhs, - BaseType const & rhs) noexcept(impl::is_nothrow_equality_comparable_v) - -> std::enable_if_t, bool> + BaseType const & rhs) noexcept(nt::concepts::nothrow_equality_comparable) -> bool { return lhs.decay() == rhs; } - template + template + requires(DerivationClause(nt::EqBase)) auto constexpr operator==(BaseType const & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_equality_comparable_v) - -> std::enable_if_t, bool> + new_type const & rhs) noexcept(nt::concepts::nothrow_equality_comparable) -> bool { return lhs == rhs.decay(); } - template + template auto constexpr operator!=(new_type const & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_inequality_comparable_v) - -> std::enable_if_t, bool> + new_type const & rhs) noexcept(nt::concepts::nothrow_inequality_comparable) -> bool { return lhs.decay() != rhs.decay(); } - template + template + requires(DerivationClause(nt::EqBase)) auto constexpr operator!=(new_type const & lhs, - BaseType const & rhs) noexcept(impl::is_nothrow_inequality_comparable_v) - -> std::enable_if_t, bool> + BaseType const & rhs) noexcept(nt::concepts::nothrow_inequality_comparable) -> bool { return lhs.decay() != rhs; } - template + template + requires(DerivationClause(nt::EqBase)) auto constexpr operator!=(BaseType const & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_inequality_comparable_v) - -> std::enable_if_t, bool> + new_type const & rhs) noexcept(nt::concepts::nothrow_inequality_comparable) -> bool { return lhs != rhs.decay(); } diff --git a/source/tests/src/equality_comparison.cpp b/source/tests/src/equality_comparison.cpp index d857d9b..0876dc2 100644 --- a/source/tests/src/equality_comparison.cpp +++ b/source/tests/src/equality_comparison.cpp @@ -1,3 +1,4 @@ +#include "newtype/concepts.hpp" #include "newtype/derivable.hpp" #include "newtype/deriving.hpp" #include "newtype/newtype.hpp" @@ -64,17 +65,17 @@ SCENARIO("Equality Comparison", "[compare]") { using type_alias = nt::new_type; - static_assert(noexcept(std::declval() == std::declval())); - static_assert(noexcept(std::declval() != std::declval())); + static_assert(nt::concepts::nothrow_equality_comparable); + static_assert(nt::concepts::nothrow_inequality_comparable); THEN("it is nothrow-equality-comparable") { - STATIC_REQUIRE(noexcept(std::declval() == std::declval())); + STATIC_REQUIRE(nt::concepts::nothrow_equality_comparable); } THEN("it is nothrow-inequality-comparable") { - STATIC_REQUIRE(noexcept(std::declval() != std::declval())); + STATIC_REQUIRE(nt::concepts::nothrow_inequality_comparable); } } @@ -88,12 +89,12 @@ SCENARIO("Equality Comparison", "[compare]") using type_alias = nt::new_type; - static_assert(!noexcept(std::declval() == std::declval())); - static_assert(!noexcept(std::declval() != std::declval())); + static_assert(!nt::concepts::nothrow_equality_comparable); + static_assert(!nt::concepts::nothrow_inequality_comparable); THEN("it is not nothrow-equality-comparable") { - STATIC_REQUIRE_FALSE(noexcept(std::declval() == std::declval())); + STATIC_REQUIRE_FALSE(nt::concepts::nothrow_equality_comparable); } THEN("it is not nothrow-inequality-comparable") -- cgit v1.2.3 From 2b22ef0132e041917b6d8a566b12e955fea163b7 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 8 Jun 2023 14:52:36 +0200 Subject: derivations: introduce nt::contains concept --- source/lib/include/newtype/derivation_clause.hpp | 3 +++ source/lib/include/newtype/newtype.hpp | 15 +++++---------- 2 files changed, 8 insertions(+), 10 deletions(-) (limited to 'source') diff --git a/source/lib/include/newtype/derivation_clause.hpp b/source/lib/include/newtype/derivation_clause.hpp index 6de70e1..c4aa051 100644 --- a/source/lib/include/newtype/derivation_clause.hpp +++ b/source/lib/include/newtype/derivation_clause.hpp @@ -65,6 +65,9 @@ namespace nt } }; + template + concept contains = requires(DerivationClause clause) { requires clause(Feature); }; + } // namespace nt #endif \ No newline at end of file diff --git a/source/lib/include/newtype/newtype.hpp b/source/lib/include/newtype/newtype.hpp index 126c439..33863ac 100644 --- a/source/lib/include/newtype/newtype.hpp +++ b/source/lib/include/newtype/newtype.hpp @@ -259,16 +259,14 @@ namespace nt return lhs.decay() == rhs.decay(); } - template - requires(DerivationClause(nt::EqBase)) + template auto DerivationClause> auto constexpr operator==(new_type const & lhs, BaseType const & rhs) noexcept(nt::concepts::nothrow_equality_comparable) -> bool { return lhs.decay() == rhs; } - template - requires(DerivationClause(nt::EqBase)) + template auto DerivationClause> auto constexpr operator==(BaseType const & lhs, new_type const & rhs) noexcept(nt::concepts::nothrow_equality_comparable) -> bool @@ -284,16 +282,14 @@ namespace nt return lhs.decay() != rhs.decay(); } - template - requires(DerivationClause(nt::EqBase)) + template auto DerivationClause> auto constexpr operator!=(new_type const & lhs, BaseType const & rhs) noexcept(nt::concepts::nothrow_inequality_comparable) -> bool { return lhs.decay() != rhs; } - template - requires(DerivationClause(nt::EqBase)) + template auto DerivationClause> auto constexpr operator!=(BaseType const & lhs, new_type const & rhs) noexcept(nt::concepts::nothrow_inequality_comparable) -> bool @@ -533,8 +529,7 @@ namespace nt namespace std { - template - requires(nt::concepts::hashable && DerivationClause(nt::Hash)) + template auto DerivationClause> struct hash> { auto constexpr operator()(nt::new_type const & object) const -- cgit v1.2.3 From 93e02a01568519344310897e8e9f4ee4f32ff75f Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 8 Jun 2023 15:42:41 +0200 Subject: concets: replace is_*_input_streamable* --- source/lib/include/newtype/concepts.hpp | 16 +++++++++++++ .../newtype/impl/type_traits_extensions.hpp | 27 ---------------------- source/lib/include/newtype/newtype.hpp | 20 +++++++++------- 3 files changed, 28 insertions(+), 35 deletions(-) (limited to 'source') diff --git a/source/lib/include/newtype/concepts.hpp b/source/lib/include/newtype/concepts.hpp index 6db528c..c053612 100644 --- a/source/lib/include/newtype/concepts.hpp +++ b/source/lib/include/newtype/concepts.hpp @@ -4,6 +4,7 @@ #include #include #include +#include namespace nt::concepts { @@ -38,6 +39,21 @@ namespace nt::concepts } noexcept; }; + template + concept input_streamable = requires(SubjectType subject) { + { + std::declval &>() >> subject + } -> std::same_as &>; + }; + + template + concept nothrow_input_streamable = requires(SubjectType subject) { + requires input_streamable; + { + std::declval &>() >> subject + } noexcept; + }; + template concept hashable = requires(SubjectType subject) { { diff --git a/source/lib/include/newtype/impl/type_traits_extensions.hpp b/source/lib/include/newtype/impl/type_traits_extensions.hpp index c4b9bee..7db8e66 100644 --- a/source/lib/include/newtype/impl/type_traits_extensions.hpp +++ b/source/lib/include/newtype/impl/type_traits_extensions.hpp @@ -155,33 +155,6 @@ namespace nt::impl template auto constexpr is_nothrow_output_streamable_v = is_nothrow_output_streamable::value; - template - struct is_input_streamable : std::false_type - { - }; - - template - struct is_input_streamable() >> std::declval())>> : std::true_type - { - }; - - template - auto constexpr is_input_streamable_v = is_input_streamable::value; - - template - struct is_nothrow_input_streamable : std::false_type - { - }; - - template - struct is_nothrow_input_streamable() >> std::declval())>> - : std::bool_constant() >> std::declval())> - { - }; - - template - auto constexpr is_nothrow_input_streamable_v = is_nothrow_input_streamable::value; - } // namespace iostreamable inline namespace arithmetic diff --git a/source/lib/include/newtype/newtype.hpp b/source/lib/include/newtype/newtype.hpp index 33863ac..acfd2f9 100644 --- a/source/lib/include/newtype/newtype.hpp +++ b/source/lib/include/newtype/newtype.hpp @@ -25,11 +25,13 @@ namespace nt static_assert(!std::is_reference_v, "The base type must not be a reference type"); static_assert(!std::is_void_v>, "The base type must not be possibly cv-qualified void"); - template + template BaseTypeT, + typename TagTypeT, + nt::contains auto DerivationClauseV> auto friend operator>>(std::basic_istream &, new_type &) noexcept( - impl::is_nothrow_input_streamable_v, BaseTypeT>) - -> std::enable_if_t, BaseTypeT>, - std::basic_istream> &; + nt::concepts::nothrow_input_streamable) -> std::basic_istream &; template auto constexpr friend @@ -342,11 +344,13 @@ namespace nt return output << source.decay(); } - template + template BaseType, + typename TagType, + nt::contains auto DerivationClause> auto operator>>(std::basic_istream & input, new_type & target) noexcept( - impl::is_nothrow_input_streamable_v, BaseType>) - -> std::enable_if_t, BaseType>, - std::basic_istream> & + nt::concepts::nothrow_input_streamable) -> std::basic_istream & { return input >> target.m_value; } -- cgit v1.2.3 From eb13bd9991ceef34cacb0913df90045b08726f81 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 8 Jun 2023 17:31:29 +0200 Subject: concepts: replace is_*_output_streamable* --- source/lib/include/newtype/concepts.hpp | 15 ++++++++++ .../newtype/impl/type_traits_extensions.hpp | 33 ---------------------- source/lib/include/newtype/newtype.hpp | 10 ++++--- source/tests/src/io_operators.cpp | 2 +- 4 files changed, 22 insertions(+), 38 deletions(-) (limited to 'source') diff --git a/source/lib/include/newtype/concepts.hpp b/source/lib/include/newtype/concepts.hpp index c053612..c9ef951 100644 --- a/source/lib/include/newtype/concepts.hpp +++ b/source/lib/include/newtype/concepts.hpp @@ -54,6 +54,21 @@ namespace nt::concepts } noexcept; }; + template + concept output_streamable = requires(SubjectType subject) { + { + std::declval &>() << subject + } -> std::same_as &>; + }; + + template + concept nothrow_output_streamable = requires(SubjectType subject) { + requires output_streamable; + { + std::declval &>() << subject + } noexcept; + }; + template concept hashable = requires(SubjectType subject) { { diff --git a/source/lib/include/newtype/impl/type_traits_extensions.hpp b/source/lib/include/newtype/impl/type_traits_extensions.hpp index 7db8e66..22834f2 100644 --- a/source/lib/include/newtype/impl/type_traits_extensions.hpp +++ b/source/lib/include/newtype/impl/type_traits_extensions.hpp @@ -124,39 +124,6 @@ namespace nt::impl auto constexpr is_nothrow_greater_than_equal_to_comparable_v = is_nothrow_greater_than_equal_to_comparable::value; } // namespace relationally_comparable - inline namespace iostreamable - { - - template - struct is_output_streamable : std::false_type - { - }; - - template - struct is_output_streamable() << std::declval())>> - : std::true_type - { - }; - - template - auto constexpr is_output_streamable_v = is_output_streamable::value; - - template - struct is_nothrow_output_streamable : std::false_type - { - }; - - template - struct is_nothrow_output_streamable() << std::declval())>> - : std::bool_constant() << std::declval())> - { - }; - - template - auto constexpr is_nothrow_output_streamable_v = is_nothrow_output_streamable::value; - - } // namespace iostreamable - inline namespace arithmetic { diff --git a/source/lib/include/newtype/newtype.hpp b/source/lib/include/newtype/newtype.hpp index acfd2f9..e40097d 100644 --- a/source/lib/include/newtype/newtype.hpp +++ b/source/lib/include/newtype/newtype.hpp @@ -335,11 +335,13 @@ namespace nt return lhs.decay() >= rhs.decay(); } - template + template BaseType, + typename TagType, + nt::contains auto DerivationClause> auto operator<<(std::basic_ostream & output, new_type const & source) noexcept( - impl::is_nothrow_output_streamable_v, BaseType>) - -> std::enable_if_t, BaseType>, - std::basic_ostream> & + nt::concepts::nothrow_output_streamable) -> std::basic_ostream & { return output << source.decay(); } diff --git a/source/tests/src/io_operators.cpp b/source/tests/src/io_operators.cpp index 23be171..2be41eb 100644 --- a/source/tests/src/io_operators.cpp +++ b/source/tests/src/io_operators.cpp @@ -83,7 +83,7 @@ SCENARIO("Stream Output") using type_alias = nt::new_type; static_assert(has_stream_output_v); - THEN("it has the stream input operator") + THEN("it has the stream output operator") { STATIC_REQUIRE(has_stream_output_v); } -- cgit v1.2.3 From 8f9e88a9c5d83ea043be341a2b8663130e85f5eb Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 8 Jun 2023 17:34:00 +0200 Subject: concepts: group in namespaces --- source/lib/include/newtype/concepts.hpp | 147 ++++++++++++++++++-------------- 1 file changed, 81 insertions(+), 66 deletions(-) (limited to 'source') diff --git a/source/lib/include/newtype/concepts.hpp b/source/lib/include/newtype/concepts.hpp index c9ef951..8f94a42 100644 --- a/source/lib/include/newtype/concepts.hpp +++ b/source/lib/include/newtype/concepts.hpp @@ -9,72 +9,87 @@ namespace nt::concepts { - template - concept equality_comparable = requires(SubjectType lhs, SubjectType rhs) { - { - lhs == rhs - } -> std::convertible_to; - }; - - template - concept nothrow_equality_comparable = requires(SubjectType lhs, SubjectType rhs) { - requires equality_comparable; - { - lhs == rhs - } noexcept; - }; - - template - concept inequality_comparable = requires(SubjectType lhs, SubjectType rhs) { - { - lhs != rhs - } -> std::convertible_to; - }; - - template - concept nothrow_inequality_comparable = requires(SubjectType lhs, SubjectType rhs) { - requires inequality_comparable; - { - lhs != rhs - } noexcept; - }; - - template - concept input_streamable = requires(SubjectType subject) { - { - std::declval &>() >> subject - } -> std::same_as &>; - }; - - template - concept nothrow_input_streamable = requires(SubjectType subject) { - requires input_streamable; - { - std::declval &>() >> subject - } noexcept; - }; - - template - concept output_streamable = requires(SubjectType subject) { - { - std::declval &>() << subject - } -> std::same_as &>; - }; - - template - concept nothrow_output_streamable = requires(SubjectType subject) { - requires output_streamable; - { - std::declval &>() << subject - } noexcept; - }; - - template - concept hashable = requires(SubjectType subject) { - { - std::hash{}(subject) - } -> std::convertible_to; - }; + inline namespace comparability + { + + template + concept equality_comparable = requires(SubjectType lhs, SubjectType rhs) { + { + lhs == rhs + } -> std::convertible_to; + }; + + template + concept nothrow_equality_comparable = requires(SubjectType lhs, SubjectType rhs) { + requires equality_comparable; + { + lhs == rhs + } noexcept; + }; + + template + concept inequality_comparable = requires(SubjectType lhs, SubjectType rhs) { + { + lhs != rhs + } -> std::convertible_to; + }; + + template + concept nothrow_inequality_comparable = requires(SubjectType lhs, SubjectType rhs) { + requires inequality_comparable; + { + lhs != rhs + } noexcept; + }; + + } // namespace comparability + + inline namespace iostreamable + { + + template + concept input_streamable = requires(SubjectType subject) { + { + std::declval &>() >> subject + } -> std::same_as &>; + }; + + template + concept nothrow_input_streamable = requires(SubjectType subject) { + requires input_streamable; + { + std::declval &>() >> subject + } noexcept; + }; + + template + concept output_streamable = requires(SubjectType subject) { + { + std::declval &>() << subject + } -> std::same_as &>; + }; + + template + concept nothrow_output_streamable = requires(SubjectType subject) { + requires output_streamable; + { + std::declval &>() << subject + } noexcept; + }; + + } // namespace iostreamable + + inline namespace standard_extensions + { + + template + concept hashable = requires(SubjectType subject) { + { + std::hash{}(subject) + } -> std::convertible_to; + }; + + } } // namespace nt::concepts -- cgit v1.2.3 From b55156bed4a56b2e9af46e0d17adc092ac16342e Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 8 Jun 2023 17:55:22 +0200 Subject: concepts: replace relational traits --- source/lib/include/newtype/concepts.hpp | 60 +++++++ .../newtype/impl/type_traits_extensions.hpp | 113 ------------ source/lib/include/newtype/newtype.hpp | 20 +-- source/tests/src/relational_operators.cpp | 198 ++++++++------------- 4 files changed, 141 insertions(+), 250 deletions(-) (limited to 'source') diff --git a/source/lib/include/newtype/concepts.hpp b/source/lib/include/newtype/concepts.hpp index 8f94a42..a50b2b3 100644 --- a/source/lib/include/newtype/concepts.hpp +++ b/source/lib/include/newtype/concepts.hpp @@ -42,6 +42,66 @@ namespace nt::concepts } noexcept; }; + template + concept less_than_comparable = requires(SubjectType lhs, SubjectType rhs) { + { + lhs < rhs + } -> std::convertible_to; + }; + + template + concept nothrow_less_than_comparable = requires(SubjectType lhs, SubjectType rhs) { + requires less_than_comparable; + { + lhs < rhs + } noexcept; + }; + + template + concept less_than_equal_comparable = requires(SubjectType lhs, SubjectType rhs) { + { + lhs <= rhs + } -> std::convertible_to; + }; + + template + concept nothrow_less_than_equal_comparable = requires(SubjectType lhs, SubjectType rhs) { + requires less_than_equal_comparable; + { + lhs <= rhs + } noexcept; + }; + + template + concept greater_than_comparable = requires(SubjectType lhs, SubjectType rhs) { + { + lhs > rhs + } -> std::convertible_to; + }; + + template + concept nothrow_greater_than_comparable = requires(SubjectType lhs, SubjectType rhs) { + requires greater_than_comparable; + { + lhs > rhs + } noexcept; + }; + + template + concept greater_than_equal_comparable = requires(SubjectType lhs, SubjectType rhs) { + { + lhs >= rhs + } -> std::convertible_to; + }; + + template + concept nothrow_greater_than_equal_comparable = requires(SubjectType lhs, SubjectType rhs) { + requires greater_than_equal_comparable; + { + lhs >= rhs + } noexcept; + }; + } // namespace comparability inline namespace iostreamable diff --git a/source/lib/include/newtype/impl/type_traits_extensions.hpp b/source/lib/include/newtype/impl/type_traits_extensions.hpp index 22834f2..c2caf51 100644 --- a/source/lib/include/newtype/impl/type_traits_extensions.hpp +++ b/source/lib/include/newtype/impl/type_traits_extensions.hpp @@ -11,119 +11,6 @@ namespace nt::impl { - inline namespace relationally_comparable - { - - template - struct is_less_than_comparable : std::false_type - { - }; - - template - struct is_less_than_comparable() < std::declval())>> : std::true_type - { - }; - - template - auto constexpr is_less_than_comparable_v = is_less_than_comparable::value; - - template - struct is_nothrow_less_than_comparable : std::false_type - { - }; - - template - struct is_nothrow_less_than_comparable() < std::declval())>> - : std::bool_constant() < std::declval())> - { - }; - - template - auto constexpr is_nothrow_less_than_comparable_v = is_nothrow_less_than_comparable::value; - - template - struct is_greater_than_comparable : std::false_type - { - }; - - template - struct is_greater_than_comparable() > std::declval())>> : std::true_type - { - }; - - template - auto constexpr is_greater_than_comparable_v = is_greater_than_comparable::value; - - template - struct is_nothrow_greater_than_comparable : std::false_type - { - }; - - template - struct is_nothrow_greater_than_comparable() > std::declval())>> - : std::bool_constant() > std::declval())> - { - }; - - template - auto constexpr is_nothrow_greater_than_comparable_v = is_nothrow_greater_than_comparable::value; - - template - struct is_less_than_equal_to_comparable : std::false_type - { - }; - - template - struct is_less_than_equal_to_comparable() <= std::declval())>> : std::true_type - { - }; - - template - auto constexpr is_less_than_equal_to_comparable_v = is_less_than_equal_to_comparable::value; - - template - struct is_nothrow_less_than_equal_to_comparable : std::false_type - { - }; - - template - struct is_nothrow_less_than_equal_to_comparable() <= std::declval())>> - : std::bool_constant() <= std::declval())> - { - }; - - template - auto constexpr is_nothrow_less_than_equal_to_comparable_v = is_nothrow_less_than_equal_to_comparable::value; - - template - struct is_greater_than_equal_to_comparable : std::false_type - { - }; - - template - struct is_greater_than_equal_to_comparable() >= std::declval())>> - : std::true_type - { - }; - - template - auto constexpr is_greater_than_equal_to_comparable_v = is_greater_than_equal_to_comparable::value; - - template - struct is_nothrow_greater_than_equal_to_comparable : std::false_type - { - }; - - template - struct is_nothrow_greater_than_equal_to_comparable() >= std::declval())>> - : std::bool_constant() >= std::declval())> - { - }; - - template - auto constexpr is_nothrow_greater_than_equal_to_comparable_v = is_nothrow_greater_than_equal_to_comparable::value; - } // namespace relationally_comparable - inline namespace arithmetic { diff --git a/source/lib/include/newtype/newtype.hpp b/source/lib/include/newtype/newtype.hpp index e40097d..44bd1b8 100644 --- a/source/lib/include/newtype/newtype.hpp +++ b/source/lib/include/newtype/newtype.hpp @@ -299,38 +299,34 @@ namespace nt return lhs != rhs.decay(); } - template + template auto DerivationClause> auto constexpr operator<(new_type const & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_less_than_comparable_v) - -> std::enable_if_t, bool> + new_type const & rhs) noexcept(nt::concepts::nothrow_less_than_comparable) { return lhs.decay() < rhs.decay(); } - template + template auto DerivationClause> auto constexpr operator>(new_type const & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_greater_than_comparable_v) - -> std::enable_if_t, bool> + new_type const & rhs) noexcept(nt::concepts::nothrow_greater_than_comparable) { return lhs.decay() > rhs.decay(); } - template + template auto DerivationClause> auto constexpr operator<=(new_type const & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_less_than_equal_to_comparable_v) - -> std::enable_if_t, bool> + new_type const & rhs) noexcept(nt::concepts::nothrow_less_than_equal_comparable) { return lhs.decay() <= rhs.decay(); } - template + template auto DerivationClause> auto constexpr operator>=(new_type const & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_greater_than_equal_to_comparable_v) - -> std::enable_if_t, bool> + new_type const & rhs) noexcept(nt::concepts::nothrow_greater_than_equal_comparable) { return lhs.decay() >= rhs.decay(); } diff --git a/source/tests/src/relational_operators.cpp b/source/tests/src/relational_operators.cpp index 95e1bd4..de6f7f3 100644 --- a/source/tests/src/relational_operators.cpp +++ b/source/tests/src/relational_operators.cpp @@ -9,190 +9,121 @@ #include #include -inline namespace traits_extensions -{ - - template - struct has_less_than : std::false_type - { - }; - - template - struct has_less_than() < std::declval())>> : std::true_type - { - }; - - template - auto constexpr has_less_than_v = has_less_than::value; - - template - auto constexpr has_nothrow_less_than_v = has_less_than_v && noexcept(std::declval() < std::declval()); - - template - struct has_greater_than : std::false_type - { - }; - - template - struct has_greater_than() > std::declval())>> : std::true_type - { - }; - - template - auto constexpr has_greater_than_v = has_greater_than::value; - - template - auto constexpr has_nothrow_greater_than_v = has_less_than_v && noexcept(std::declval() < std::declval()); - - template - struct has_less_than_equal_to : std::false_type - { - }; - - template - struct has_less_than_equal_to() <= std::declval())>> : std::true_type - { - }; - - template - auto constexpr has_less_than_equal_to_v = has_less_than_equal_to::value; - - template - auto constexpr has_nothrow_less_than_equal_to_v = has_less_than_v && noexcept(std::declval() < std::declval()); - - template - struct has_greater_than_equal_to : std::false_type - { - }; - - template - struct has_greater_than_equal_to() >= std::declval())>> : std::true_type - { - }; - - template - auto constexpr has_greater_than_equal_to_v = has_greater_than_equal_to::value; - - template - auto constexpr has_nothrow_greater_than_equal_to_v = has_less_than_v && noexcept(std::declval() < std::declval()); - -} // namespace traits_extensions - SCENARIO("Relational Operator Availability") { GIVEN("A new_type over a relationally comparable type not deriving nt::Relational") { using type_alias = nt::new_type; - static_assert(has_less_than_v); - static_assert(has_less_than_equal_to_v); - static_assert(has_greater_than_v); - static_assert(has_greater_than_equal_to_v); + static_assert(nt::concepts::less_than_comparable); + static_assert(nt::concepts::less_than_equal_comparable); + static_assert(nt::concepts::greater_than_comparable); + static_assert(nt::concepts::greater_than_equal_comparable); THEN("it does not have <") { - STATIC_REQUIRE_FALSE(has_less_than_v); + STATIC_REQUIRE_FALSE(nt::concepts::less_than_comparable); } THEN("it does not have <=") { - STATIC_REQUIRE_FALSE(has_less_than_equal_to_v); + STATIC_REQUIRE_FALSE(nt::concepts::less_than_equal_comparable); } THEN("it does not have >") { - STATIC_REQUIRE_FALSE(has_greater_than_v); + STATIC_REQUIRE_FALSE(nt::concepts::greater_than_comparable); } THEN("it does not have >=") { - STATIC_REQUIRE_FALSE(has_greater_than_equal_to_v); + STATIC_REQUIRE_FALSE(nt::concepts::greater_than_equal_comparable); } } GIVEN("A new_type over a relationally comparable type deriving nt::Relational") { using type_alias = nt::new_type; - static_assert(has_less_than_v); - static_assert(has_less_than_equal_to_v); - static_assert(has_greater_than_v); - static_assert(has_greater_than_equal_to_v); + static_assert(nt::concepts::less_than_comparable); + static_assert(nt::concepts::less_than_equal_comparable); + static_assert(nt::concepts::greater_than_comparable); + static_assert(nt::concepts::greater_than_equal_comparable); THEN("it does have <") { - STATIC_REQUIRE(has_less_than_v); + STATIC_REQUIRE(nt::concepts::less_than_comparable); } THEN("it does have <=") { - STATIC_REQUIRE(has_less_than_equal_to_v); + STATIC_REQUIRE(nt::concepts::less_than_equal_comparable); } THEN("it does have >") { - STATIC_REQUIRE(has_greater_than_v); + STATIC_REQUIRE(nt::concepts::greater_than_comparable); } THEN("it does have >=") { - STATIC_REQUIRE(has_greater_than_equal_to_v); + STATIC_REQUIRE(nt::concepts::greater_than_equal_comparable); } } GIVEN("A new_type over a type that is not relationally comparable not deriving nt::Relational") { using type_alias = nt::new_type; - static_assert(!has_less_than_v); - static_assert(!has_less_than_equal_to_v); - static_assert(!has_greater_than_v); - static_assert(!has_greater_than_equal_to_v); + static_assert(!nt::concepts::less_than_comparable); + static_assert(!nt::concepts::less_than_equal_comparable); + static_assert(!nt::concepts::greater_than_comparable); + static_assert(!nt::concepts::greater_than_equal_comparable); THEN("it does not have <") { - STATIC_REQUIRE_FALSE(has_less_than_v); + STATIC_REQUIRE_FALSE(nt::concepts::less_than_comparable); } THEN("it does not have <=") { - STATIC_REQUIRE_FALSE(has_less_than_equal_to_v); + STATIC_REQUIRE_FALSE(nt::concepts::less_than_equal_comparable); } THEN("it does not have >") { - STATIC_REQUIRE_FALSE(has_greater_than_v); + STATIC_REQUIRE_FALSE(nt::concepts::greater_than_comparable); } THEN("it does not have >=") { - STATIC_REQUIRE_FALSE(has_greater_than_equal_to_v); + STATIC_REQUIRE_FALSE(nt::concepts::greater_than_equal_comparable); } } GIVEN("A new_type over a type that is not relationally comparable deriving nt::Relational") { using type_alias = nt::new_type; - static_assert(!has_less_than_v); - static_assert(!has_less_than_equal_to_v); - static_assert(!has_greater_than_v); - static_assert(!has_greater_than_equal_to_v); + static_assert(!nt::concepts::less_than_comparable); + static_assert(!nt::concepts::less_than_equal_comparable); + static_assert(!nt::concepts::greater_than_comparable); + static_assert(!nt::concepts::greater_than_equal_comparable); THEN("it does not have <") { - STATIC_REQUIRE_FALSE(has_less_than_v); + STATIC_REQUIRE_FALSE(nt::concepts::less_than_comparable); } THEN("it does not have <=") { - STATIC_REQUIRE_FALSE(has_less_than_equal_to_v); + STATIC_REQUIRE_FALSE(nt::concepts::less_than_equal_comparable); } THEN("it does not have >") { - STATIC_REQUIRE_FALSE(has_greater_than_v); + STATIC_REQUIRE_FALSE(nt::concepts::greater_than_comparable); } THEN("it does not have >=") { - STATIC_REQUIRE_FALSE(has_greater_than_equal_to_v); + STATIC_REQUIRE_FALSE(nt::concepts::greater_than_equal_comparable); } } } @@ -202,10 +133,10 @@ SCENARIO("Relational Comparisons") GIVEN("A new_type over a relationally comparable type deriving nt::Relational") { using type_alias = nt::new_type; - static_assert(has_less_than_v); - static_assert(has_less_than_equal_to_v); - static_assert(has_greater_than_v); - static_assert(has_greater_than_equal_to_v); + static_assert(nt::concepts::less_than_comparable); + static_assert(nt::concepts::less_than_equal_comparable); + static_assert(nt::concepts::greater_than_comparable); + static_assert(nt::concepts::greater_than_equal_comparable); THEN("comparing two instances using < yields the same result as it does for the base type") { @@ -238,29 +169,29 @@ SCENARIO("Nothrow Relational Comparison") GIVEN("A new_type over a nothrow relationally comparable type deriving nt::Relational") { using type_alias = nt::new_type; - static_assert(has_nothrow_less_than_v); - static_assert(has_nothrow_less_than_equal_to_v); - static_assert(has_nothrow_greater_than_v); - static_assert(has_nothrow_greater_than_equal_to_v); + static_assert(nt::concepts::nothrow_less_than_comparable); + static_assert(nt::concepts::nothrow_less_than_equal_comparable); + static_assert(nt::concepts::nothrow_greater_than_comparable); + static_assert(nt::concepts::nothrow_greater_than_equal_comparable); THEN("it is nothrow-comparable using < ") { - STATIC_REQUIRE(has_nothrow_less_than_v); + STATIC_REQUIRE(nt::concepts::nothrow_less_than_comparable); } THEN("it is nothrow-comparable using <= ") { - STATIC_REQUIRE(has_nothrow_less_than_equal_to_v); + STATIC_REQUIRE(nt::concepts::nothrow_less_than_equal_comparable); } THEN("it is nothrow-comparable using > ") { - STATIC_REQUIRE(has_nothrow_greater_than_v); + STATIC_REQUIRE(nt::concepts::nothrow_greater_than_comparable); } THEN("it is nothrow-comparable using >= ") { - STATIC_REQUIRE(has_nothrow_greater_than_equal_to_v); + STATIC_REQUIRE(nt::concepts::nothrow_greater_than_equal_comparable); } } @@ -268,36 +199,53 @@ SCENARIO("Nothrow Relational Comparison") { struct strange_type { - auto constexpr operator<(strange_type const & other) const noexcept(false) -> bool; - auto constexpr operator>(strange_type const & other) const noexcept(false) -> bool; - auto constexpr operator<=(strange_type const & other) const noexcept(false) -> bool; - auto constexpr operator>=(strange_type const & other) const noexcept(false) -> bool; + auto constexpr operator<(strange_type const &) const noexcept(false) -> bool + { + return false; + } + auto constexpr operator>(strange_type const &) const noexcept(false) -> bool + { + return false; + } + auto constexpr operator<=(strange_type const &) const noexcept(false) -> bool + { + return false; + } + auto constexpr operator>=(strange_type const &) const noexcept(false) -> bool + { + return false; + } }; using type_alias = nt::new_type; - static_assert(has_less_than_v && !has_nothrow_less_than_v); - static_assert(has_less_than_equal_to_v && !has_nothrow_less_than_equal_to_v); - static_assert(has_greater_than_v && !has_nothrow_greater_than_v); - static_assert(has_greater_than_equal_to_v && !has_nothrow_greater_than_equal_to_v); + static_assert(nt::concepts::less_than_comparable && + !nt::concepts::nothrow_less_than_comparable); + static_assert(nt::concepts::less_than_equal_comparable && + !nt::concepts::nothrow_less_than_equal_comparable); + static_assert(nt::concepts::greater_than_comparable && + !nt::concepts::nothrow_greater_than_comparable); + static_assert(nt::concepts::greater_than_equal_comparable && + !nt::concepts::nothrow_greater_than_equal_comparable); THEN("it is not nothrow-comparable using < ") { - STATIC_REQUIRE(has_less_than_v && !has_nothrow_less_than_v); + STATIC_REQUIRE(nt::concepts::less_than_comparable && !nt::concepts::nothrow_less_than_comparable); } THEN("it is not nothrow-comparable using <= ") { - STATIC_REQUIRE(has_less_than_equal_to_v && !has_nothrow_less_than_equal_to_v); + STATIC_REQUIRE(nt::concepts::less_than_equal_comparable && !nt::concepts::nothrow_less_than_equal_comparable); } THEN("it is not nothrow-comparable using > ") { - STATIC_REQUIRE(has_greater_than_v && !has_nothrow_greater_than_v); + STATIC_REQUIRE(nt::concepts::greater_than_comparable && !nt::concepts::nothrow_greater_than_comparable); } THEN("it is not nothrow-comparable using >= ") { - STATIC_REQUIRE(has_greater_than_equal_to_v && !has_nothrow_greater_than_equal_to_v); + STATIC_REQUIRE(nt::concepts::greater_than_equal_comparable && + !nt::concepts::nothrow_greater_than_equal_comparable); } } } -- cgit v1.2.3 From bc83f6dd1330b6b9cb39c8600242d17ff964de36 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 8 Jun 2023 18:09:00 +0200 Subject: concepts: replace arithmetic traits --- source/lib/include/newtype/concepts.hpp | 65 ++++++++++++ .../newtype/impl/type_traits_extensions.hpp | 113 --------------------- source/lib/include/newtype/newtype.hpp | 24 ++--- source/tests/src/arithmetic.cpp | 32 +++--- 4 files changed, 93 insertions(+), 141 deletions(-) (limited to 'source') diff --git a/source/lib/include/newtype/concepts.hpp b/source/lib/include/newtype/concepts.hpp index a50b2b3..42713f5 100644 --- a/source/lib/include/newtype/concepts.hpp +++ b/source/lib/include/newtype/concepts.hpp @@ -9,6 +9,71 @@ namespace nt::concepts { + inline namespace arithmetic + { + + template + concept addable = requires(SubjectType lhs, SubjectType rhs) { + { + lhs + rhs + } -> std::same_as; + }; + + template + concept nothrow_addable = requires(SubjectType lhs, SubjectType rhs) { + requires addable; + { + lhs + rhs + } noexcept; + }; + + template + concept divisible = requires(SubjectType lhs, SubjectType rhs) { + { + lhs / rhs + } -> std::same_as; + }; + + template + concept nothrow_divisible = requires(SubjectType lhs, SubjectType rhs) { + requires divisible; + { + lhs / rhs + } noexcept; + }; + + template + concept multipliable = requires(SubjectType lhs, SubjectType rhs) { + { + lhs * rhs + } -> std::same_as; + }; + + template + concept nothrow_multipliable = requires(SubjectType lhs, SubjectType rhs) { + requires multipliable; + { + lhs / rhs + } noexcept; + }; + + template + concept subtractable = requires(SubjectType lhs, SubjectType rhs) { + { + lhs - rhs + } -> std::same_as; + }; + + template + concept nothrow_subtractable = requires(SubjectType lhs, SubjectType rhs) { + requires subtractable; + { + lhs - rhs + } noexcept; + }; + + } // namespace arithmetic + inline namespace comparability { diff --git a/source/lib/include/newtype/impl/type_traits_extensions.hpp b/source/lib/include/newtype/impl/type_traits_extensions.hpp index c2caf51..3bf2c8d 100644 --- a/source/lib/include/newtype/impl/type_traits_extensions.hpp +++ b/source/lib/include/newtype/impl/type_traits_extensions.hpp @@ -11,119 +11,6 @@ namespace nt::impl { - inline namespace arithmetic - { - - template - struct is_addable : std::false_type - { - }; - - template - struct is_addable() + std::declval())>> : std::true_type - { - }; - - template - auto constexpr is_addable_v = is_addable::value; - - template - struct is_nothrow_addable : std::false_type - { - }; - - template - struct is_nothrow_addable() + std::declval())>> - : std::bool_constant() + std::declval())> - { - }; - - template - auto constexpr is_nothrow_addable_v = is_nothrow_addable::value; - - template - struct is_subtractable : std::false_type - { - }; - - template - struct is_subtractable() - std::declval())>> : std::true_type - { - }; - - template - auto constexpr is_subtractable_v = is_subtractable::value; - - template - struct is_nothrow_subtractable : std::false_type - { - }; - - template - struct is_nothrow_subtractable() - std::declval())>> - : std::bool_constant() - std::declval())> - { - }; - - template - auto constexpr is_nothrow_subtractable_v = is_nothrow_subtractable::value; - - template - struct is_multipliable : std::false_type - { - }; - - template - struct is_multipliable() * std::declval())>> : std::true_type - { - }; - - template - auto constexpr is_multipliable_v = is_multipliable::value; - - template - struct is_nothrow_multipliable : std::false_type - { - }; - - template - struct is_nothrow_multipliable() * std::declval())>> - : std::bool_constant() * std::declval())> - { - }; - - template - auto constexpr is_nothrow_multipliable_v = is_nothrow_multipliable::value; - - template - struct is_dividable : std::false_type - { - }; - - template - struct is_dividable() / std::declval())>> : std::true_type - { - }; - - template - auto constexpr is_dividable_v = is_dividable::value; - - template - struct is_nothrow_dividable : std::false_type - { - }; - - template - struct is_nothrow_dividable() / std::declval())>> - : std::bool_constant() / std::declval())> - { - }; - - template - auto constexpr is_nothrow_dividable_v = is_nothrow_dividable::value; - - } // namespace arithmetic - inline namespace compound_arithmetic { diff --git a/source/lib/include/newtype/newtype.hpp b/source/lib/include/newtype/newtype.hpp index 44bd1b8..4642122 100644 --- a/source/lib/include/newtype/newtype.hpp +++ b/source/lib/include/newtype/newtype.hpp @@ -353,11 +353,11 @@ namespace nt return input >> target.m_value; } - template + template auto DerivationClause> auto constexpr operator+(new_type const & lhs, new_type const & rhs) noexcept( - impl::is_nothrow_addable_v && std::is_nothrow_copy_constructible_v) - -> std::enable_if_t, new_type> + nt::concepts::nothrow_addable && std::is_nothrow_copy_constructible_v) + -> new_type { return {lhs.decay() + rhs.decay()}; } @@ -372,11 +372,11 @@ namespace nt return lhs; } - template + template auto DerivationClause> auto constexpr operator-(new_type const & lhs, new_type const & rhs) noexcept( - impl::is_nothrow_subtractable_v && std::is_nothrow_copy_constructible_v) - -> std::enable_if_t, new_type> + nt::concepts::nothrow_subtractable && std::is_nothrow_copy_constructible_v) + -> new_type { return {lhs.decay() - rhs.decay()}; } @@ -392,11 +392,11 @@ namespace nt return lhs; } - template + template auto DerivationClause> auto constexpr operator*(new_type const & lhs, new_type const & rhs) noexcept( - impl::is_nothrow_multipliable_v && std::is_nothrow_copy_constructible_v) - -> std::enable_if_t, new_type> + nt::concepts::nothrow_multipliable && std::is_nothrow_copy_constructible_v) + -> new_type { return {lhs.decay() * rhs.decay()}; } @@ -412,11 +412,11 @@ namespace nt return lhs; } - template + template auto DerivationClause> auto constexpr operator/(new_type const & lhs, new_type const & rhs) noexcept( - impl::is_nothrow_dividable_v && std::is_nothrow_copy_constructible_v) - -> std::enable_if_t, new_type> + nt::concepts::nothrow_divisible && std::is_nothrow_copy_constructible_v) + -> new_type { return {lhs.decay() / rhs.decay()}; } diff --git a/source/tests/src/arithmetic.cpp b/source/tests/src/arithmetic.cpp index 09b0c4a..647e600 100644 --- a/source/tests/src/arithmetic.cpp +++ b/source/tests/src/arithmetic.cpp @@ -23,7 +23,7 @@ SCENARIO("Addition", "[arithmetic]") THEN("it is not addable") { - STATIC_REQUIRE(!nt::impl::is_addable_v); + STATIC_REQUIRE(!nt::concepts::addable); } } @@ -33,7 +33,7 @@ SCENARIO("Addition", "[arithmetic]") THEN("it is addable") { - STATIC_REQUIRE(nt::impl::is_addable_v); + STATIC_REQUIRE(nt::concepts::addable); } } @@ -43,7 +43,7 @@ SCENARIO("Addition", "[arithmetic]") THEN("it is not addable") { - STATIC_REQUIRE(!nt::impl::is_addable_v == nt::impl::is_addable_v); + STATIC_REQUIRE(!nt::concepts::addable == nt::concepts::addable); } } @@ -53,7 +53,7 @@ SCENARIO("Addition", "[arithmetic]") THEN("it is addable") { - STATIC_REQUIRE(nt::impl::is_addable_v == nt::impl::is_addable_v); + STATIC_REQUIRE(nt::concepts::addable == nt::concepts::addable); } } @@ -96,7 +96,7 @@ SCENARIO("Subtraction", "[arithmetic]") THEN("it is not subtractable") { - STATIC_REQUIRE(!nt::impl::is_subtractable_v); + STATIC_REQUIRE(!nt::concepts::subtractable); } } @@ -106,7 +106,7 @@ SCENARIO("Subtraction", "[arithmetic]") THEN("it is subtractable") { - STATIC_REQUIRE(nt::impl::is_subtractable_v); + STATIC_REQUIRE(nt::concepts::subtractable); } } @@ -116,7 +116,7 @@ SCENARIO("Subtraction", "[arithmetic]") THEN("it is not addable") { - STATIC_REQUIRE(!nt::impl::is_subtractable_v); + STATIC_REQUIRE(!nt::concepts::subtractable); } } @@ -126,7 +126,7 @@ SCENARIO("Subtraction", "[arithmetic]") THEN("it is subtractable") { - STATIC_REQUIRE(nt::impl::is_subtractable_v); + STATIC_REQUIRE(nt::concepts::subtractable); } } @@ -169,7 +169,7 @@ SCENARIO("Multiplication", "[arithmetic]") THEN("it is not multipliable") { - STATIC_REQUIRE(!nt::impl::is_multipliable_v); + STATIC_REQUIRE(!nt::concepts::multipliable); } } @@ -179,7 +179,7 @@ SCENARIO("Multiplication", "[arithmetic]") THEN("it is multipliable") { - STATIC_REQUIRE(nt::impl::is_multipliable_v); + STATIC_REQUIRE(nt::concepts::multipliable); } } @@ -189,7 +189,7 @@ SCENARIO("Multiplication", "[arithmetic]") THEN("it is not multipliable") { - STATIC_REQUIRE(!nt::impl::is_multipliable_v); + STATIC_REQUIRE(!nt::concepts::multipliable); } } @@ -199,7 +199,7 @@ SCENARIO("Multiplication", "[arithmetic]") THEN("it is multipliable") { - STATIC_REQUIRE(nt::impl::is_multipliable_v); + STATIC_REQUIRE(nt::concepts::multipliable); } } @@ -242,7 +242,7 @@ SCENARIO("Division", "[arithmetic]") THEN("it is not divisible") { - STATIC_REQUIRE(!nt::impl::is_dividable_v); + STATIC_REQUIRE(!nt::concepts::divisible); } } @@ -252,7 +252,7 @@ SCENARIO("Division", "[arithmetic]") THEN("it is divisible") { - STATIC_REQUIRE(nt::impl::is_dividable_v); + STATIC_REQUIRE(nt::concepts::divisible); } } @@ -262,7 +262,7 @@ SCENARIO("Division", "[arithmetic]") THEN("it is not divisible") { - STATIC_REQUIRE(!nt::impl::is_dividable_v); + STATIC_REQUIRE(!nt::concepts::divisible); } } @@ -272,7 +272,7 @@ SCENARIO("Division", "[arithmetic]") THEN("it is divisible") { - STATIC_REQUIRE(nt::impl::is_dividable_v); + STATIC_REQUIRE(nt::concepts::divisible); } } -- cgit v1.2.3 From e42a927fbb40bab04a1398695efffccf8f284cdc Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 9 Jun 2023 11:10:52 +0200 Subject: concepts: replace iterator traits --- source/lib/include/newtype/concepts.hpp | 232 +++++++++ source/lib/include/newtype/derivation_clause.hpp | 7 +- .../newtype/impl/type_traits_extensions.hpp | 360 ------------- source/lib/include/newtype/newtype.hpp | 226 ++++---- source/tests/CMakeLists.txt | 1 + source/tests/src/iterable.cpp | 576 ++++++++++----------- 6 files changed, 620 insertions(+), 782 deletions(-) (limited to 'source') diff --git a/source/lib/include/newtype/concepts.hpp b/source/lib/include/newtype/concepts.hpp index 42713f5..fc625ed 100644 --- a/source/lib/include/newtype/concepts.hpp +++ b/source/lib/include/newtype/concepts.hpp @@ -204,6 +204,238 @@ namespace nt::concepts } // namespace iostreamable + inline namespace iterable + { + + template + concept free_begin = requires(SubjectType & subject) { + typename SubjectType::iterator; + { + begin(subject) + } -> std::same_as; + }; + + template + concept const_free_begin = requires(SubjectType const & subject) { + typename SubjectType::const_iterator; + { + begin(subject) + } -> std::same_as; + }; + + template + concept member_begin = requires(SubjectType & subject) { + typename SubjectType::iterator; + { + subject.begin() + } -> std::same_as; + }; + + template + concept const_member_begin = requires(SubjectType const & subject) { + typename SubjectType::const_iterator; + { + subject.begin() + } -> std::same_as; + }; + + template + concept beginnable = free_begin || member_begin; + + template + concept const_beginnable = const_free_begin || const_member_begin; + + template + concept free_cbegin = requires(SubjectType const & subject) { + typename SubjectType::const_iterator; + { + cbegin(subject) + } -> std::same_as; + }; + + template + concept member_cbegin = requires(SubjectType const & subject) { + typename SubjectType::const_iterator; + { + subject.cbegin() + } -> std::same_as; + }; + + template + concept cbeginnable = free_cbegin || member_cbegin; + + template + concept free_rbegin = requires(SubjectType & subject) { + typename SubjectType::reverse_iterator; + { + rbegin(subject) + } -> std::same_as; + }; + + template + concept const_free_rbegin = requires(SubjectType const & subject) { + typename SubjectType::const_reverse_iterator; + { + rbegin(subject) + } -> std::same_as; + }; + + template + concept member_rbegin = requires(SubjectType & subject) { + typename SubjectType::reverse_iterator; + { + subject.rbegin() + } -> std::same_as; + }; + + template + concept const_member_rbegin = requires(SubjectType const & subject) { + typename SubjectType::const_reverse_iterator; + { + subject.rbegin() + } -> std::same_as; + }; + + template + concept rbeginnable = free_rbegin || member_rbegin; + + template + concept const_rbeginnable = const_free_rbegin || const_member_rbegin; + + template + concept free_crbegin = requires(SubjectType const & subject) { + typename SubjectType::const_reverse_iterator; + { + crbegin(subject) + } -> std::same_as; + }; + + template + concept member_crbegin = requires(SubjectType const & subject) { + typename SubjectType::const_reverse_iterator; + { + subject.crbegin() + } -> std::same_as; + }; + + template + concept crbeginnable = free_crbegin || member_crbegin; + + template + concept free_end = requires(SubjectType & subject) { + typename SubjectType::iterator; + { + end(subject) + } -> std::same_as; + }; + + template + concept const_free_end = requires(SubjectType const & subject) { + typename SubjectType::const_iterator; + { + end(subject) + } -> std::same_as; + }; + + template + concept member_end = requires(SubjectType & subject) { + typename SubjectType::iterator; + { + subject.end() + } -> std::same_as; + }; + + template + concept const_member_end = requires(SubjectType const & subject) { + typename SubjectType::const_iterator; + { + subject.end() + } -> std::same_as; + }; + + template + concept endable = free_end || member_end; + + template + concept const_endable = const_free_end || const_member_end; + + template + concept free_cend = requires(SubjectType const & subject) { + typename SubjectType::const_iterator; + { + cend(subject) + } -> std::same_as; + }; + + template + concept member_cend = requires(SubjectType const & subject) { + typename SubjectType::const_iterator; + { + subject.cend() + } -> std::same_as; + }; + + template + concept cendable = free_cend || member_cend; + + template + concept free_rend = requires(SubjectType & subject) { + typename SubjectType::reverse_iterator; + { + rend(subject) + } -> std::same_as; + }; + + template + concept const_free_rend = requires(SubjectType const & subject) { + typename SubjectType::const_reverse_iterator; + { + rend(subject) + } -> std::same_as; + }; + + template + concept member_rend = requires(SubjectType & subject) { + typename SubjectType::reverse_iterator; + { + subject.rend() + } -> std::same_as; + }; + + template + concept const_member_rend = requires(SubjectType const & subject) { + typename SubjectType::const_reverse_iterator; + { + subject.rend() + } -> std::same_as; + }; + + template + concept rendable = free_rend || member_rend; + + template + concept const_rendable = const_free_rend || const_member_rend; + + template + concept free_crend = requires(SubjectType const & subject) { + typename SubjectType::const_reverse_iterator; + { + crend(subject) + } -> std::same_as; + }; + + template + concept member_crend = requires(SubjectType const & subject) { + typename SubjectType::const_reverse_iterator; + { + subject.crend() + } -> std::same_as; + }; + + template + concept crendable = free_crend || member_crend; + } // namespace iterable + inline namespace standard_extensions { diff --git a/source/lib/include/newtype/derivation_clause.hpp b/source/lib/include/newtype/derivation_clause.hpp index c4aa051..eb3e8f1 100644 --- a/source/lib/include/newtype/derivation_clause.hpp +++ b/source/lib/include/newtype/derivation_clause.hpp @@ -12,6 +12,9 @@ namespace nt template struct derivation_clause { + template + using contains = std::disjunction...>; + constexpr derivation_clause(derivable...) noexcept { } @@ -65,8 +68,8 @@ namespace nt } }; - template - concept contains = requires(DerivationClause clause) { requires clause(Feature); }; + template + concept contains = requires(DerivationClause clause) { requires DerivationClause::template contains::value; }; } // namespace nt diff --git a/source/lib/include/newtype/impl/type_traits_extensions.hpp b/source/lib/include/newtype/impl/type_traits_extensions.hpp index 3bf2c8d..dd25905 100644 --- a/source/lib/include/newtype/impl/type_traits_extensions.hpp +++ b/source/lib/include/newtype/impl/type_traits_extensions.hpp @@ -124,366 +124,6 @@ namespace nt::impl } // namespace compound_arithmetic - inline namespace iterable_begin - { - template - struct has_free_begin : std::false_type - { - }; - - template - struct has_free_begin()))>> - : std::is_same()))>> - { - }; - - template - struct has_free_begin()))>> - : std::is_same()))>> - { - }; - - template - auto constexpr has_free_begin_v = has_free_begin::value; - - template - struct has_member_begin : std::false_type - { - }; - - template - struct has_member_begin().begin())>> - : std::is_same().begin())>> - { - }; - - template - struct has_member_begin().begin())>> - : std::is_same().begin())>> - { - }; - - template - auto constexpr has_member_begin_v = has_member_begin::value; - - template - struct has_begin : std::disjunction, has_member_begin> - { - }; - - template - auto constexpr has_begin_v = has_begin::value; - } // namespace iterable_begin - - inline namespace iterable_cbegin - { - template - struct has_free_cbegin : std::false_type - { - }; - - template - struct has_free_cbegin()))>> - : std::is_same()))>> - { - }; - - template - auto constexpr has_free_cbegin_v = has_free_cbegin::value; - - template - struct has_member_cbegin : std::false_type - { - }; - - template - struct has_member_cbegin().cbegin())>> - : std::is_same().cbegin())> - { - }; - - template - auto constexpr has_member_cbegin_v = has_member_cbegin::value; - - template - struct has_cbegin : std::disjunction, has_member_cbegin> - { - }; - - template - auto constexpr has_cbegin_v = has_cbegin::value; - } // namespace iterable_cbegin - - inline namespace iterable_rbegin - { - template - struct has_free_rbegin : std::false_type - { - }; - - template - struct has_free_rbegin()))>> - : std::is_same()))>> - { - }; - - template - struct has_free_rbegin()))>> - : std::is_same()))>> - { - }; - - template - auto constexpr has_free_rbegin_v = has_free_rbegin::value; - - template - struct has_member_rbegin : std::false_type - { - }; - - template - struct has_member_rbegin().rbegin())>> - : std::is_same().rbegin())>> - { - }; - - template - struct has_member_rbegin().rbegin())>> - : std::is_same().rbegin())>> - { - }; - - template - auto constexpr has_member_rbegin_v = has_member_rbegin::value; - - template - struct has_rbegin : std::disjunction, has_member_rbegin> - { - }; - - template - auto constexpr has_rbegin_v = has_rbegin::value; - } // namespace iterable_rbegin - - inline namespace iterable_crbegin - { - template - struct has_free_crbegin : std::false_type - { - }; - - template - struct has_free_crbegin()))>> - : std::is_same()))>> - { - }; - - template - auto constexpr has_free_crbegin_v = has_free_crbegin::value; - - template - struct has_member_crbegin : std::false_type - { - }; - - template - struct has_member_crbegin().crbegin())>> - : std::is_same().crbegin())>> - { - }; - - template - auto constexpr has_member_crbegin_v = has_member_crbegin::value; - - template - struct has_crbegin : std::disjunction, has_member_crbegin> - { - }; - - template - auto constexpr has_crbegin_v = has_crbegin::value; - } // namespace iterable_crbegin - - inline namespace iterable_end - { - template - struct has_free_end : std::false_type - { - }; - - template - struct has_free_end()))>> - : std::is_same()))>> - { - }; - - template - struct has_free_end()))>> - : std::is_same()))>> - { - }; - - template - auto constexpr has_free_end_v = has_free_end::value; - - template - struct has_member_end : std::false_type - { - }; - - template - struct has_member_end().end())>> - : std::is_same().end())>> - { - }; - - template - struct has_member_end().end())>> - : std::is_same().end())>> - { - }; - - template - auto constexpr has_member_end_v = has_member_end::value; - - template - struct has_end : std::disjunction, has_member_end> - { - }; - - template - auto constexpr has_end_v = has_end::value; - } // namespace iterable_end - - inline namespace iterable_cend - { - template - struct has_free_cend : std::false_type - { - }; - - template - struct has_free_cend()))>> - : std::is_same()))>> - { - }; - - template - auto constexpr has_free_cend_v = has_free_cend::value; - - template - struct has_member_cend : std::false_type - { - }; - - template - struct has_member_cend().cend())>> - : std::is_same().cend())> - { - }; - - template - auto constexpr has_member_cend_v = has_member_cend::value; - - template - struct has_cend : std::disjunction, has_member_cend> - { - }; - - template - auto constexpr has_cend_v = has_cend::value; - } // namespace iterable_cend - - inline namespace iterable_rend - { - template - struct has_free_rend : std::false_type - { - }; - - template - struct has_free_rend()))>> - : std::is_same()))>> - { - }; - - template - struct has_free_rend()))>> - : std::is_same()))>> - { - }; - - template - auto constexpr has_free_rend_v = has_free_rend::value; - - template - struct has_member_rend : std::false_type - { - }; - - template - struct has_member_rend().rend())>> - : std::is_same().rend())>> - { - }; - - template - struct has_member_rend().rend())>> - : std::is_same().rend())>> - { - }; - - template - auto constexpr has_member_rend_v = has_member_rend::value; - - template - struct has_rend : std::disjunction, has_member_rend> - { - }; - - template - auto constexpr has_rend_v = has_rend::value; - } // namespace iterable_rend - - inline namespace iterable_crend - { - template - struct has_free_crend : std::false_type - { - }; - - template - struct has_free_crend()))>> - : std::is_same()))>> - { - }; - - template - auto constexpr has_free_crend_v = has_free_crend::value; - - template - struct has_member_crend : std::false_type - { - }; - - template - struct has_member_crend().crend())>> - : std::is_same().crend())>> - { - }; - - template - auto constexpr has_member_crend_v = has_member_crend::value; - - template - struct has_crend : std::disjunction, has_member_crend> - { - }; - - template - auto constexpr has_crend_v = has_crend::value; - } // namespace iterable_crend - } // namespace nt::impl #endif \ No newline at end of file diff --git a/source/lib/include/newtype/newtype.hpp b/source/lib/include/newtype/newtype.hpp index 4642122..b5eca97 100644 --- a/source/lib/include/newtype/newtype.hpp +++ b/source/lib/include/newtype/newtype.hpp @@ -61,65 +61,53 @@ namespace nt -> std::enable_if_t, new_type &>; - template - auto constexpr friend begin(new_type & obj) - -> std::enable_if_t, - typename new_type::iterator>; + template auto DerivationClauseV> + auto constexpr friend begin(new_type & obj) -> + typename new_type::iterator; - template - auto constexpr friend begin(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_iterator>; + template auto DerivationClauseV> + auto constexpr friend begin(new_type const & obj) -> + typename new_type::const_iterator; - template - auto constexpr friend cbegin(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_iterator>; + template auto DerivationClauseV> + auto constexpr friend cbegin(new_type const & obj) -> + typename new_type::const_iterator; - template - auto constexpr friend rbegin(new_type & obj) - -> std::enable_if_t, - typename new_type::reverse_iterator>; + template auto DerivationClauseV> + auto constexpr friend rbegin(new_type & obj) -> + typename new_type::reverse_iterator; - template - auto constexpr friend rbegin(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_reverse_iterator>; + template auto DerivationClauseV> + auto constexpr friend rbegin(new_type const & obj) -> + typename new_type::const_reverse_iterator; - template - auto constexpr friend crbegin(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_reverse_iterator>; + template auto DerivationClauseV> + auto constexpr friend crbegin(new_type const & obj) -> + typename new_type::const_reverse_iterator; - template - auto constexpr friend end(new_type & obj) - -> std::enable_if_t, - typename new_type::iterator>; + template auto DerivationClauseV> + auto constexpr friend end(new_type & obj) -> + typename new_type::iterator; - template - auto constexpr friend end(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_iterator>; + template auto DerivationClauseV> + auto constexpr friend end(new_type const & obj) -> + typename new_type::const_iterator; - template - auto constexpr friend cend(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_iterator>; + template auto DerivationClauseV> + auto constexpr friend cend(new_type const & obj) -> + typename new_type::const_iterator; - template - auto constexpr friend rend(new_type & obj) - -> std::enable_if_t, - typename new_type::reverse_iterator>; + template auto DerivationClauseV> + auto constexpr friend rend(new_type & obj) -> + typename new_type::reverse_iterator; - template - auto constexpr friend rend(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_reverse_iterator>; + template auto DerivationClauseV> + auto constexpr friend rend(new_type const & obj) -> + typename new_type::const_reverse_iterator; - template - auto constexpr friend crend(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_reverse_iterator>; + template auto DerivationClauseV> + auto constexpr friend crend(new_type const & obj) -> + typename new_type::const_reverse_iterator; using super = impl::new_type_move_assignment; @@ -168,86 +156,74 @@ namespace nt return std::addressof(this->m_value); } - template * = nullptr> - auto constexpr begin() - -> std::enable_if_t, typename NewType::iterator> + template auto DerivationClauseV = DerivationClause> + auto constexpr begin() -> typename new_type::iterator { return this->m_value.begin(); } - template - auto constexpr begin() const -> std::enable_if_t, - typename NewType::const_iterator> + template auto DerivationClauseV = DerivationClause> + auto constexpr begin() const -> typename new_type::const_iterator { return this->m_value.begin(); } - template - auto constexpr cbegin() const -> std::enable_if_t, - typename NewType::const_iterator> + template auto DerivationClauseV = DerivationClause> + auto constexpr cbegin() const -> typename new_type::const_iterator { return this->m_value.cbegin(); } - template * = nullptr> - auto constexpr rbegin() - -> std::enable_if_t, typename NewType::reverse_iterator> + template auto DerivationClauseV = DerivationClause> + auto constexpr rbegin() -> typename new_type::reverse_iterator { return this->m_value.rbegin(); } - template - auto constexpr rbegin() const -> std::enable_if_t, - typename NewType::const_reverse_iterator> + template auto DerivationClauseV = DerivationClause> + auto constexpr rbegin() const -> typename new_type::const_reverse_iterator { return this->m_value.rbegin(); } - template - auto constexpr crbegin() const -> std::enable_if_t, - typename NewType::const_reverse_iterator> + template auto DerivationClauseV = DerivationClause> + auto constexpr crbegin() const -> typename new_type::const_reverse_iterator { return this->m_value.crbegin(); } - template * = nullptr> - auto constexpr end() - -> std::enable_if_t, typename NewType::iterator> + template auto DerivationClauseV = DerivationClause> + auto constexpr end() -> typename new_type::iterator { return this->m_value.end(); } - template - auto constexpr end() const -> std::enable_if_t, - typename NewType::const_iterator> + template auto DerivationClauseV = DerivationClause> + auto constexpr end() const -> typename new_type::const_iterator { return this->m_value.end(); } - template - auto constexpr cend() const -> std::enable_if_t, - typename NewType::const_iterator> + template auto DerivationClauseV = DerivationClause> + auto constexpr cend() const -> typename new_type::const_iterator { return this->m_value.cend(); } - template * = nullptr> - auto constexpr rend() - -> std::enable_if_t, typename NewType::reverse_iterator> + template auto DerivationClauseV = DerivationClause> + auto constexpr rend() -> typename new_type::reverse_iterator { return this->m_value.rend(); } - template - auto constexpr rend() const -> std::enable_if_t, - typename NewType::const_reverse_iterator> + template auto DerivationClauseV = DerivationClause> + auto constexpr rend() const -> typename new_type::const_reverse_iterator { return this->m_value.rend(); } - template - auto constexpr crend() const -> std::enable_if_t, - typename NewType::const_reverse_iterator> + template auto DerivationClauseV = DerivationClause> + auto constexpr crend() const -> typename new_type::const_reverse_iterator { return this->m_value.crend(); } @@ -431,98 +407,84 @@ namespace nt return lhs; } - template - auto constexpr begin(new_type & obj) - -> std::enable_if_t, - typename new_type::iterator> + template auto DerivationClause> + auto constexpr begin(new_type & obj) -> typename new_type::iterator { return begin(obj.m_value); } - template - auto constexpr begin(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_iterator> + template auto DerivationClause> + auto constexpr begin(new_type const & obj) -> + typename new_type::const_iterator { return begin(obj.m_value); } - template - auto constexpr cbegin(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_iterator> + template auto DerivationClause> + auto constexpr cbegin(new_type const & obj) -> + typename new_type::const_iterator { return cbegin(obj.m_value); } - template - auto constexpr rbegin(new_type & obj) - -> std::enable_if_t, - typename new_type::reverse_iterator> + template auto DerivationClause> + auto constexpr rbegin(new_type & obj) -> + typename new_type::reverse_iterator { return rbegin(obj.m_value); } - template - auto constexpr rbegin(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_reverse_iterator> + template auto DerivationClause> + auto constexpr rbegin(new_type const & obj) -> + typename new_type::const_reverse_iterator { return rbegin(obj.m_value); } - template - auto constexpr crbegin(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_reverse_iterator> + template auto DerivationClause> + auto constexpr crbegin(new_type const & obj) -> + typename new_type::const_reverse_iterator { return crbegin(obj.m_value); } - template - auto constexpr end(new_type & obj) - -> std::enable_if_t, - typename new_type::iterator> + template auto DerivationClause> + auto constexpr end(new_type & obj) -> typename new_type::iterator { return end(obj.m_value); } - template - auto constexpr end(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_iterator> + template auto DerivationClause> + auto constexpr end(new_type const & obj) -> + typename new_type::const_iterator { return end(obj.m_value); } - template - auto constexpr cend(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_iterator> + template auto DerivationClause> + auto constexpr cend(new_type const & obj) -> + typename new_type::const_iterator { return cend(obj.m_value); } - template - auto constexpr rend(new_type & obj) - -> std::enable_if_t, - typename new_type::reverse_iterator> + template auto DerivationClause> + auto constexpr rend(new_type & obj) -> + typename new_type::reverse_iterator { return rend(obj.m_value); } - template - auto constexpr rend(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_reverse_iterator> + template auto DerivationClause> + auto constexpr rend(new_type const & obj) -> + typename new_type::const_reverse_iterator { return rend(obj.m_value); } - template - auto constexpr crend(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_reverse_iterator> + template auto DerivationClause> + auto constexpr crend(new_type const & obj) -> + typename new_type::const_reverse_iterator { return crend(obj.m_value); } diff --git a/source/tests/CMakeLists.txt b/source/tests/CMakeLists.txt index 4fa1cdc..ce6b707 100644 --- a/source/tests/CMakeLists.txt +++ b/source/tests/CMakeLists.txt @@ -28,6 +28,7 @@ target_compile_options("${PROJECT_NAME}_tests" PRIVATE "$<$:-Wextra>" "$<$:-Werror>" "$<$:-pedantic-errors>" + "$<$:-fconcepts-diagnostics-depth=5>" ) catch_discover_tests("${PROJECT_NAME}_tests") diff --git a/source/tests/src/iterable.cpp b/source/tests/src/iterable.cpp index 265dc8c..ba91500 100644 --- a/source/tests/src/iterable.cpp +++ b/source/tests/src/iterable.cpp @@ -63,308 +63,308 @@ SCENARIO("Iterators", "[iterators]") GIVEN("A new_type over a non-iterable base type not deriving nt::Iterable") { using type_alias = nt::new_type; - static_assert(!nt::impl::has_begin_v); - static_assert(!nt::impl::has_begin_v); - static_assert(!nt::impl::has_cbegin_v); - static_assert(!nt::impl::has_rbegin_v); - static_assert(!nt::impl::has_rbegin_v); - static_assert(!nt::impl::has_crbegin_v); - static_assert(!nt::impl::has_end_v); - static_assert(!nt::impl::has_end_v); - static_assert(!nt::impl::has_cend_v); - static_assert(!nt::impl::has_rend_v); - static_assert(!nt::impl::has_rend_v); - static_assert(!nt::impl::has_crend_v); + static_assert(!nt::concepts::beginnable); + static_assert(!nt::concepts::beginnable); + static_assert(!nt::concepts::cbeginnable); + static_assert(!nt::concepts::rbeginnable); + static_assert(!nt::concepts::rbeginnable); + static_assert(!nt::concepts::crbeginnable); + static_assert(!nt::concepts::endable); + static_assert(!nt::concepts::endable); + static_assert(!nt::concepts::cendable); + static_assert(!nt::concepts::rendable); + static_assert(!nt::concepts::rendable); + static_assert(!nt::concepts::crendable); THEN("it has no begin") { - STATIC_REQUIRE_FALSE(nt::impl::has_begin_v); + STATIC_REQUIRE_FALSE(nt::concepts::beginnable); } THEN("it has no constant begin") { - STATIC_REQUIRE_FALSE(nt::impl::has_begin_v); + STATIC_REQUIRE_FALSE(nt::concepts::beginnable); } THEN("it has no cbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_cbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::cbeginnable); } THEN("it has no rbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_rbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::rbeginnable); } THEN("it has no constant rbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_rbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::rbeginnable); } THEN("it has no crbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_crbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::crbeginnable); } THEN("it has no end") { - STATIC_REQUIRE_FALSE(nt::impl::has_end_v); + STATIC_REQUIRE_FALSE(nt::concepts::endable); } THEN("it has no constant end") { - STATIC_REQUIRE_FALSE(nt::impl::has_end_v); + STATIC_REQUIRE_FALSE(nt::concepts::endable); } THEN("it has no cend") { - STATIC_REQUIRE_FALSE(nt::impl::has_cend_v); + STATIC_REQUIRE_FALSE(nt::concepts::cendable); } THEN("it has no rend") { - STATIC_REQUIRE_FALSE(nt::impl::has_rend_v); + STATIC_REQUIRE_FALSE(nt::concepts::rendable); } THEN("it has no constant rend") { - STATIC_REQUIRE_FALSE(nt::impl::has_rend_v); + STATIC_REQUIRE_FALSE(nt::concepts::rendable); } THEN("it has no crend") { - STATIC_REQUIRE_FALSE(nt::impl::has_crend_v); + STATIC_REQUIRE_FALSE(nt::concepts::crendable); } } GIVEN("A new_type over a non-iterable base type deriving nt::Iterable") { using type_alias = nt::new_type; - static_assert(!nt::impl::has_begin_v); - static_assert(!nt::impl::has_begin_v); - static_assert(!nt::impl::has_cbegin_v); - static_assert(!nt::impl::has_rbegin_v); - static_assert(!nt::impl::has_rbegin_v); - static_assert(!nt::impl::has_crbegin_v); - static_assert(!nt::impl::has_end_v); - static_assert(!nt::impl::has_end_v); - static_assert(!nt::impl::has_cend_v); - static_assert(!nt::impl::has_rend_v); - static_assert(!nt::impl::has_rend_v); - static_assert(!nt::impl::has_crend_v); + static_assert(!nt::concepts::beginnable); + static_assert(!nt::concepts::beginnable); + static_assert(!nt::concepts::cbeginnable); + static_assert(!nt::concepts::rbeginnable); + static_assert(!nt::concepts::rbeginnable); + static_assert(!nt::concepts::crbeginnable); + static_assert(!nt::concepts::endable); + static_assert(!nt::concepts::endable); + static_assert(!nt::concepts::cendable); + static_assert(!nt::concepts::rendable); + static_assert(!nt::concepts::rendable); + static_assert(!nt::concepts::crendable); THEN("it has no begin") { - STATIC_REQUIRE_FALSE(nt::impl::has_begin_v); + STATIC_REQUIRE_FALSE(nt::concepts::beginnable); } THEN("it has no constant begin") { - STATIC_REQUIRE_FALSE(nt::impl::has_begin_v); + STATIC_REQUIRE_FALSE(nt::concepts::beginnable); } THEN("it has no cbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_cbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::cbeginnable); } THEN("it has no rbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_rbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::rbeginnable); } THEN("it has no constant rbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_rbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::rbeginnable); } THEN("it has no crbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_crbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::crbeginnable); } THEN("it has no end") { - STATIC_REQUIRE_FALSE(nt::impl::has_end_v); + STATIC_REQUIRE_FALSE(nt::concepts::endable); } THEN("it has no constant end") { - STATIC_REQUIRE_FALSE(nt::impl::has_end_v); + STATIC_REQUIRE_FALSE(nt::concepts::endable); } THEN("it has no cend") { - STATIC_REQUIRE_FALSE(nt::impl::has_cend_v); + STATIC_REQUIRE_FALSE(nt::concepts::cendable); } THEN("it has no rend") { - STATIC_REQUIRE_FALSE(nt::impl::has_rend_v); + STATIC_REQUIRE_FALSE(nt::concepts::rendable); } THEN("it has no constant rend") { - STATIC_REQUIRE_FALSE(nt::impl::has_rend_v); + STATIC_REQUIRE_FALSE(nt::concepts::rendable); } THEN("it has no crend") { - STATIC_REQUIRE_FALSE(nt::impl::has_crend_v); + STATIC_REQUIRE_FALSE(nt::concepts::crendable); } } GIVEN("A new_type over an iterable base type not deriving nt::Iterable") { using type_alias = nt::new_type, struct tag>; - static_assert(nt::impl::has_begin_v); - static_assert(nt::impl::has_begin_v); - static_assert(nt::impl::has_cbegin_v); - static_assert(nt::impl::has_rbegin_v); - static_assert(nt::impl::has_rbegin_v); - static_assert(nt::impl::has_crbegin_v); - static_assert(nt::impl::has_end_v); - static_assert(nt::impl::has_end_v); - static_assert(nt::impl::has_cend_v); - static_assert(nt::impl::has_rend_v); - static_assert(nt::impl::has_rend_v); - static_assert(nt::impl::has_crend_v); + static_assert(nt::concepts::beginnable); + static_assert(nt::concepts::const_beginnable); + static_assert(nt::concepts::cbeginnable); + static_assert(nt::concepts::rbeginnable); + static_assert(nt::concepts::const_rbeginnable); + static_assert(nt::concepts::crbeginnable); + static_assert(nt::concepts::endable); + static_assert(nt::concepts::const_endable); + static_assert(nt::concepts::cendable); + static_assert(nt::concepts::rendable); + static_assert(nt::concepts::const_rendable); + static_assert(nt::concepts::crendable); THEN("it has no begin") { - STATIC_REQUIRE_FALSE(nt::impl::has_begin_v); + STATIC_REQUIRE_FALSE(nt::concepts::beginnable); } THEN("it has no constant begin") { - STATIC_REQUIRE_FALSE(nt::impl::has_begin_v); + STATIC_REQUIRE_FALSE(nt::concepts::beginnable); } THEN("it has no cbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_cbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::cbeginnable); } THEN("it has no rbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_rbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::rbeginnable); } THEN("it has no constant rbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_rbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::rbeginnable); } THEN("it has no crbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_crbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::crbeginnable); } THEN("it has no end") { - STATIC_REQUIRE_FALSE(nt::impl::has_end_v); + STATIC_REQUIRE_FALSE(nt::concepts::endable); } THEN("it has no constant end") { - STATIC_REQUIRE_FALSE(nt::impl::has_end_v); + STATIC_REQUIRE_FALSE(nt::concepts::endable); } THEN("it has no cend") { - STATIC_REQUIRE_FALSE(nt::impl::has_cend_v); + STATIC_REQUIRE_FALSE(nt::concepts::cendable); } THEN("it has no rend") { - STATIC_REQUIRE_FALSE(nt::impl::has_rend_v); + STATIC_REQUIRE_FALSE(nt::concepts::rendable); } THEN("it has no constant rend") { - STATIC_REQUIRE_FALSE(nt::impl::has_rend_v); + STATIC_REQUIRE_FALSE(nt::concepts::rendable); } THEN("it has no crend") { - STATIC_REQUIRE_FALSE(nt::impl::has_crend_v); + STATIC_REQUIRE_FALSE(nt::concepts::crendable); } } GIVEN("A new_type over an iterable base type deriving nt::Iterable") { using type_alias = nt::new_type, struct tag, deriving(nt::Iterable)>; - static_assert(nt::impl::has_begin_v); - static_assert(nt::impl::has_begin_v); - static_assert(nt::impl::has_cbegin_v); - static_assert(nt::impl::has_rbegin_v); - static_assert(nt::impl::has_rbegin_v); - static_assert(nt::impl::has_crbegin_v); - static_assert(nt::impl::has_end_v); - static_assert(nt::impl::has_end_v); - static_assert(nt::impl::has_cend_v); - static_assert(nt::impl::has_rend_v); - static_assert(nt::impl::has_rend_v); - static_assert(nt::impl::has_crend_v); + static_assert(nt::concepts::beginnable); + static_assert(nt::concepts::const_beginnable); + static_assert(nt::concepts::cbeginnable); + static_assert(nt::concepts::rbeginnable); + static_assert(nt::concepts::const_rbeginnable); + static_assert(nt::concepts::crbeginnable); + static_assert(nt::concepts::endable); + static_assert(nt::concepts::const_endable); + static_assert(nt::concepts::cendable); + static_assert(nt::concepts::rendable); + static_assert(nt::concepts::const_rendable); + static_assert(nt::concepts::crendable); THEN("it has begin") { - STATIC_REQUIRE(nt::impl::has_begin_v); + STATIC_REQUIRE(nt::concepts::beginnable); } THEN("it has constant begin") { - STATIC_REQUIRE(nt::impl::has_begin_v); + STATIC_REQUIRE(nt::concepts::const_beginnable); } THEN("it has cbegin") { - STATIC_REQUIRE(nt::impl::has_cbegin_v); + STATIC_REQUIRE(nt::concepts::cbeginnable); } THEN("it has rbegin") { - STATIC_REQUIRE(nt::impl::has_rbegin_v); + STATIC_REQUIRE(nt::concepts::rbeginnable); } THEN("it has constant rbegin") { - STATIC_REQUIRE(nt::impl::has_rbegin_v); + STATIC_REQUIRE(nt::concepts::const_rbeginnable); } THEN("it has crbegin") { - STATIC_REQUIRE(nt::impl::has_crbegin_v); + STATIC_REQUIRE(nt::concepts::crbeginnable); } THEN("it has end") { - STATIC_REQUIRE(nt::impl::has_end_v); + STATIC_REQUIRE(nt::concepts::endable); } THEN("it has constant end") { - STATIC_REQUIRE(nt::impl::has_end_v); + STATIC_REQUIRE(nt::concepts::const_endable); } THEN("it has cend") { - STATIC_REQUIRE(nt::impl::has_cend_v); + STATIC_REQUIRE(nt::concepts::cendable); } THEN("it has rend") { - STATIC_REQUIRE(nt::impl::has_rend_v); + STATIC_REQUIRE(nt::concepts::rendable); } THEN("it has constant rend") { - STATIC_REQUIRE(nt::impl::has_rend_v); + STATIC_REQUIRE(nt::concepts::const_rendable); } THEN("it has crend") { - STATIC_REQUIRE(nt::impl::has_crend_v); + STATIC_REQUIRE(nt::concepts::crendable); } } } @@ -374,308 +374,308 @@ SCENARIO("Iterators (member)", "[iterators]") GIVEN("A new_type over a non-iterable base type not deriving nt::Iterable") { using type_alias = nt::new_type; - static_assert(!nt::impl::has_member_begin_v); - static_assert(!nt::impl::has_member_begin_v); - static_assert(!nt::impl::has_member_cbegin_v); - static_assert(!nt::impl::has_member_rbegin_v); - static_assert(!nt::impl::has_member_rbegin_v); - static_assert(!nt::impl::has_member_crbegin_v); - static_assert(!nt::impl::has_member_end_v); - static_assert(!nt::impl::has_member_end_v); - static_assert(!nt::impl::has_member_cend_v); - static_assert(!nt::impl::has_member_rend_v); - static_assert(!nt::impl::has_member_rend_v); - static_assert(!nt::impl::has_member_crend_v); + static_assert(!nt::concepts::member_begin); + static_assert(!nt::concepts::const_member_begin); + static_assert(!nt::concepts::member_cbegin); + static_assert(!nt::concepts::member_rbegin); + static_assert(!nt::concepts::const_member_rbegin); + static_assert(!nt::concepts::member_crbegin); + static_assert(!nt::concepts::member_end); + static_assert(!nt::concepts::const_member_end); + static_assert(!nt::concepts::member_cend); + static_assert(!nt::concepts::member_rend); + static_assert(!nt::concepts::const_member_rend); + static_assert(!nt::concepts::member_crend); THEN("it has no member begin") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_begin_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_begin); } THEN("it has no member constant begin") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_begin_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_begin); } THEN("it has no member cbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_cbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_cbegin); } THEN("it has no member rbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_rbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_rbegin); } THEN("it has no member constant rbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_rbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_rbegin); } THEN("it has no member crbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_crbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_crbegin); } THEN("it has no member end") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_end_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_end); } THEN("it has no member constant end") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_end_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_end); } THEN("it has no member cend") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_cend_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_cend); } THEN("it has no member rend") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_rend_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_rend); } THEN("it has no member constant rend") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_rend_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_rend); } THEN("it has no member crend") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_crend_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_crend); } } GIVEN("A new_type over a non-iterable base type deriving nt::Iterable") { using type_alias = nt::new_type; - static_assert(!nt::impl::has_member_begin_v); - static_assert(!nt::impl::has_member_begin_v); - static_assert(!nt::impl::has_member_cbegin_v); - static_assert(!nt::impl::has_member_rbegin_v); - static_assert(!nt::impl::has_member_rbegin_v); - static_assert(!nt::impl::has_member_crbegin_v); - static_assert(!nt::impl::has_member_end_v); - static_assert(!nt::impl::has_member_end_v); - static_assert(!nt::impl::has_member_cend_v); - static_assert(!nt::impl::has_member_rend_v); - static_assert(!nt::impl::has_member_rend_v); - static_assert(!nt::impl::has_member_crend_v); + static_assert(!nt::concepts::member_begin); + static_assert(!nt::concepts::const_member_begin); + static_assert(!nt::concepts::member_cbegin); + static_assert(!nt::concepts::member_rbegin); + static_assert(!nt::concepts::const_member_rbegin); + static_assert(!nt::concepts::member_crbegin); + static_assert(!nt::concepts::member_end); + static_assert(!nt::concepts::const_member_end); + static_assert(!nt::concepts::member_cend); + static_assert(!nt::concepts::member_rend); + static_assert(!nt::concepts::const_member_rend); + static_assert(!nt::concepts::member_crend); THEN("it has no member begin") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_begin_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_begin); } THEN("it has no member constant begin") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_begin_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_begin); } THEN("it has no member cbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_cbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_cbegin); } THEN("it has no member rbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_rbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_rbegin); } THEN("it has no member constant rbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_rbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_rbegin); } THEN("it has no member crbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_crbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_crbegin); } THEN("it has no member end") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_end_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_end); } THEN("it has no member constant end") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_end_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_end); } THEN("it has no member cend") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_cend_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_cend); } THEN("it has no member rend") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_rend_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_rend); } THEN("it has no member constant rend") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_rend_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_rend); } THEN("it has no member crend") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_crend_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_crend); } } GIVEN("A new_type over an iterable base type not deriving nt::Iterable") { using type_alias = nt::new_type, struct tag>; - static_assert(nt::impl::has_member_begin_v); - static_assert(nt::impl::has_member_begin_v); - static_assert(nt::impl::has_member_cbegin_v); - static_assert(nt::impl::has_member_rbegin_v); - static_assert(nt::impl::has_member_rbegin_v); - static_assert(nt::impl::has_member_crbegin_v); - static_assert(nt::impl::has_member_end_v); - static_assert(nt::impl::has_member_end_v); - static_assert(nt::impl::has_member_cend_v); - static_assert(nt::impl::has_member_rend_v); - static_assert(nt::impl::has_member_rend_v); - static_assert(nt::impl::has_member_crend_v); + static_assert(nt::concepts::member_begin); + static_assert(nt::concepts::const_member_begin); + static_assert(nt::concepts::member_cbegin); + static_assert(nt::concepts::member_rbegin); + static_assert(nt::concepts::const_member_rbegin); + static_assert(nt::concepts::member_crbegin); + static_assert(nt::concepts::member_end); + static_assert(nt::concepts::const_member_end); + static_assert(nt::concepts::member_cend); + static_assert(nt::concepts::member_rend); + static_assert(nt::concepts::const_member_rend); + static_assert(nt::concepts::member_crend); THEN("it has no member begin") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_begin_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_begin); } THEN("it has no member constant begin") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_begin_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_begin); } THEN("it has no member cbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_cbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_cbegin); } THEN("it has no member rbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_rbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_rbegin); } THEN("it has no member constant rbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_rbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_rbegin); } THEN("it has no member crbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_crbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_crbegin); } THEN("it has no member end") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_end_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_end); } THEN("it has no member constant end") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_end_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_end); } THEN("it has no member cend") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_cend_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_cend); } THEN("it has no member rend") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_rend_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_rend); } THEN("it has no member constant rend") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_rend_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_rend); } THEN("it has no member crend") { - STATIC_REQUIRE_FALSE(nt::impl::has_member_crend_v); + STATIC_REQUIRE_FALSE(nt::concepts::member_crend); } } GIVEN("A new_type over an iterable base type deriving nt::Iterable") { using type_alias = nt::new_type, struct tag, deriving(nt::Iterable)>; - static_assert(nt::impl::has_member_begin_v); - static_assert(nt::impl::has_member_begin_v); - static_assert(nt::impl::has_member_cbegin_v); - static_assert(nt::impl::has_member_rbegin_v); - static_assert(nt::impl::has_member_rbegin_v); - static_assert(nt::impl::has_member_crbegin_v); - static_assert(nt::impl::has_member_end_v); - static_assert(nt::impl::has_member_end_v); - static_assert(nt::impl::has_member_cend_v); - static_assert(nt::impl::has_member_rend_v); - static_assert(nt::impl::has_member_rend_v); - static_assert(nt::impl::has_member_crend_v); + static_assert(nt::concepts::member_begin); + static_assert(nt::concepts::const_member_begin); + static_assert(nt::concepts::member_cbegin); + static_assert(nt::concepts::member_rbegin); + static_assert(nt::concepts::const_member_rbegin); + static_assert(nt::concepts::member_crbegin); + static_assert(nt::concepts::member_end); + static_assert(nt::concepts::const_member_end); + static_assert(nt::concepts::member_cend); + static_assert(nt::concepts::member_rend); + static_assert(nt::concepts::const_member_rend); + static_assert(nt::concepts::member_crend); THEN("it has member begin") { - STATIC_REQUIRE(nt::impl::has_member_begin_v); + STATIC_REQUIRE(nt::concepts::member_begin); } THEN("it has member constant begin") { - STATIC_REQUIRE(nt::impl::has_member_begin_v); + STATIC_REQUIRE(nt::concepts::const_member_begin); } THEN("it has member cbegin") { - STATIC_REQUIRE(nt::impl::has_member_cbegin_v); + STATIC_REQUIRE(nt::concepts::member_cbegin); } THEN("it has member rbegin") { - STATIC_REQUIRE(nt::impl::has_member_rbegin_v); + STATIC_REQUIRE(nt::concepts::member_rbegin); } THEN("it has member constant rbegin") { - STATIC_REQUIRE(nt::impl::has_member_rbegin_v); + STATIC_REQUIRE(nt::concepts::const_member_rbegin); } THEN("it has member crbegin") { - STATIC_REQUIRE(nt::impl::has_member_crbegin_v); + STATIC_REQUIRE(nt::concepts::member_crbegin); } THEN("it has member end") { - STATIC_REQUIRE(nt::impl::has_member_end_v); + STATIC_REQUIRE(nt::concepts::member_end); } THEN("it has member constant end") { - STATIC_REQUIRE(nt::impl::has_member_end_v); + STATIC_REQUIRE(nt::concepts::const_member_end); } THEN("it has member cend") { - STATIC_REQUIRE(nt::impl::has_member_cend_v); + STATIC_REQUIRE(nt::concepts::member_cend); } THEN("it has member rend") { - STATIC_REQUIRE(nt::impl::has_member_rend_v); + STATIC_REQUIRE(nt::concepts::member_rend); } THEN("it has member constant rend") { - STATIC_REQUIRE(nt::impl::has_member_rend_v); + STATIC_REQUIRE(nt::concepts::const_member_rend); } THEN("it has member crend") { - STATIC_REQUIRE(nt::impl::has_member_crend_v); + STATIC_REQUIRE(nt::concepts::member_crend); } } } @@ -685,308 +685,308 @@ SCENARIO("Iterators (free)", "[iterators]") GIVEN("A new_type over a non-iterable base type not deriving nt::Iterable") { using type_alias = nt::new_type; - static_assert(!nt::impl::has_free_begin_v); - static_assert(!nt::impl::has_free_begin_v); - static_assert(!nt::impl::has_free_cbegin_v); - static_assert(!nt::impl::has_free_rbegin_v); - static_assert(!nt::impl::has_free_rbegin_v); - static_assert(!nt::impl::has_free_crbegin_v); - static_assert(!nt::impl::has_free_end_v); - static_assert(!nt::impl::has_free_end_v); - static_assert(!nt::impl::has_free_cend_v); - static_assert(!nt::impl::has_free_rend_v); - static_assert(!nt::impl::has_free_rend_v); - static_assert(!nt::impl::has_free_crend_v); + static_assert(!nt::concepts::free_begin); + static_assert(!nt::concepts::const_free_begin); + static_assert(!nt::concepts::free_cbegin); + static_assert(!nt::concepts::free_rbegin); + static_assert(!nt::concepts::const_free_rbegin); + static_assert(!nt::concepts::free_crbegin); + static_assert(!nt::concepts::free_end); + static_assert(!nt::concepts::const_free_end); + static_assert(!nt::concepts::free_cend); + static_assert(!nt::concepts::free_rend); + static_assert(!nt::concepts::const_free_rend); + static_assert(!nt::concepts::free_crend); THEN("it has no free begin") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_begin_v); + STATIC_REQUIRE_FALSE(nt::concepts::free_begin); } THEN("it has no free constant begin") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_begin_v); + STATIC_REQUIRE_FALSE(nt::concepts::const_free_begin); } THEN("it has no free cbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_cbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::free_cbegin); } THEN("it has no free rbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_rbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::free_rbegin); } THEN("it has no free constant rbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_rbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::const_free_rbegin); } THEN("it has no free crbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_crbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::free_crbegin); } THEN("it has no free end") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_end_v); + STATIC_REQUIRE_FALSE(nt::concepts::free_end); } THEN("it has no free constant end") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_end_v); + STATIC_REQUIRE_FALSE(nt::concepts::const_free_end); } THEN("it has no free cend") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_cend_v); + STATIC_REQUIRE_FALSE(nt::concepts::free_cend); } THEN("it has no free rend") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_rend_v); + STATIC_REQUIRE_FALSE(nt::concepts::free_rend); } THEN("it has no free constant rend") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_rend_v); + STATIC_REQUIRE_FALSE(nt::concepts::const_free_rend); } THEN("it has no free crend") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_crend_v); + STATIC_REQUIRE_FALSE(nt::concepts::free_crend); } } GIVEN("A new_type over a non-iterable base type deriving nt::Iterable") { using type_alias = nt::new_type; - static_assert(!nt::impl::has_free_begin_v); - static_assert(!nt::impl::has_free_begin_v); - static_assert(!nt::impl::has_free_cbegin_v); - static_assert(!nt::impl::has_free_rbegin_v); - static_assert(!nt::impl::has_free_rbegin_v); - static_assert(!nt::impl::has_free_crbegin_v); - static_assert(!nt::impl::has_free_end_v); - static_assert(!nt::impl::has_free_end_v); - static_assert(!nt::impl::has_free_cend_v); - static_assert(!nt::impl::has_free_rend_v); - static_assert(!nt::impl::has_free_rend_v); - static_assert(!nt::impl::has_free_crend_v); + static_assert(!nt::concepts::free_begin); + static_assert(!nt::concepts::const_free_begin); + static_assert(!nt::concepts::free_cbegin); + static_assert(!nt::concepts::free_rbegin); + static_assert(!nt::concepts::const_free_rbegin); + static_assert(!nt::concepts::free_crbegin); + static_assert(!nt::concepts::free_end); + static_assert(!nt::concepts::const_free_end); + static_assert(!nt::concepts::free_cend); + static_assert(!nt::concepts::free_rend); + static_assert(!nt::concepts::const_free_rend); + static_assert(!nt::concepts::free_crend); THEN("it has no free begin") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_begin_v); + STATIC_REQUIRE_FALSE(nt::concepts::free_begin); } THEN("it has no free constant begin") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_begin_v); + STATIC_REQUIRE_FALSE(nt::concepts::const_free_begin); } THEN("it has no free cbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_cbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::free_cbegin); } THEN("it has no free rbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_rbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::free_rbegin); } THEN("it has no free constant rbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_rbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::const_free_rbegin); } THEN("it has no free crbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_crbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::free_crbegin); } THEN("it has no free end") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_end_v); + STATIC_REQUIRE_FALSE(nt::concepts::free_end); } THEN("it has no free constant end") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_end_v); + STATIC_REQUIRE_FALSE(nt::concepts::const_free_end); } THEN("it has no free cend") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_cend_v); + STATIC_REQUIRE_FALSE(nt::concepts::free_cend); } THEN("it has no free rend") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_rend_v); + STATIC_REQUIRE_FALSE(nt::concepts::free_rend); } THEN("it has no free constant rend") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_rend_v); + STATIC_REQUIRE_FALSE(nt::concepts::const_free_rend); } THEN("it has no free crend") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_crend_v); + STATIC_REQUIRE_FALSE(nt::concepts::free_crend); } } GIVEN("A new_type over an iterable base type not deriving nt::Iterable") { using type_alias = nt::new_type, struct tag>; - static_assert(nt::impl::has_free_begin_v); - static_assert(nt::impl::has_free_begin_v); - static_assert(nt::impl::has_free_cbegin_v); - static_assert(nt::impl::has_free_rbegin_v); - static_assert(nt::impl::has_free_rbegin_v); - static_assert(nt::impl::has_free_crbegin_v); - static_assert(nt::impl::has_free_end_v); - static_assert(nt::impl::has_free_end_v); - static_assert(nt::impl::has_free_cend_v); - static_assert(nt::impl::has_free_rend_v); - static_assert(nt::impl::has_free_rend_v); - static_assert(nt::impl::has_free_crend_v); + static_assert(nt::concepts::free_begin); + static_assert(nt::concepts::const_free_begin); + static_assert(nt::concepts::free_cbegin); + static_assert(nt::concepts::free_rbegin); + static_assert(nt::concepts::const_free_rbegin); + static_assert(nt::concepts::free_crbegin); + static_assert(nt::concepts::free_end); + static_assert(nt::concepts::const_free_end); + static_assert(nt::concepts::free_cend); + static_assert(nt::concepts::free_rend); + static_assert(nt::concepts::const_free_rend); + static_assert(nt::concepts::free_crend); THEN("it has no free begin") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_begin_v); + STATIC_REQUIRE_FALSE(nt::concepts::free_begin); } THEN("it has no free constant begin") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_begin_v); + STATIC_REQUIRE_FALSE(nt::concepts::free_begin); } THEN("it has no free cbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_cbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::free_cbegin); } THEN("it has no free rbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_rbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::free_rbegin); } THEN("it has no free constant rbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_rbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::free_rbegin); } THEN("it has no free crbegin") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_crbegin_v); + STATIC_REQUIRE_FALSE(nt::concepts::free_crbegin); } THEN("it has no free end") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_end_v); + STATIC_REQUIRE_FALSE(nt::concepts::free_end); } THEN("it has no free constant end") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_end_v); + STATIC_REQUIRE_FALSE(nt::concepts::free_end); } THEN("it has no free cend") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_cend_v); + STATIC_REQUIRE_FALSE(nt::concepts::free_cend); } THEN("it has no free rend") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_rend_v); + STATIC_REQUIRE_FALSE(nt::concepts::free_rend); } THEN("it has no free constant rend") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_rend_v); + STATIC_REQUIRE_FALSE(nt::concepts::free_rend); } THEN("it has no free crend") { - STATIC_REQUIRE_FALSE(nt::impl::has_free_crend_v); + STATIC_REQUIRE_FALSE(nt::concepts::free_crend); } } GIVEN("A new_type over an iterable base type deriving nt::Iterable") { using type_alias = nt::new_type, struct tag, deriving(nt::Iterable)>; - static_assert(nt::impl::has_free_begin_v); - static_assert(nt::impl::has_free_begin_v); - static_assert(nt::impl::has_free_cbegin_v); - static_assert(nt::impl::has_free_rbegin_v); - static_assert(nt::impl::has_free_rbegin_v); - static_assert(nt::impl::has_free_crbegin_v); - static_assert(nt::impl::has_free_end_v); - static_assert(nt::impl::has_free_end_v); - static_assert(nt::impl::has_free_cend_v); - static_assert(nt::impl::has_free_rend_v); - static_assert(nt::impl::has_free_rend_v); - static_assert(nt::impl::has_free_crend_v); + static_assert(nt::concepts::free_begin); + static_assert(nt::concepts::const_free_begin); + static_assert(nt::concepts::free_cbegin); + static_assert(nt::concepts::free_rbegin); + static_assert(nt::concepts::const_free_rbegin); + static_assert(nt::concepts::free_crbegin); + static_assert(nt::concepts::free_end); + static_assert(nt::concepts::const_free_end); + static_assert(nt::concepts::free_cend); + static_assert(nt::concepts::free_rend); + static_assert(nt::concepts::const_free_rend); + static_assert(nt::concepts::free_crend); THEN("it has free begin") { - STATIC_REQUIRE(nt::impl::has_free_begin_v); + STATIC_REQUIRE(nt::concepts::free_begin); } THEN("it has free constant begin") { - STATIC_REQUIRE(nt::impl::has_free_begin_v); + STATIC_REQUIRE(nt::concepts::const_free_begin); } THEN("it has free cbegin") { - STATIC_REQUIRE(nt::impl::has_free_cbegin_v); + STATIC_REQUIRE(nt::concepts::free_cbegin); } THEN("it has free rbegin") { - STATIC_REQUIRE(nt::impl::has_free_rbegin_v); + STATIC_REQUIRE(nt::concepts::free_rbegin); } THEN("it has free constant rbegin") { - STATIC_REQUIRE(nt::impl::has_free_rbegin_v); + STATIC_REQUIRE(nt::concepts::const_free_rbegin); } THEN("it has free crbegin") { - STATIC_REQUIRE(nt::impl::has_free_crbegin_v); + STATIC_REQUIRE(nt::concepts::free_crbegin); } THEN("it has free end") { - STATIC_REQUIRE(nt::impl::has_free_end_v); + STATIC_REQUIRE(nt::concepts::free_end); } THEN("it has free constant end") { - STATIC_REQUIRE(nt::impl::has_free_end_v); + STATIC_REQUIRE(nt::concepts::const_free_end); } THEN("it has free cend") { - STATIC_REQUIRE(nt::impl::has_free_cend_v); + STATIC_REQUIRE(nt::concepts::free_cend); } THEN("it has free rend") { - STATIC_REQUIRE(nt::impl::has_free_rend_v); + STATIC_REQUIRE(nt::concepts::free_rend); } THEN("it has free constant rend") { - STATIC_REQUIRE(nt::impl::has_free_rend_v); + STATIC_REQUIRE(nt::concepts::const_free_rend); } THEN("it has free crend") { - STATIC_REQUIRE(nt::impl::has_free_crend_v); + STATIC_REQUIRE(nt::concepts::free_crend); } } } -- cgit v1.2.3 From 306982e16c4191604840e33b20db9479de977bbb Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 9 Jun 2023 11:30:03 +0200 Subject: concepts: replace compound arithmetic traits --- source/lib/include/newtype/concepts.hpp | 63 ++++++++++ .../newtype/impl/type_traits_extensions.hpp | 129 --------------------- source/lib/include/newtype/newtype.hpp | 63 +++++----- source/tests/src/arithmetic.cpp | 1 - source/tests/src/hash.cpp | 1 - source/tests/src/iterable.cpp | 1 - 6 files changed, 91 insertions(+), 167 deletions(-) delete mode 100644 source/lib/include/newtype/impl/type_traits_extensions.hpp (limited to 'source') diff --git a/source/lib/include/newtype/concepts.hpp b/source/lib/include/newtype/concepts.hpp index fc625ed..88313b9 100644 --- a/source/lib/include/newtype/concepts.hpp +++ b/source/lib/include/newtype/concepts.hpp @@ -169,6 +169,69 @@ namespace nt::concepts } // namespace comparability + inline namespace compound_arithmetic + { + template + concept compound_addable = requires(SubjectType & lhs, SubjectType const & rhs) { + { + lhs += rhs + } -> std::convertible_to; + }; + + template + concept nothrow_compound_addable = requires(SubjectType & lhs, SubjectType const & rhs) { + requires compound_addable; + { + lhs += rhs + } noexcept; + }; + + template + concept compound_divisible = requires(SubjectType & lhs, SubjectType const & rhs) { + { + lhs /= rhs + } -> std::convertible_to; + }; + + template + concept nothrow_compound_divisible = requires(SubjectType & lhs, SubjectType const & rhs) { + requires compound_divisible; + { + lhs /= rhs + } noexcept; + }; + + template + concept compound_multipliable = requires(SubjectType & lhs, SubjectType const & rhs) { + { + lhs *= rhs + } -> std::convertible_to; + }; + + template + concept nothrow_compound_multipliable = requires(SubjectType & lhs, SubjectType const & rhs) { + requires compound_multipliable; + { + lhs *= rhs + } noexcept; + }; + + template + concept compound_subtractable = requires(SubjectType & lhs, SubjectType const & rhs) { + { + lhs -= rhs + } -> std::convertible_to; + }; + + template + concept nothrow_compound_subtractable = requires(SubjectType & lhs, SubjectType const & rhs) { + requires compound_subtractable; + { + lhs -= rhs + } noexcept; + }; + } // namespace compound_arithmetic + inline namespace iostreamable { diff --git a/source/lib/include/newtype/impl/type_traits_extensions.hpp b/source/lib/include/newtype/impl/type_traits_extensions.hpp deleted file mode 100644 index dd25905..0000000 --- a/source/lib/include/newtype/impl/type_traits_extensions.hpp +++ /dev/null @@ -1,129 +0,0 @@ -#ifndef NEWTYPE_IMPL_TYPE_TRAITS_EXTENSIONS_HPP -#define NEWTYPE_IMPL_TYPE_TRAITS_EXTENSIONS_HPP - -#include "newtype/version.hpp" - -#include -#include -#include -#include - -namespace nt::impl -{ - - inline namespace compound_arithmetic - { - - template - struct is_add_assignable : std::false_type - { - }; - - template - struct is_add_assignable() += std::declval())>> : std::true_type - { - }; - - template - auto constexpr is_add_assignable_v = is_add_assignable::value; - - template - struct is_nothrow_add_assignable : std::false_type - { - }; - - template - struct is_nothrow_add_assignable() += std::declval())>> - : std::bool_constant() += std::declval())> - { - }; - - template - auto constexpr is_nothrow_add_assignable_v = is_nothrow_add_assignable::value; - - template - struct is_subtract_assignable : std::false_type - { - }; - - template - struct is_subtract_assignable() -= std::declval())>> : std::true_type - { - }; - - template - auto constexpr is_subtract_assignable_v = is_subtract_assignable::value; - - template - struct is_nothrow_subtract_assignable : std::false_type - { - }; - - template - struct is_nothrow_subtract_assignable() -= std::declval())>> - : std::bool_constant() -= std::declval())> - { - }; - - template - auto constexpr is_nothrow_subtract_assignable_v = is_nothrow_subtract_assignable::value; - - template - struct is_multiply_assignable : std::false_type - { - }; - - template - struct is_multiply_assignable() *= std::declval())>> : std::true_type - { - }; - - template - auto constexpr is_multiply_assignable_v = is_multiply_assignable::value; - - template - struct is_nothrow_multiply_assignable : std::false_type - { - }; - - template - struct is_nothrow_multiply_assignable() *= std::declval())>> - : std::bool_constant() *= std::declval())> - { - }; - - template - auto constexpr is_nothrow_multiply_assignable_v = is_nothrow_multiply_assignable::value; - - template - struct is_divide_assignable : std::false_type - { - }; - - template - struct is_divide_assignable() /= std::declval())>> : std::true_type - { - }; - - template - auto constexpr is_divide_assignable_v = is_divide_assignable::value; - - template - struct is_nothrow_divide_assignable : std::false_type - { - }; - - template - struct is_nothrow_divide_assignable() /= std::declval())>> - : std::bool_constant() /= std::declval())> - { - }; - - template - auto constexpr is_nothrow_divide_assignable_v = is_nothrow_divide_assignable::value; - - } // namespace compound_arithmetic - -} // namespace nt::impl - -#endif \ No newline at end of file diff --git a/source/lib/include/newtype/newtype.hpp b/source/lib/include/newtype/newtype.hpp index b5eca97..824a3da 100644 --- a/source/lib/include/newtype/newtype.hpp +++ b/source/lib/include/newtype/newtype.hpp @@ -6,7 +6,6 @@ #include "newtype/deriving.hpp" #include "newtype/impl/new_type_iterator_types.hpp" #include "newtype/impl/new_type_storage.hpp" -#include "newtype/impl/type_traits_extensions.hpp" #include "newtype/version.hpp" #include @@ -33,33 +32,29 @@ namespace nt auto friend operator>>(std::basic_istream &, new_type &) noexcept( nt::concepts::nothrow_input_streamable) -> std::basic_istream &; - template + template auto DerivationClauseV> auto constexpr friend operator+=(new_type & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_add_assignable_v) - -> std::enable_if_t, - new_type &>; + new_type const & rhs) noexcept(nt::concepts::nothrow_compound_addable) + -> new_type &; - template + template auto DerivationClauseV> auto constexpr friend operator-=(new_type & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_subtract_assignable_v) - -> std::enable_if_t, - new_type &>; + new_type const & rhs) noexcept(nt::concepts::nothrow_compound_subtractable) + -> new_type &; - template + template auto DerivationClauseV> auto constexpr friend operator*=(new_type & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_multiply_assignable_v) - -> std::enable_if_t, - new_type &>; + new_type const & rhs) noexcept(nt::concepts::nothrow_compound_multipliable) + -> new_type &; - template + template auto DerivationClauseV> auto constexpr friend operator/=(new_type & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_divide_assignable_v) - -> std::enable_if_t, - new_type &>; + new_type const & rhs) noexcept(nt::concepts::nothrow_compound_divisible) + -> new_type &; template auto DerivationClauseV> auto constexpr friend begin(new_type & obj) -> @@ -338,11 +333,11 @@ namespace nt return {lhs.decay() + rhs.decay()}; } - template - auto constexpr operator+=(new_type & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_add_assignable_v) - -> std::enable_if_t, - new_type &> + template auto DerivationClause> + auto constexpr + operator+=(new_type & lhs, + new_type const & rhs) noexcept(nt::concepts::nothrow_compound_addable) + -> new_type & { lhs.m_value += rhs.m_value; return lhs; @@ -357,12 +352,11 @@ namespace nt return {lhs.decay() - rhs.decay()}; } - template + template auto DerivationClause> auto constexpr operator-=(new_type & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_subtract_assignable_v) - -> std::enable_if_t, - new_type &> + new_type const & rhs) noexcept(nt::concepts::nothrow_compound_subtractable) + -> new_type & { lhs.m_value -= rhs.m_value; return lhs; @@ -377,12 +371,11 @@ namespace nt return {lhs.decay() * rhs.decay()}; } - template + template auto DerivationClause> auto constexpr operator*=(new_type & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_multiply_assignable_v) - -> std::enable_if_t, - new_type &> + new_type const & rhs) noexcept(nt::concepts::nothrow_compound_multipliable) + -> new_type & { lhs.m_value *= rhs.m_value; return lhs; @@ -397,11 +390,11 @@ namespace nt return {lhs.decay() / rhs.decay()}; } - template - auto constexpr operator/=(new_type & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_divide_assignable_v) - -> std::enable_if_t, - new_type &> + template auto DerivationClause> + auto constexpr + operator/=(new_type & lhs, + new_type const & rhs) noexcept(nt::concepts::nothrow_compound_divisible) + -> new_type & { lhs.m_value /= rhs.m_value; return lhs; diff --git a/source/tests/src/arithmetic.cpp b/source/tests/src/arithmetic.cpp index 647e600..8161f0c 100644 --- a/source/tests/src/arithmetic.cpp +++ b/source/tests/src/arithmetic.cpp @@ -1,6 +1,5 @@ #include "newtype/derivable.hpp" #include "newtype/deriving.hpp" -#include "newtype/impl/type_traits_extensions.hpp" #include "newtype/newtype.hpp" #include diff --git a/source/tests/src/hash.cpp b/source/tests/src/hash.cpp index bcf793c..9bf6862 100644 --- a/source/tests/src/hash.cpp +++ b/source/tests/src/hash.cpp @@ -1,7 +1,6 @@ #include "newtype/concepts.hpp" #include "newtype/derivable.hpp" #include "newtype/deriving.hpp" -#include "newtype/impl/type_traits_extensions.hpp" #include "newtype/newtype.hpp" #include diff --git a/source/tests/src/iterable.cpp b/source/tests/src/iterable.cpp index ba91500..bc862cc 100644 --- a/source/tests/src/iterable.cpp +++ b/source/tests/src/iterable.cpp @@ -1,6 +1,5 @@ #include "newtype/derivable.hpp" #include "newtype/deriving.hpp" -#include "newtype/impl/type_traits_extensions.hpp" #include "newtype/newtype.hpp" #include -- cgit v1.2.3