diff options
| -rw-r--r-- | include/newtype/derivable.hpp | 63 | ||||
| -rw-r--r-- | include/newtype/derivation_clause.hpp | 45 | ||||
| -rw-r--r-- | include/newtype/deriving.hpp | 3 | ||||
| -rw-r--r-- | include/newtype/impl/type_traits_extensions.hpp | 563 | ||||
| -rw-r--r-- | include/newtype/new_type.hpp | 149 |
5 files changed, 0 insertions, 823 deletions
diff --git a/include/newtype/derivable.hpp b/include/newtype/derivable.hpp index faa844d..c798c59 100644 --- a/include/newtype/derivable.hpp +++ b/include/newtype/derivable.hpp @@ -12,80 +12,17 @@ namespace nt using tag_type = DerivableTag; }; - /** - * @brief A set of standard derivation tags - * - * This convenience namespace contains all standard derivation tags. - * - * @since 1.0.0 - */ inline namespace derivables { - /** - * @brief A tag to enable derivation of arithmetic operators - * - * @since 1.0.0 - */ auto constexpr Arithmetic = derivable<struct arithmetic_tag>{}; - - /** - * @brief A tag to enable derivation of "equality comparison with base type" operators - * - * @note Deriving this feature seriously weakens the using nt::new_type instance - * @since 1.0.0 - */ auto constexpr EqBase = derivable<struct eq_base_tag>{}; - - /** - * @brief A tag to enable derivation of a specialization of std::hash - * - * @since 1.0.0 - */ auto constexpr Hash = derivable<struct hash_tag>{}; - - /** - * @brief A tag to enable derivation of the implicit "conversion to base type" operator - * - * @note If this tag is not present in the derivation clause of any given nt::new_type, the type instance only supports explicit - * "conversion to base type" - * @since 1.0.0 - */ auto constexpr ImplicitConversion = derivable<struct implicit_conversion_tag>{}; - - /** - * @brief A tag to enable access to the members of the base type object through a pointer - * - * @since 1.0.0 - */ auto constexpr Indirection = derivable<struct indirection_tag>{}; - - /** - * @brief A tag to enable derivation of the iterator accessors - * - * @since 1.0.0 - */ auto constexpr Iterable = derivable<struct iterable_tag>{}; - - /** - * @brief A tag to enable derivation of the stream input operator - * - * @since 1.0.0 - */ auto constexpr Read = derivable<struct read_tag>{}; - - /** - * @brief A tag to enable derivation of the relational operators - * - * @since 1.0.0 - */ auto constexpr Relational = derivable<struct relational_tag>{}; - - /** - * @brief A tag to enable derivation of the stream output operator - * - * @since 1.0.0 - */ auto constexpr Show = derivable<struct show_tag>{}; } // namespace derivables diff --git a/include/newtype/derivation_clause.hpp b/include/newtype/derivation_clause.hpp index edb2f85..6de70e1 100644 --- a/include/newtype/derivation_clause.hpp +++ b/include/newtype/derivation_clause.hpp @@ -9,11 +9,6 @@ namespace nt { - /** - * A @p deriving clause type - * - * @tparam DerivableTags A list of tag types defining a set of derivable features - */ template<typename... DerivableTags> struct derivation_clause { @@ -21,88 +16,48 @@ namespace nt { } - /** - * Check whether the derivation clause contains a given derivable - */ template<typename DerivableTag> auto constexpr operator()(derivable<DerivableTag>) const noexcept -> bool { return (std::is_same_v<DerivableTags, DerivableTag> || ...); } - /** - * Check whether the derivation clause contains all derivables in a given lists - */ template<typename DerivableTag, typename... RemainingDerivableTags> auto constexpr operator()(derivable<DerivableTag>, derivable<RemainingDerivableTags>...) const noexcept -> bool { return (*this)(derivable<DerivableTag>{}) && (*this)(derivable<RemainingDerivableTags>{}...); } - /** - * Check whether this derivation clause is less than an other derivation clause - * - * A derivation clause is considered less than an other derivation clause iff. its set of derivables is a strict subset of - * the set derivables of the other. - */ template<typename... OtherDerivableTags> auto constexpr operator<(derivation_clause<OtherDerivableTags...> other) const noexcept -> bool { return (sizeof...(DerivableTags) < sizeof...(OtherDerivableTags)) && other(derivable<DerivableTags>{}...); } - /** - * Check whether this derivation clause is greater than an other derivation clause - * - * A derivation clause is considered greater than an other derivation clause iff. its set of derivables is a strict superset - * of the set derivables of the other. - */ template<typename... OtherDerivableTags> auto constexpr operator>(derivation_clause<OtherDerivableTags...> other) const noexcept -> bool { return other < *this; } - /** - * Check whether this derivation clause is equal to an other derivation clause - * - * Two derivation clauses are considered equal if both have the same set of derivables - */ template<typename... OtherDerivableTags> auto constexpr operator==(derivation_clause<OtherDerivableTags...> other) const noexcept -> bool { return sizeof...(DerivableTags) == sizeof...(OtherDerivableTags) && other(derivable<DerivableTags>{}...); } - /** - * Check whether this derivation clause is not equal to an other derivation clause - * - * Two derivation clauses are considered not equal if neither has the same set of derivables as the other - */ template<typename... OtherDerivableTags> auto constexpr operator!=(derivation_clause<OtherDerivableTags...> other) const noexcept -> bool { return !(*this == other); } - /** - * Check whether this derivation clause is less-than or equal to an other derivation clause - * - * @see nt::distinct::operator== - * @see nt::distinct::operator< - */ template<typename... OtherDerivableTags> auto constexpr operator<=(derivation_clause<OtherDerivableTags...> other) const noexcept -> bool { return *this < other || *this == other; } - /** - * Check whether this derivation clause is greater-than or equal to an other derivation clause - * - * @see nt::distinct::operator== - * @see nt::distinct::operator< - */ template<typename... OtherDerivableTags> auto constexpr operator>=(derivation_clause<OtherDerivableTags...> other) const noexcept -> bool { diff --git a/include/newtype/deriving.hpp b/include/newtype/deriving.hpp index e762c9b..ae10bab 100644 --- a/include/newtype/deriving.hpp +++ b/include/newtype/deriving.hpp @@ -10,9 +10,6 @@ namespace nt { - /** - * Create a new derivation clause with the given derivables - */ template<typename... DerivableTags> auto constexpr deriving(derivable<DerivableTags>... features) noexcept -> derivation_clause<DerivableTags...> { diff --git a/include/newtype/impl/type_traits_extensions.hpp b/include/newtype/impl/type_traits_extensions.hpp index ee33730..a9bd6af 100644 --- a/include/newtype/impl/type_traits_extensions.hpp +++ b/include/newtype/impl/type_traits_extensions.hpp @@ -14,125 +14,57 @@ namespace nt::impl inline namespace equality_comparable { - /** - * @brief A trait to test if a given type is comparable using operator== - * - * @tparam T The type to test - * @note This specialization forms the base case for non-equals-comparable T - */ template<typename T, typename = void> struct is_equality_comparable : std::false_type { }; - /** - * @brief A trait to test if a given type is comparable using operator== - * - * @tparam T The type to test - * @note This specialization forms the case for equals-comparable T - */ template<typename T> struct is_equality_comparable<T, std::void_t<decltype(std::declval<T const &>() == std::declval<T const &>())>> : std::true_type { }; - /** - * @brief A variable template to test if a given type is comparable using operator== - * - * @tparam T The type to test - */ template<typename T> auto constexpr is_equality_comparable_v = is_equality_comparable<T>::value; - /** - * @brief A trait to test if a given type is noexcept comparable using operator== - * - * @tparam T The type to test - * @note This specialization forms the base case for non-noexcept equals-comparable or non-equals-comparable T - */ template<typename T, typename = void> struct is_nothrow_equality_comparable : std::false_type { }; - /** - * @brief A trait to test if a given type is noexcept comparable using operator== - * - * @tparam T The type to test - * @note This specialization forms the case for equals-comparable T detemining if T is noexcept comparable using operator== - */ template<typename T> struct is_nothrow_equality_comparable<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 &>())> { }; - /** - * @brief A variable template to test if a given type is noexcept comparable using operator== - * - * @tparam T The type to test - */ template<typename T> auto constexpr is_nothrow_equality_comparable_v = is_nothrow_equality_comparable<T>::value; - /** - * @brief A trait to test if a given type is comparable using operator!= - * - * @tparam T The type to test - * @note This specialization forms the base case for non-not-equals-comparable T - */ template<typename T, typename = void> struct is_inequality_comparable : std::false_type { }; - /** - * @brief A trait to test if a given type is comparable using operator!= - * - * @tparam T The type to test - * @note This specialization forms the case for not-equals-comparable T - */ template<typename T> struct is_inequality_comparable<T, std::void_t<decltype(std::declval<T const &>() != std::declval<T const &>())>> : std::true_type { }; - /** - * @brief A variable template to test if a given type is comparable using operator!= - * - * @tparam T The type to test - */ template<typename T> auto constexpr is_inequality_comparable_v = is_inequality_comparable<T>::value; - /** - * @brief A trait to test if a given type is noexcept comparable using operator!= - * - * @tparam T The type to test - * @note This specialization forms the base case for non-noexcept not-equals-comparable or non-not-equals-comparable T - */ template<typename T, typename = void> struct is_nothrow_inequality_comparable : std::false_type { }; - /** - * @brief A trait to test if a given type is noexcept comparable using operator== - * - * @tparam T The type to test - * @note This specialization forms the case for equals-comparable T detemining if T is noexcept comparable using operator!= - */ template<typename T> struct is_nothrow_inequality_comparable<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 &>())> { }; - /** - * @brief A variable template to test if a given type is noexcept comparable using operator!= - * - * @tparam T The type to test - */ template<typename T> auto constexpr is_nothrow_inequality_comparable_v = is_nothrow_inequality_comparable<T>::value; @@ -141,250 +73,112 @@ namespace nt::impl inline namespace relationally_comparable { - /** - * @brief A trait to test if a given type is comparable using operator< - * - * @tparam T The type to test - * @note This specialization forms the base case for non-less-than-comparable T - */ template<typename T, typename = void> struct is_less_than_comparable : std::false_type { }; - /** - * @brief A trait to test if a given type is comparable using operator< - * - * @tparam T The type to test - * @note This specialization forms the case for less-than-comparable T - */ template<typename T> struct is_less_than_comparable<T, std::void_t<decltype(std::declval<T const &>() < std::declval<T const &>())>> : std::true_type { }; - /** - * @brief A variable template to test if a given type is comparable using operator< - * - * @tparam T The type to test - */ template<typename T> auto constexpr is_less_than_comparable_v = is_less_than_comparable<T>::value; - /** - * @brief A trait to test if a given type is noexcept comparable using operator< - * - * @tparam T The type to test - * @note This specialization forms the base case for non-noexcept less-than-comparable or non-less-than-comparable T - */ template<typename T, typename = void> struct is_nothrow_less_than_comparable : std::false_type { }; - /** - * @brief A trait to test if a given type is noexcept comparable using operator< - * - * @tparam T The type to test - * @note This specialization forms the case for less-than-comparable T detemining if T is noexcept comparable using operator< - */ template<typename T> struct is_nothrow_less_than_comparable<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 &>())> { }; - /** - * @brief A variable template to test if a given type is noexcept comparable using operator< - * - * @tparam T The type to test - */ template<typename T> auto constexpr is_nothrow_less_than_comparable_v = is_nothrow_less_than_comparable<T>::value; - /** - * @brief A trait to test if a given type is comparable using operator> - * - * @tparam T The type to test - * @note This specialization forms the base case for non-greater-than-comparable T - */ template<typename T, typename = void> struct is_greater_than_comparable : std::false_type { }; - /** - * @brief A trait to test if a given type is comparable using operator> - * - * @tparam T The type to test - * @note This specialization forms the case for greater-than-comparable T - */ template<typename T> struct is_greater_than_comparable<T, std::void_t<decltype(std::declval<T const &>() > std::declval<T const &>())>> : std::true_type { }; - /** - * @brief A variable template to test if a given type is comparable using operator> - * - * @tparam T The type to test - */ template<typename T> auto constexpr is_greater_than_comparable_v = is_greater_than_comparable<T>::value; - /** - * @brief A trait to test if a given type is noexcept comparable using operator> - * - * @tparam T The type to test - * @note This specialization forms the base case for non-noexcept greater-than-comparable or non-greater-than-comparable T - */ template<typename T, typename = void> struct is_nothrow_greater_than_comparable : std::false_type { }; - /** - * @brief A trait to test if a given type is noexcept comparable using operator> - * - * @tparam T The type to test - * @note This specialization forms the case for greater-than-comparable T detemining if T is noexcept comparable using operator> - */ template<typename T> struct is_nothrow_greater_than_comparable<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 &>())> { }; - /** - * @brief A variable template to test if a given type is noexcept comparable using operator> - * - * @tparam T The type to test - */ template<typename T> auto constexpr is_nothrow_greater_than_comparable_v = is_nothrow_greater_than_comparable<T>::value; - /** - * @brief A trait to test if a given type is comparable using operator<= - * - * @tparam T The type to test - * @note This specialization forms the base case for non-less-than-or-equal-to-comparable T - */ template<typename T, typename = void> struct is_less_than_equal_to_comparable : std::false_type { }; - /** - * @brief A trait to test if a given type is comparable using operator<= - * - * @tparam T The type to test - * @note This specialization forms the case for less-than-or-equal-to-comparable T - */ template<typename T> struct is_less_than_equal_to_comparable<T, std::void_t<decltype(std::declval<T const &>() <= std::declval<T const &>())>> : std::true_type { }; - /** - * @brief A variable template to test if a given type is comparable using operator<= - * - * @tparam T The type to test - */ template<typename T> auto constexpr is_less_than_equal_to_comparable_v = is_less_than_equal_to_comparable<T>::value; - /** - * @brief A trait to test if a given type is noexcept comparable using operator<= - * - * @tparam T The type to test - * @note This specialization forms the base case for non-noexcept less-than-or-equal-to-comparable or non-less-than-or-equal-to-comparable T - */ template<typename T, typename = void> struct is_nothrow_less_than_equal_to_comparable : std::false_type { }; - /** - * @brief A trait to test if a given type is noexcept comparable using operator<= - * - * @tparam T The type to test - * @note This specialization forms the case for less-than-or-equal-to-comparable T detemining if T is noexcept comparable using operator<= - */ template<typename T> struct is_nothrow_less_than_equal_to_comparable<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 &>())> { }; - /** - * @brief A variable template to test if a given type is noexcept comparable using operator<= - * - * @tparam T The type to test - */ template<typename T> auto constexpr is_nothrow_less_than_equal_to_comparable_v = is_nothrow_less_than_equal_to_comparable<T>::value; - /** - * @brief A trait to test if a given type is comparable using operator>= - * - * @tparam T The type to test - * @note This specialization forms the base case for non-greater-than-or-equal-to-comparable T - */ template<typename T, typename = void> struct is_greater_than_equal_to_comparable : std::false_type { }; - /** - * @brief A trait to test if a given type is comparable using operator>= - * - * @tparam T The type to test - * @note This specialization forms the case for greater-than-or-equal-to-comparable T - */ template<typename T> struct is_greater_than_equal_to_comparable<T, std::void_t<decltype(std::declval<T const &>() >= std::declval<T const &>())>> : std::true_type { }; - /** - * @brief A variable template to test if a given type is comparable using operator>= - * - * @tparam T The type to test - */ template<typename T> auto constexpr is_greater_than_equal_to_comparable_v = is_greater_than_equal_to_comparable<T>::value; - /** - * @brief A trait to test if a given type is noexcept comparable using operator>= - * - * @tparam T The type to test - * @note This specialization forms the base case for non-noexcept greater-than-or-equal-to-comparable or - * non-greater-than-or-equal-to-comparable T - */ template<typename T, typename = void> struct is_nothrow_greater_than_equal_to_comparable : std::false_type { }; - /** - * @brief A trait to test if a given type is noexcept comparable using operator>= - * - * @tparam T The type to test - * @note This specialization forms the case for greater-than-or-equal-to-comparable T detemining if T is noexcept comparable using - * operator>= - */ template<typename T> struct is_nothrow_greater_than_equal_to_comparable<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 &>())> { }; - /** - * @brief A variable template to test if a given type is noexcept comparable using operator>= - * - * @tparam T The type to test - */ template<typename T> auto constexpr is_nothrow_greater_than_equal_to_comparable_v = is_nothrow_greater_than_equal_to_comparable<T>::value; } // namespace relationally_comparable @@ -392,126 +186,58 @@ namespace nt::impl inline namespace iostreamable { - /** - * @brief A trait to test if a given type is output streamable - * - * @tparam T The type to test - * @note This specialization forms the base case for non-output-streamable T - */ template<typename StreamType, typename T, typename = void> struct is_output_streamable : std::false_type { }; - /** - * @brief A trait to test if a given type is output streamable - * - * @tparam T The type to test - * @note This specialization forms the case for output-streamable T - */ template<typename StreamType, typename T> struct is_output_streamable<StreamType, T, std::void_t<decltype(std::declval<StreamType &>() << std::declval<T const &>())>> : std::true_type { }; - /** - * @brief A variable template to test if a given type is output streamable - * - * @tparam T The type to test - */ template<typename StreamType, typename T> auto constexpr is_output_streamable_v = is_output_streamable<StreamType, T>::value; - /** - * @brief A trait to test if a given type is noexcept output streamable - * - * @tparam T The type to test - * @note This specialization forms the base case for non-noexcept output-streamable or non-output-streamable T - */ template<typename StreamType, typename T, typename = void> struct is_nothrow_output_streamable : std::false_type { }; - /** - * @brief A trait to test if a given type is noexcept output streamable - * - * @tparam T The type to test - * @note This specialization forms the case for output-streamable T detemining if T is noexcept output-streamable - */ template<typename StreamType, typename T> struct is_nothrow_output_streamable<StreamType, T, std::void_t<decltype(std::declval<StreamType &>() << std::declval<T const &>())>> : std::bool_constant<noexcept(std::declval<StreamType &>() << std::declval<T const &>())> { }; - /** - * @brief A variable template to test if a given type is noexcept output streamable - * - * @tparam T The type to test - */ template<typename StreamType, typename T> auto constexpr is_nothrow_output_streamable_v = is_nothrow_output_streamable<StreamType, T>::value; - /** - * @brief A trait to test if a given type is input streamable - * - * @tparam T The type to test - * @note This specialization forms the base case for non-input-streamable T - */ template<typename StreamType, typename T, typename = void> struct is_input_streamable : std::false_type { }; - /** - * @brief A trait to test if a given type is input streamable - * - * @tparam T The type to test - * @note This specialization forms the case for input-streamable T - */ template<typename StreamType, typename T> struct is_input_streamable<StreamType, T, std::void_t<decltype(std::declval<StreamType &>() >> std::declval<T &>())>> : std::true_type { }; - /** - * @brief A variable template to test if a given type is input streamable - * - * @tparam T The type to test - */ template<typename StreamType, typename T> auto constexpr is_input_streamable_v = is_input_streamable<StreamType, T>::value; - /** - * @brief A trait to test if a given type is noexcept input streamable - * - * @tparam T The type to test - * @note This specialization forms the base case for non-noexcept input-streamable or non-input-streamable T - */ template<typename StreamType, typename T, typename = void> struct is_nothrow_input_streamable : std::false_type { }; - /** - * @brief A trait to test if a given type is noexcept input streamable - * - * @tparam T The type to test - * @note This specialization forms the case for input-streamable T detemining if T is noexcept input-streamable - */ template<typename StreamType, typename T> struct is_nothrow_input_streamable<StreamType, T, std::void_t<decltype(std::declval<StreamType &>() >> std::declval<T &>())>> : std::bool_constant<noexcept(std::declval<StreamType &>() >> std::declval<T &>())> { }; - /** - * @brief A variable template to test if a given type is noexcept input streamable - * - * @tparam T The type to test - */ template<typename StreamType, typename T> auto constexpr is_nothrow_input_streamable_v = is_nothrow_input_streamable<StreamType, T>::value; @@ -520,247 +246,111 @@ namespace nt::impl inline namespace arithmetic { - /** - * @brief A trait to test if a given type is addable - * - * @tparam T The type to test - * @note This specialization forms the base case for non-addable T - */ template<typename T, typename = void> struct is_addable : std::false_type { }; - /** - * @brief A trait to test if a given type is addable - * - * @tparam T The type to test - * @note This specialization forms the case for addable T - */ template<typename T> struct is_addable<T, std::void_t<decltype(std::declval<T const &>() + std::declval<T const &>())>> : std::true_type { }; - /** - * @brief A variable template to test if a given type is addable - * - * @tparam T The type to test - */ template<typename T> auto constexpr is_addable_v = is_addable<T>::value; - /** - * @brief A trait to test if a given type is noexcept addable - * - * @tparam T The type to test - * @note This specialization forms the base case for non-noexcept addable or non-addable T - */ template<typename T, typename = void> struct is_nothrow_addable : std::false_type { }; - /** - * @brief A trait to test if a given type is noexcept addable - * - * @tparam T The type to test - * @note This specialization forms the case for addable T detemining if T is noexcept addable - */ 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 &>())> { }; - /** - * @brief A variable template to test if a given type is noexcept addable - * - * @tparam T The type to test - */ template<typename T> auto constexpr is_nothrow_addable_v = is_nothrow_addable<T>::value; - /** - * @brief A trait to test if a given type is subtractable - * - * @tparam T The type to test - * @note This specialization forms the base case for non-subtractable T - */ template<typename T, typename = void> struct is_subtractable : std::false_type { }; - /** - * @brief A trait to test if a given type is subtractable - * - * @tparam T The type to test - * @note This specialization forms the case for subtractable T - */ template<typename T> struct is_subtractable<T, std::void_t<decltype(std::declval<T const &>() - std::declval<T const &>())>> : std::true_type { }; - /** - * @brief A variable template to test if a given type is subtractable - * - * @tparam T The type to test - */ template<typename T> auto constexpr is_subtractable_v = is_subtractable<T>::value; - /** - * @brief A trait to test if a given type is noexcept subtractable - * - * @tparam T The type to test - * @note This specialization forms the base case for non-noexcept subtractable or non-subtractable T - */ template<typename T, typename = void> struct is_nothrow_subtractable : std::false_type { }; - /** - * @brief A trait to test if a given type is noexcept subtractable - * - * @tparam T The type to test - * @note This specialization forms the case for subtractable T detemining if T is noexcept subtractable - */ 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 &>())> { }; - /** - * @brief A variable template to test if a given type is noexcept subtractable - * - * @tparam T The type to test - */ template<typename T> auto constexpr is_nothrow_subtractable_v = is_nothrow_subtractable<T>::value; - /** - * @brief A trait to test if a given type is multipliable - * - * @tparam T The type to test - * @note This specialization forms the base case for non-multipliable T - */ template<typename T, typename = void> struct is_multipliable : std::false_type { }; - /** - * @brief A trait to test if a given type is multipliable - * - * @tparam T The type to test - * @note This specialization forms the case for multipliable T - */ template<typename T> struct is_multipliable<T, std::void_t<decltype(std::declval<T const &>() * std::declval<T const &>())>> : std::true_type { }; - /** - * @brief A variable template to test if a given type is multipliable - * - * @tparam T The type to test - */ template<typename T> auto constexpr is_multipliable_v = is_multipliable<T>::value; - /** - * @brief A trait to test if a given type is noexcept multipliable - * - * @tparam T The type to test - * @note This specialization forms the base case for non-noexcept multipliable or non-multipliable T - */ template<typename T, typename = void> struct is_nothrow_multipliable : std::false_type { }; - /** - * @brief A trait to test if a given type is noexcept multipliable - * - * @tparam T The type to test - * @note This specialization forms the case for multipliable T detemining if T is noexcept multipliable - */ 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 &>())> { }; - /** - * @brief A variable template to test if a given type is noexcept multipliable - * - * @tparam T The type to test - */ template<typename T> auto constexpr is_nothrow_multipliable_v = is_nothrow_multipliable<T>::value; - /** - * @brief A trait to test if a given type is dividable - * - * @tparam T The type to test - * @note This specialization forms the base case for non-dividable T - */ template<typename T, typename = void> struct is_dividable : std::false_type { }; - /** - * @brief A trait to test if a given type is dividable - * - * @tparam T The type to test - * @note This specialization forms the case for dividable T - */ template<typename T> struct is_dividable<T, std::void_t<decltype(std::declval<T const &>() / std::declval<T const &>())>> : std::true_type { }; - /** - * @brief A variable template to test if a given type is dividable - * - * @tparam T The type to test - */ template<typename T> auto constexpr is_dividable_v = is_dividable<T>::value; - /** - * @brief A trait to test if a given type is noexcept dividable - * - * @tparam T The type to test - * @note This specialization forms the base case for non-noexcept dividable or non-dividable T - */ template<typename T, typename = void> struct is_nothrow_dividable : std::false_type { }; - /** - * @brief A trait to test if a given type is noexcept dividable - * - * @tparam T The type to test - * @note This specialization forms the case for dividable T detemining if T is noexcept dividable - */ 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 &>())> { }; - /** - * @brief A variable template to test if a given type is noexcept dividable - * - * @tparam T The type to test - */ template<typename T> auto constexpr is_nothrow_dividable_v = is_nothrow_dividable<T>::value; @@ -769,247 +359,111 @@ namespace nt::impl inline namespace compound_arithmetic { - /** - * @brief A trait to test if a given type is add-assignable - * - * @tparam T The type to test - * @note This specialization forms the base case for non-add-assignable T - */ template<typename T, typename = void> struct is_add_assignable : std::false_type { }; - /** - * @brief A trait to test if a given type is add-assignable - * - * @tparam T The type to test - * @note This specialization forms the case for add-assignable T - */ template<typename T> struct is_add_assignable<T, std::void_t<decltype(std::declval<T &>() += std::declval<T const &>())>> : std::true_type { }; - /** - * @brief A variable template to test if a give |
