diff options
| -rw-r--r-- | source/lib/include/newtype/concepts.hpp | 63 | ||||
| -rw-r--r-- | source/lib/include/newtype/impl/type_traits_extensions.hpp | 129 | ||||
| -rw-r--r-- | source/lib/include/newtype/newtype.hpp | 63 | ||||
| -rw-r--r-- | source/tests/src/arithmetic.cpp | 1 | ||||
| -rw-r--r-- | source/tests/src/hash.cpp | 1 | ||||
| -rw-r--r-- | source/tests/src/iterable.cpp | 1 |
6 files changed, 91 insertions, 167 deletions
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<typename SubjectType> + concept compound_addable = requires(SubjectType & lhs, SubjectType const & rhs) { + { + lhs += rhs + } -> std::convertible_to<SubjectType &>; + }; + + template<typename SubjectType> + concept nothrow_compound_addable = requires(SubjectType & lhs, SubjectType const & rhs) { + requires compound_addable<SubjectType>; + { + lhs += rhs + } noexcept; + }; + + template<typename SubjectType> + concept compound_divisible = requires(SubjectType & lhs, SubjectType const & rhs) { + { + lhs /= rhs + } -> std::convertible_to<SubjectType &>; + }; + + template<typename SubjectType> + concept nothrow_compound_divisible = requires(SubjectType & lhs, SubjectType const & rhs) { + requires compound_divisible<SubjectType>; + { + lhs /= rhs + } noexcept; + }; + + template<typename SubjectType> + concept compound_multipliable = requires(SubjectType & lhs, SubjectType const & rhs) { + { + lhs *= rhs + } -> std::convertible_to<SubjectType &>; + }; + + template<typename SubjectType> + concept nothrow_compound_multipliable = requires(SubjectType & lhs, SubjectType const & rhs) { + requires compound_multipliable<SubjectType>; + { + lhs *= rhs + } noexcept; + }; + + template<typename SubjectType> + concept compound_subtractable = requires(SubjectType & lhs, SubjectType const & rhs) { + { + lhs -= rhs + } -> std::convertible_to<SubjectType &>; + }; + + template<typename SubjectType> + concept nothrow_compound_subtractable = requires(SubjectType & lhs, SubjectType const & rhs) { + requires compound_subtractable<SubjectType>; + { + 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 <cstddef> -#include <functional> -#include <iosfwd> -#include <type_traits> - -namespace nt::impl -{ - - inline namespace compound_arithmetic - { - - template<typename T, typename = void> - struct is_add_assignable : std::false_type - { - }; - - template<typename T> - struct is_add_assignable<T, std::void_t<decltype(std::declval<T &>() += std::declval<T const &>())>> : std::true_type - { - }; - - template<typename T> - auto constexpr is_add_assignable_v = is_add_assignable<T>::value; - - template<typename T, typename = void> - struct is_nothrow_add_assignable : std::false_type - { - }; - - template<typename T> - struct is_nothrow_add_assignable<T, std::void_t<decltype(std::declval<T &>() += std::declval<T const &>())>> - : std::bool_constant<noexcept(std::declval<T &>() += std::declval<T const &>())> - { - }; - - template<typename T> - auto constexpr is_nothrow_add_assignable_v = is_nothrow_add_assignable<T>::value; - - template<typename T, typename = void> - struct is_subtract_assignable : std::false_type - { - }; - - template<typename T> - struct is_subtract_assignable<T, std::void_t<decltype(std::declval<T &>() -= std::declval<T const &>())>> : std::true_type - { - }; - - template<typename T> - auto constexpr is_subtract_assignable_v = is_subtract_assignable<T>::value; - - template<typename T, typename = void> - struct is_nothrow_subtract_assignable : std::false_type - { - }; - - template<typename T> - struct is_nothrow_subtract_assignable<T, std::void_t<decltype(std::declval<T &>() -= std::declval<T const &>())>> - : std::bool_constant<noexcept(std::declval<T &>() -= std::declval<T const &>())> - { - }; - - template<typename T> - auto constexpr is_nothrow_subtract_assignable_v = is_nothrow_subtract_assignable<T>::value; - - template<typename T, typename = void> - struct is_multiply_assignable : std::false_type - { - }; - - template<typename T> - struct is_multiply_assignable<T, std::void_t<decltype(std::declval<T &>() *= std::declval<T const &>())>> : std::true_type - { - }; - - template<typename T> - auto constexpr is_multiply_assignable_v = is_multiply_assignable<T>::value; - - template<typename T, typename = void> - struct is_nothrow_multiply_assignable : std::false_type - { - }; - - template<typename T> - struct is_nothrow_multiply_assignable<T, std::void_t<decltype(std::declval<T &>() *= std::declval<T const &>())>> - : std::bool_constant<noexcept(std::declval<T &>() *= std::declval<T const &>())> - { - }; - - template<typename T> - auto constexpr is_nothrow_multiply_assignable_v = is_nothrow_multiply_assignable<T>::value; - - template<typename T, typename = void> - struct is_divide_assignable : std::false_type - { - }; - - template<typename T> - struct is_divide_assignable<T, std::void_t<decltype(std::declval<T &>() /= std::declval<T const &>())>> : std::true_type - { - }; - - template<typename T> - auto constexpr is_divide_assignable_v = is_divide_assignable<T>::value; - - template<typename T, typename = void> - struct is_nothrow_divide_assignable : std::false_type - { - }; - - template<typename T> - struct is_nothrow_divide_assignable<T, std::void_t<decltype(std::declval<T &>() /= std::declval<T const &>())>> - : std::bool_constant<noexcept(std::declval<T &>() /= std::declval<T const &>())> - { - }; - - template<typename T> - auto constexpr is_nothrow_divide_assignable_v = is_nothrow_divide_assignable<T>::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 <functional> @@ -33,33 +32,29 @@ namespace nt auto friend operator>>(std::basic_istream<CharType, StreamTraits> &, new_type<BaseTypeT, TagTypeT, DerivationClauseV> &) noexcept( nt::concepts::nothrow_input_streamable<BaseTypeT, CharType, StreamTraits>) -> std::basic_istream<CharType, StreamTraits> &; - template<typename BaseTypeT, typename TagTypeT, auto DerivationClauseV> + template<nt::concepts::compound_addable BaseTypeT, typename TagTypeT, nt::contains<nt::Arithmetic> auto DerivationClauseV> auto constexpr friend operator+=(new_type<BaseTypeT, TagTypeT, DerivationClauseV> & lhs, - new_type<BaseTypeT, TagTypeT, DerivationClauseV> const & rhs) noexcept(impl::is_nothrow_add_assignable_v<BaseTypeT>) - -> std::enable_if_t<DerivationClauseV(nt::Arithmetic) && impl::is_add_assignable_v<BaseTypeT>, - new_type<BaseTypeT, TagTypeT, DerivationClauseV> &>; + new_type<BaseTypeT, TagTypeT, DerivationClauseV> const & rhs) noexcept(nt::concepts::nothrow_compound_addable<BaseTypeT>) + -> new_type<BaseTypeT, TagTypeT, DerivationClauseV> &; - template<typename BaseTypeT, typename TagTypeT, auto DerivationClauseV> + template<nt::concepts::compound_subtractable BaseTypeT, typename TagTypeT, nt::contains<nt::Arithmetic> auto DerivationClauseV> auto constexpr friend operator-=(new_type<BaseTypeT, TagTypeT, DerivationClauseV> & lhs, - new_type<BaseTypeT, TagTypeT, DerivationClauseV> const & rhs) noexcept(impl::is_nothrow_subtract_assignable_v<BaseTypeT>) - -> std::enable_if_t<DerivationClauseV(nt::Arithmetic) && impl::is_subtract_assignable_v<BaseTypeT>, - new_type<BaseTypeT, TagTypeT, DerivationClauseV> &>; + new_type<BaseTypeT, TagTypeT, DerivationClauseV> const & rhs) noexcept(nt::concepts::nothrow_compound_subtractable<BaseTypeT>) + -> new_type<BaseTypeT, TagTypeT, DerivationClauseV> &; - template<typename BaseTypeT, typename TagTypeT, auto DerivationClauseV> + template<nt::concepts::compound_multipliable BaseTypeT, typename TagTypeT, nt::contains<nt::Arithmetic> auto DerivationClauseV> auto constexpr friend operator*=(new_type<BaseTypeT, TagTypeT, DerivationClauseV> & lhs, - new_type<BaseTypeT, TagTypeT, DerivationClauseV> const & rhs) noexcept(impl::is_nothrow_multiply_assignable_v<BaseTypeT>) - -> std::enable_if_t<DerivationClauseV(nt::Arithmetic) && impl::is_multiply_assignable_v<BaseTypeT>, - new_type<BaseTypeT, TagTypeT, DerivationClauseV> &>; + new_type<BaseTypeT, TagTypeT, DerivationClauseV> const & rhs) noexcept(nt::concepts::nothrow_compound_multipliable<BaseTypeT>) + -> new_type<BaseTypeT, TagTypeT, DerivationClauseV> &; - template<typename BaseTypeT, typename TagTypeT, auto DerivationClauseV> + template<nt::concepts::compound_divisible BaseTypeT, typename TagTypeT, nt::contains<nt::Arithmetic> auto DerivationClauseV> auto constexpr friend operator/=(new_type<BaseTypeT, TagTypeT, DerivationClauseV> & lhs, - new_type<BaseTypeT, TagTypeT, DerivationClauseV> const & rhs) noexcept(impl::is_nothrow_divide_assignable_v<BaseTypeT>) - -> std::enable_if_t<DerivationClauseV(nt::Arithmetic) && impl::is_divide_assignable_v<BaseTypeT>, - new_type<BaseTypeT, TagTypeT, DerivationClauseV> &>; + new_type<BaseTypeT, TagTypeT, DerivationClauseV> const & rhs) noexcept(nt::concepts::nothrow_compound_divisible<BaseTypeT>) + -> new_type<BaseTypeT, TagTypeT, DerivationClauseV> &; template<nt::concepts::free_begin BaseTypeT, typename TagTypeT, nt::contains<nt::Iterable> auto DerivationClauseV> auto constexpr friend begin(new_type<BaseTypeT, TagTypeT, DerivationClauseV> & obj) -> @@ -338,11 +333,11 @@ namespace nt return {lhs.decay() + rhs.decay()}; } - template<typename BaseType, typename TagType, auto DerivationClause> - auto constexpr operator+=(new_type<BaseType, TagType, DerivationClause> & lhs, - new_type<BaseType, TagType, DerivationClause> const & rhs) noexcept(impl::is_nothrow_add_assignable_v<BaseType>) - -> std::enable_if_t<DerivationClause(nt::Arithmetic) && impl::is_add_assignable_v<BaseType>, - new_type<BaseType, TagType, DerivationClause> &> + template<nt::concepts::compound_addable BaseType, typename TagType, nt::contains<nt::Arithmetic> auto DerivationClause> + auto constexpr + operator+=(new_type<BaseType, TagType, DerivationClause> & lhs, + new_type<BaseType, TagType, DerivationClause> const & rhs) noexcept(nt::concepts::nothrow_compound_addable<BaseType>) + -> new_type<BaseType, TagType, DerivationClause> & { lhs.m_value += rhs.m_value; return lhs; @@ -357,12 +352,11 @@ namespace nt return {lhs.decay() - rhs.decay()}; } - template<typename BaseType, typename TagType, auto DerivationClause> + template<nt::concepts::compound_subtractable BaseType, typename TagType, nt::contains<nt::Arithmetic> auto DerivationClause> auto constexpr operator-=(new_type<BaseType, TagType, DerivationClause> & lhs, - new_type<BaseType, TagType, DerivationClause> const & rhs) noexcept(impl::is_nothrow_subtract_assignable_v<BaseType>) - -> std::enable_if_t<DerivationClause(nt::Arithmetic) && impl::is_subtract_assignable_v<BaseType>, - new_type<BaseType, TagType, DerivationClause> &> + new_type<BaseType, TagType, DerivationClause> const & rhs) noexcept(nt::concepts::nothrow_compound_subtractable<BaseType>) + -> new_type<BaseType, TagType, DerivationClause> & { lhs.m_value -= rhs.m_value; return lhs; @@ -377,12 +371,11 @@ namespace nt return {lhs.decay() * rhs.decay()}; } - template<typename BaseType, typename TagType, auto DerivationClause> + template<nt::concepts::compound_multipliable BaseType, typename TagType, nt::contains<nt::Arithmetic> auto DerivationClause> auto constexpr operator*=(new_type<BaseType, TagType, DerivationClause> & lhs, - new_type<BaseType, TagType, DerivationClause> const & rhs) noexcept(impl::is_nothrow_multiply_assignable_v<BaseType>) - -> std::enable_if_t<DerivationClause(nt::Arithmetic) && impl::is_multiply_assignable_v<BaseType>, - new_type<BaseType, TagType, DerivationClause> &> + new_type<BaseType, TagType, DerivationClause> const & rhs) noexcept(nt::concepts::nothrow_compound_multipliable<BaseType>) + -> new_type<BaseType, TagType, DerivationClause> & { lhs.m_value *= rhs.m_value; return lhs; @@ -397,11 +390,11 @@ namespace nt return {lhs.decay() / rhs.decay()}; } - template<typename BaseType, typename TagType, auto DerivationClause> - auto constexpr operator/=(new_type<BaseType, TagType, DerivationClause> & lhs, - new_type<BaseType, TagType, DerivationClause> const & rhs) noexcept(impl::is_nothrow_divide_assignable_v<BaseType>) - -> std::enable_if_t<DerivationClause(nt::Arithmetic) && impl::is_divide_assignable_v<BaseType>, - new_type<BaseType, TagType, DerivationClause> &> + template<nt::concepts::compound_divisible BaseType, typename TagType, nt::contains<nt::Arithmetic> auto DerivationClause> + auto constexpr + operator/=(new_type<BaseType, TagType, DerivationClause> & lhs, + new_type<BaseType, TagType, DerivationClause> const & rhs) noexcept(nt::concepts::nothrow_compound_divisible<BaseType>) + -> new_type<BaseType, TagType, DerivationClause> & { 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 <catch2/catch_test_macros.hpp> 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 <catch2/catch_template_test_macros.hpp> 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 <catch2/catch_test_macros.hpp> |
