pfor/src/pfor/expression/traits.h

59 lines
1.5 KiB
C++

#ifndef PFOR_PFOR_EXPRESSION_TRAITS_H
#define PFOR_PFOR_EXPRESSION_TRAITS_H
#include <utility>
#include "tag.h"
namespace pfor {
namespace expr {
/**
* @brief tests a type and return true if it is an expression
*
* @return true if the type is an expression
*/
template<typename, typename = void>
struct IsExpression: std::false_type {};
template<typename T>
struct IsExpression<T, std::enable_if_t<std::is_same<typename std::decay_t<T>::IsExpression, tag::Expression>{}>>: std::true_type {};
template<typename E>
constexpr bool isExpression = IsExpression<E>::value;
/**
* @brief tests a pack of types and returns true is all are expressions
*/
template<typename...> struct AllExpression: std::false_type {};
template<typename T, typename... Ts>
struct AllExpression<T, Ts...> {
static constexpr bool value = IsExpression<T>::value && AllExpression<Ts...>::value;
};
template<typename T> struct AllExpression<T>: IsExpression<T> {};
template<typename... Ts>
constexpr bool allExpression = AllExpression<Ts...>::value;
/**
* @brief tests a pack of types and returns true if any of them is an expression
*/
template<typename...> struct AnyExpression: std::false_type {};
template<typename T, typename... Ts>
struct AnyExpression<T, Ts...> {
static constexpr bool value = IsExpression<T>::value || AnyExpression<Ts...>::value;
};
template<typename T> struct AnyExpression<T>: IsExpression<T> {};
template<typename... Ts>
constexpr bool anyExpression = AnyExpression<Ts...>::value;
}
}
#endif