Commit 2df931ad authored by Jakub Klinkovský's avatar Jakub Klinkovský
Browse files

Improved type traits to work even with reference types

parent 43597c11
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@ template< typename T, typename V = T >
constexpr ExpressionVariableType
getExpressionVariableType()
{
   if( std::is_arithmetic< std::decay_t< T > >::value )
   if( std::is_arithmetic< T >::value )
      return ArithmeticVariable;
   // vectors must be considered as an arithmetic type when used as RealType in another vector
   if( IsArithmeticSubtype< T, V >::value )
+27 −19
Original line number Diff line number Diff line
@@ -33,47 +33,55 @@ struct HasEnabledDistributedExpressionTemplates : std::false_type
// type aliases for enabling specific operators and functions using SFINAE
template< typename ET1 >
using EnableIfStaticUnaryExpression_t = std::enable_if_t<
      HasEnabledStaticExpressionTemplates< ET1 >::value >;
      HasEnabledStaticExpressionTemplates< std::decay_t< ET1 > >::value >;

template< typename ET1, typename ET2 >
using EnableIfStaticBinaryExpression_t = std::enable_if_t<
      HasEnabledStaticExpressionTemplates< ET1 >::value ||
      HasEnabledStaticExpressionTemplates< ET2 >::value >;
      (
         HasEnabledStaticExpressionTemplates< std::decay_t< ET1 > >::value ||
         HasEnabledStaticExpressionTemplates< std::decay_t< ET2 > >::value
      ) && !
      (
         HasEnabledExpressionTemplates< std::decay_t< ET2 > >::value ||
         HasEnabledExpressionTemplates< std::decay_t< ET1 > >::value ||
         HasEnabledDistributedExpressionTemplates< std::decay_t< ET2 > >::value ||
         HasEnabledDistributedExpressionTemplates< std::decay_t< ET1 > >::value
      ) >;

template< typename ET1 >
using EnableIfUnaryExpression_t = std::enable_if_t<
      HasEnabledExpressionTemplates< ET1 >::value >;
      HasEnabledExpressionTemplates< std::decay_t< ET1 > >::value >;

template< typename ET1, typename ET2 >
using EnableIfBinaryExpression_t = std::enable_if_t<
      // we need to avoid ambiguity with operators defined in Array (e.g. Array::operator==)
      // so the first operand must not be Array
      (
         HasAddAssignmentOperator< ET1 >::value ||
         HasEnabledExpressionTemplates< ET1 >::value ||
         std::is_arithmetic< ET1 >::value
         HasAddAssignmentOperator< std::decay_t< ET1 > >::value ||
         HasEnabledExpressionTemplates< std::decay_t< ET1 > >::value ||
         std::is_arithmetic< std::decay_t< ET1 > >::value
      ) &&
      (
         HasEnabledExpressionTemplates< ET2 >::value ||
         HasEnabledExpressionTemplates< ET1 >::value
         HasEnabledExpressionTemplates< std::decay_t< ET2 > >::value ||
         HasEnabledExpressionTemplates< std::decay_t< ET1 > >::value
      ) >;

template< typename ET1 >
using EnableIfDistributedUnaryExpression_t = std::enable_if_t<
      HasEnabledDistributedExpressionTemplates< ET1 >::value >;
      HasEnabledDistributedExpressionTemplates< std::decay_t< ET1 > >::value >;

template< typename ET1, typename ET2 >
using EnableIfDistributedBinaryExpression_t = std::enable_if_t<
      // we need to avoid ambiguity with operators defined in Array (e.g. Array::operator==)
      // so the first operand must not be Array
      (
         HasAddAssignmentOperator< ET1 >::value ||
         HasEnabledDistributedExpressionTemplates< ET1 >::value ||
         std::is_arithmetic< ET1 >::value
         HasAddAssignmentOperator< std::decay_t< ET1 > >::value ||
         HasEnabledDistributedExpressionTemplates< std::decay_t< ET1 > >::value ||
         std::is_arithmetic< std::decay_t< ET1 > >::value
      ) &&
      (
         HasEnabledDistributedExpressionTemplates< ET2 >::value ||
         HasEnabledDistributedExpressionTemplates< ET1 >::value
         HasEnabledDistributedExpressionTemplates< std::decay_t< ET2 > >::value ||
         HasEnabledDistributedExpressionTemplates< std::decay_t< ET1 > >::value
      ) >;


@@ -83,7 +91,7 @@ template< typename T, typename V,
struct IsArithmeticSubtype
: public std::integral_constant< bool,
            // TODO: use std::is_assignable?
            std::is_same< T, typename V::RealType >::value >
            std::is_same< T, typename std::decay_t< V >::RealType >::value >
{};

template< typename T >
@@ -109,13 +117,13 @@ struct enable_if_type { typedef R type; };
template< typename R, typename Enable = void >
struct RemoveExpressionTemplate
{
   using type = R;
   using type = std::decay_t< R >;
};

template< typename R >
struct RemoveExpressionTemplate< R, typename enable_if_type< typename R::VectorOperandType >::type >
struct RemoveExpressionTemplate< R, typename enable_if_type< typename std::decay_t< R >::VectorOperandType >::type >
{
   using type = typename RemoveExpressionTemplate< typename R::VectorOperandType >::type;
   using type = typename RemoveExpressionTemplate< typename std::decay_t< R >::VectorOperandType >::type;
};

template< typename R >
+8 −8
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ private:
    template< typename C > static NoType& test(...);

public:
    static constexpr bool value = ( sizeof( test< T >(0) ) == sizeof( YesType ) );
    static constexpr bool value = ( sizeof( test< std::decay_t<T> >(0) ) == sizeof( YesType ) );
};

