diff options
| author | Felix Morgner <felix.morgner@gmail.com> | 2023-06-08 18:09:00 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@gmail.com> | 2023-06-08 18:09:00 +0200 |
| commit | bc83f6dd1330b6b9cb39c8600242d17ff964de36 (patch) | |
| tree | 01285817cc8d4c7d7b891d24bdb3ddbeba67c163 | |
| parent | b55156bed4a56b2e9af46e0d17adc092ac16342e (diff) | |
| download | newtype-bc83f6dd1330b6b9cb39c8600242d17ff964de36.tar.xz newtype-bc83f6dd1330b6b9cb39c8600242d17ff964de36.zip | |
concepts: replace arithmetic traits
| -rw-r--r-- | source/lib/include/newtype/concepts.hpp | 65 | ||||
| -rw-r--r-- | source/lib/include/newtype/impl/type_traits_extensions.hpp | 113 | ||||
| -rw-r--r-- | source/lib/include/newtype/newtype.hpp | 24 | ||||
| -rw-r--r-- | source/tests/src/arithmetic.cpp | 32 |
4 files changed, 93 insertions, 141 deletions
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<typename SubjectType> + concept addable = requires(SubjectType lhs, SubjectType rhs) { + { + lhs + rhs + } -> std::same_as<SubjectType>; + }; + + template<typename SubjectType> + concept nothrow_addable = requires(SubjectType lhs, SubjectType rhs) { + requires addable<SubjectType>; + { + lhs + rhs + } noexcept; + }; + + template<typename SubjectType> + concept divisible = requires(SubjectType lhs, SubjectType rhs) { + { + lhs / rhs + } -> std::same_as<SubjectType>; + }; + + template<typename SubjectType> + concept nothrow_divisible = requires(SubjectType lhs, SubjectType rhs) { + requires divisible<SubjectType>; + { + lhs / rhs + } noexcept; + }; + + template<typename SubjectType> + concept multipliable = requires(SubjectType lhs, SubjectType rhs) { + { + lhs * rhs + } -> std::same_as<SubjectType>; + }; + + template<typename SubjectType> + concept nothrow_multipliable = requires(SubjectType lhs, SubjectType rhs) { + requires multipliable<SubjectType>; + { + lhs / rhs + } noexcept; + }; + + template<typename SubjectType> + concept subtractable = requires(SubjectType lhs, SubjectType rhs) { + { + lhs - rhs + } -> std::same_as<SubjectType>; + }; + + template<typename SubjectType> + concept nothrow_subtractable = requires(SubjectType lhs, SubjectType rhs) { + requires subtractable<SubjectType>; + { + 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<typename T, typename = void> - struct is_addable : std::false_type - { - }; - - template<typename T> - struct is_addable<T, std::void_t<decltype(std::declval<T const &>() + std::declval<T const &>())>> : std::true_type - { - }; - - template<typename T> - auto constexpr is_addable_v = is_addable<T>::value; - - template<typename T, typename = void> - struct is_nothrow_addable : std::false_type - { - }; - - template<typename T> - struct is_nothrow_addable<T, std::void_t<decltype(std::declval<T const &>() + std::declval<T const &>())>> - : std::bool_constant<noexcept(std::declval<T const &>() + std::declval<T const &>())> - { - }; - - template<typename T> - auto constexpr is_nothrow_addable_v = is_nothrow_addable<T>::value; - - template<typename T, typename = void> - struct is_subtractable : std::false_type - { - }; - - template<typename T> - struct is_subtractable<T, std::void_t<decltype(std::declval<T const &>() - std::declval<T const &>())>> : std::true_type - { - }; - - template<typename T> - auto constexpr is_subtractable_v = is_subtractable<T>::value; - - template<typename T, typename = void> - struct is_nothrow_subtractable : std::false_type - { - }; - - template<typename T> - struct is_nothrow_subtractable<T, std::void_t<decltype(std::declval<T const &>() - std::declval<T const &>())>> - : std::bool_constant<noexcept(std::declval<T const &>() - std::declval<T const &>())> - { - }; - - template<typename T> - auto constexpr is_nothrow_subtractable_v = is_nothrow_subtractable<T>::value; - - template<typename T, typename = void> - struct is_multipliable : std::false_type - { - }; - - template<typename T> - struct is_multipliable<T, std::void_t<decltype(std::declval<T const &>() * std::declval<T const &>())>> : std::true_type - { - }; - - template<typename T> - auto constexpr is_multipliable_v = is_multipliable<T>::value; - - template<typename T, typename = void> - struct is_nothrow_multipliable : std::false_type - { - }; - - template<typename T> - struct is_nothrow_multipliable<T, std::void_t<decltype(std::declval<T const &>() * std::declval<T const &>())>> - : std::bool_constant<noexcept(std::declval<T const &>() * std::declval<T const &>())> - { - }; - - template<typename T> - auto constexpr is_nothrow_multipliable_v = is_nothrow_multipliable<T>::value; - - template<typename T, typename = void> - struct is_dividable : std::false_type - { - }; - - template<typename T> - struct is_dividable<T, std::void_t<decltype(std::declval<T const &>() / std::declval<T const &>())>> : std::true_type - { - }; - - template<typename T> - auto constexpr is_dividable_v = is_dividable<T>::value; - - template<typename T, typename = void> - struct is_nothrow_dividable : std::false_type - { - }; - - template<typename T> - struct is_nothrow_dividable<T, std::void_t<decltype(std::declval<T const &>() / std::declval<T const &>())>> - : std::bool_constant<noexcept(std::declval<T const &>() / std::declval<T const &>())> - { - }; - - template<typename T> - auto constexpr is_nothrow_dividable_v = is_nothrow_dividable<T>::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<typename BaseType, typename TagType, auto DerivationClause> + template<nt::concepts::addable BaseType, typename TagType, nt::contains<nt::Arithmetic> auto DerivationClause> auto constexpr operator+(new_type<BaseType, TagType, DerivationClause> const & lhs, new_type<BaseType, TagType, DerivationClause> const & rhs) noexcept( - impl::is_nothrow_addable_v<BaseType> && std::is_nothrow_copy_constructible_v<BaseType>) - -> std::enable_if_t<DerivationClause(nt::Arithmetic) && impl::is_addable_v<BaseType>, new_type<BaseType, TagType, DerivationClause>> + nt::concepts::nothrow_addable<BaseType> && std::is_nothrow_copy_constructible_v<BaseType>) + -> new_type<BaseType, TagType, DerivationClause> { return {lhs.decay() + rhs.decay()}; } @@ -372,11 +372,11 @@ namespace nt return lhs; } - template<typename BaseType, typename TagType, auto DerivationClause> + template<nt::concepts::subtractable BaseType, typename TagType, nt::contains<nt::Arithmetic> auto DerivationClause> auto constexpr operator-(new_type<BaseType, TagType, DerivationClause> const & lhs, new_type<BaseType, TagType, DerivationClause> const & rhs) noexcept( - impl::is_nothrow_subtractable_v<BaseType> && std::is_nothrow_copy_constructible_v<BaseType>) - -> std::enable_if_t<DerivationClause(nt::Arithmetic) && impl::is_subtractable_v<BaseType>, new_type<BaseType, TagType, DerivationClause>> + nt::concepts::nothrow_subtractable<BaseType> && std::is_nothrow_copy_constructible_v<BaseType>) + -> new_type<BaseType, TagType, DerivationClause> { return {lhs.decay() - rhs.decay()}; } @@ -392,11 +392,11 @@ namespace nt return lhs; } - template<typename BaseType, typename TagType, auto DerivationClause> + template<nt::concepts::multipliable BaseType, typename TagType, nt::contains<nt::Arithmetic> auto DerivationClause> auto constexpr operator*(new_type<BaseType, TagType, DerivationClause> const & lhs, new_type<BaseType, TagType, DerivationClause> const & rhs) noexcept( - impl::is_nothrow_multipliable_v<BaseType> && std::is_nothrow_copy_constructible_v<BaseType>) - -> std::enable_if_t<DerivationClause(nt::Arithmetic) && impl::is_multipliable_v<BaseType>, new_type<BaseType, TagType, DerivationClause>> + nt::concepts::nothrow_multipliable<BaseType> && std::is_nothrow_copy_constructible_v<BaseType>) + -> new_type<BaseType, TagType, DerivationClause> { return {lhs.decay() * rhs.decay()}; } @@ -412,11 +412,11 @@ namespace nt return lhs; } - template<typename BaseType, typename TagType, auto DerivationClause> + template<nt::concepts::divisible BaseType, typename TagType, nt::contains<nt::Arithmetic> auto DerivationClause> auto constexpr operator/(new_type<BaseType, TagType, DerivationClause> const & lhs, new_type<BaseType, TagType, DerivationClause> const & rhs) noexcept( - impl::is_nothrow_dividable_v<BaseType> && std::is_nothrow_copy_constructible_v<BaseType>) - -> std::enable_if_t<DerivationClause(nt::Arithmetic) && impl::is_dividable_v<BaseType>, new_type<BaseType, TagType, DerivationClause>> + nt::concepts::nothrow_divisible<BaseType> && std::is_nothrow_copy_constructible_v<BaseType>) + -> new_type<BaseType, TagType, DerivationClause> { 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<type_alias>); + STATIC_REQUIRE(!nt::concepts::addable<type_alias>); } } @@ -33,7 +33,7 @@ SCENARIO("Addition", "[arithmetic]") THEN("it is addable") { - STATIC_REQUIRE(nt::impl::is_addable_v<type_alias>); + STATIC_REQUIRE(nt::concepts::addable<type_alias>); } } @@ -43,7 +43,7 @@ SCENARIO("Addition", "[arithmetic]") THEN("it is not addable") { - STATIC_REQUIRE(!nt::impl::is_addable_v<addable_type> == nt::impl::is_addable_v<type_alias>); + STATIC_REQUIRE(!nt::concepts::addable<addable_type> == nt::concepts::addable<type_alias>); } } @@ -53,7 +53,7 @@ SCENARIO("Addition", "[arithmetic]") THEN("it is addable") { - STATIC_REQUIRE(nt::impl::is_addable_v<addable_type> == nt::impl::is_addable_v<type_alias>); + STATIC_REQUIRE(nt::concepts::addable<addable_type> == nt::concepts::addable<type_alias>); } } @@ -96,7 +96,7 @@ SCENARIO("Subtraction", "[arithmetic]") THEN("it is not subtractable") { - STATIC_REQUIRE(!nt::impl::is_subtractable_v<type_alias>); + STATIC_REQUIRE(!nt::concepts::subtractable<type_alias>); } } @@ -106,7 +106,7 @@ SCENARIO("Subtraction", "[arithmetic]") THEN("it is subtractable") { - STATIC_REQUIRE(nt::impl::is_subtractable_v<type_alias>); + STATIC_REQUIRE(nt::concepts::subtractable<type_alias>); } } @@ -116,7 +116,7 @@ SCENARIO("Subtraction", "[arithmetic]") THEN("it is not addable") { - STATIC_REQUIRE(!nt::impl::is_subtractable_v<type_alias>); + STATIC_REQUIRE(!nt::concepts::subtractable<type_alias>); } } @@ -126,7 +126,7 @@ SCENARIO("Subtraction", "[arithmetic]") THEN("it is subtractable") { - STATIC_REQUIRE(nt::impl::is_subtractable_v<type_alias>); + STATIC_REQUIRE(nt::concepts::subtractable<type_alias>); } } @@ -169,7 +169,7 @@ SCENARIO("Multiplication", "[arithmetic]") THEN("it is not multipliable") { - STATIC_REQUIRE(!nt::impl::is_multipliable_v<type_alias>); + STATIC_REQUIRE(!nt::concepts::multipliable<type_alias>); } } @@ -179,7 +179,7 @@ SCENARIO("Multiplication", "[arithmetic]") THEN("it is multipliable") { - STATIC_REQUIRE(nt::impl::is_multipliable_v<type_alias>); + STATIC_REQUIRE(nt::concepts::multipliable<type_alias>); } } @@ -189,7 +189,7 @@ SCENARIO("Multiplication", "[arithmetic]") THEN("it is not multipliable") { - STATIC_REQUIRE(!nt::impl::is_multipliable_v<type_alias>); + STATIC_REQUIRE(!nt::concepts::multipliable<type_alias>); } } @@ -199,7 +199,7 @@ SCENARIO("Multiplication", "[arithmetic]") THEN("it is multipliable") { - STATIC_REQUIRE(nt::impl::is_multipliable_v<type_alias>); + STATIC_REQUIRE(nt::concepts::multipliable<type_alias>); } } @@ -242,7 +242,7 @@ SCENARIO("Division", "[arithmetic]") THEN("it is not divisible") { - STATIC_REQUIRE(!nt::impl::is_dividable_v<type_alias>); + STATIC_REQUIRE(!nt::concepts::divisible<type_alias>); } } @@ -252,7 +252,7 @@ SCENARIO("Division", "[arithmetic]") THEN("it is divisible") { - STATIC_REQUIRE(nt::impl::is_dividable_v<type_alias>); + STATIC_REQUIRE(nt::concepts::divisible<type_alias>); } } @@ -262,7 +262,7 @@ SCENARIO("Division", "[arithmetic]") THEN("it is not divisible") { - STATIC_REQUIRE(!nt::impl::is_dividable_v<type_alias>); + STATIC_REQUIRE(!nt::concepts::divisible<type_alias>); } } @@ -272,7 +272,7 @@ SCENARIO("Division", "[arithmetic]") THEN("it is divisible") { - STATIC_REQUIRE(nt::impl::is_dividable_v<type_alias>); + STATIC_REQUIRE(nt::concepts::divisible<type_alias>); } } |
