types/traits: add is_same_basic_type trait

This commit is contained in:
Danny Robson 2018-08-01 18:39:01 +10:00
parent 00c46e0f9a
commit bcb4d7569f
2 changed files with 60 additions and 2 deletions

View File

@ -63,5 +63,9 @@ main (void)
tap.expect (is_contiguous_v<std::vector<char>>, "vector is contiguous");
tap.expect (is_contiguous_v<std::array<char,4>>, "array is contiguous");
tap.expect (!is_contiguous_v<std::list<char>>, "list is not contiguous");
tap.expect ( util::is_same_basic_type_v<float,double>, "float-double same_basic_type");
tap.expect (!util::is_same_basic_type_v<float,int>, "float-int same_basic_type");
return tap.status ();
}

View File

@ -27,7 +27,7 @@
/// modifiers are applied in the order they are provided.
///
/// use without any modifiers results in the identity modifier.
namespace util {
namespace util::types {
//-------------------------------------------------------------------------
template <typename TypeT, template <typename> class ...ModifierT>
struct compose;
@ -260,7 +260,7 @@ template <typename T>
struct func_traits : public ::detail::func_traits<
// we apply as many transforms as possible before palming it off to the
// detail class so that we don't have to write as many distinct cases.
::util::chain_t<T,
::util::types::chain_t<T,
std::remove_cv,
std::decay,
remove_member_const,
@ -405,4 +405,58 @@ template <
template <template <typename...> class TemplateT, typename QueryT>
constexpr auto is_same_template_template_v = is_same_template_template<TemplateT,QueryT>::value;
namespace util::traits {
/// combines an abitrary sequence of type traits into one result
template <
typename ValueT,
template <typename> class ...Traits
> struct all : public std::integral_constant<
bool,
(Traits<ValueT>::value && ...)
> { };
};
///////////////////////////////////////////////////////////////////////////////
namespace util {
/// tests if the type is a signed integer type
template <typename ValueT>
struct is_signed_integral : public traits::all<
ValueT, std::is_signed, std::is_integral
> { };
template <typename ValueT>
constexpr auto is_signed_integral_v = is_signed_integral<ValueT>::value;
/// tests if the type is an unsigned integer type
template <typename ValueT>
struct is_unsigned_integral : public traits::all<
ValueT, std::is_unsigned, std::is_integral
> { };
template <typename ValueT>
constexpr auto is_unsigned_integral_v = is_unsigned_integral<ValueT>::value;
/// tests if the type has the same basic fundamental type.
///
/// ie, both float, signed, unsigned, or char.
template <typename ValueA, typename ValueB>
struct is_same_basic_type {
static constexpr bool value =
(std::is_floating_point_v<ValueA> && std::is_floating_point_v<ValueB>) ||
(is_unsigned_integral_v<ValueA> && is_unsigned_integral_v<ValueB>) ||
(is_signed_integral_v<ValueA> && is_signed_integral_v<ValueB>) ||
(std::is_same_v<char,ValueA> && std::is_same_v<char,ValueB>);
};
template <typename ValueA, typename ValueB>
constexpr auto is_same_basic_type_v = is_same_basic_type<ValueA,ValueB>::value;
}
#endif