/**
@@ -46,7 +46,7 @@ private:
    template< typename C > static NoType& test(...);

public:
    static constexpr bool value = ( sizeof( test< T >(0) ) == sizeof( YesType ) );
    static constexpr bool value = ( sizeof( test< std::decay_t<T> >(0) ) == sizeof( YesType ) );
};

/**
@@ -70,7 +70,7 @@ private:
   template< typename >
   static constexpr std::false_type check(...);

   using type = decltype(check<T>(0));
   using type = decltype(check<std::decay_t<T>>(0));

public:
    static constexpr bool value = type::value;
@@ -97,7 +97,7 @@ private:
   template< typename >
   static constexpr std::false_type check(...);

   using type = decltype(check<T>(0));
   using type = decltype(check<std::decay_t<T>>(0));

public:
    static constexpr bool value = type::value;
@@ -124,7 +124,7 @@ private:
   template< typename >
   static constexpr std::false_type check(...);

   using type = decltype(check<T>(0));
   using type = decltype(check<std::decay_t<T>>(0));

public:
    static constexpr bool value = type::value;
@@ -188,7 +188,7 @@ private:
      template< typename M, M method >
      static constexpr std::false_type is_constexpr_impl(...);

      using type = decltype(is_constexpr_impl< decltype(&T::getSize), &T::getSize >(0));
      using type = decltype(is_constexpr_impl< decltype(&std::decay_t<T>::getSize), &std::decay_t<T>::getSize >(0));
   };

   // specialization for types which don't have getSize() method at all
@@ -223,7 +223,7 @@ struct IsStaticArrayType
template< typename T >
struct IsViewType
: public std::integral_constant< bool,
            std::is_same< typename T::ViewType, T >::value >
            std::is_same< typename std::decay_t<T>::ViewType, T >::value >
{};

/**
@@ -247,7 +247,7 @@ private:
   template< typename >
   static constexpr std::false_type check(...);

   using type = decltype(check<T>(0));
   using type = decltype(check<std::decay_t<T>>(0));

public:
    static constexpr bool value = type::value;