aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/lib/include/newtype/concepts.hpp65
-rw-r--r--source/lib/include/newtype/impl/type_traits_extensions.hpp113
-rw-r--r--source/lib/include/newtype/newtype.hpp24
-rw-r--r--source/tests/src/arithmetic.cpp32
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>);
}
}