pfor/src/pfor/index/traits.h

67 lines
1.8 KiB
C++

#ifndef PFOR_PFOR_INDEX_TRAITS_H
#define PFOR_PFOR_INDEX_TRAITS_H
#include <utility>
#include "index.h"
#include "op.h"
#include "tag.h"
#include "../mp/pack.h"
namespace pfor {
namespace index {
/**
* @brief tests a type and return true if it is an index expression
*
* @return true if the type is an index expression
*/
template<typename, typename = void>
struct IsIndexImpl: std::false_type {};
template<typename T>
struct IsIndexImpl<T, std::enable_if_t<std::is_same<typename std::decay_t<T>::IsIndex, tag::Index>{}>>: std::true_type {};
template<typename T>
struct IsIndex: IsIndexImpl<T> {};
template<typename E>
constexpr bool isIndex = IsIndex<E>::value;
/**
* @brief tests a pack of types and returns true is all are index expressions
*/
template<typename... Ts> struct AllIndex: std::integral_constant<bool, packAll<Pack<Ts...>, IsIndex>> {};
template<typename... Ts>
constexpr bool allIndex = AllIndex<Ts...>::value;
/**
*/
template<typename> struct IsConstant: std::true_type {};
template<typename P>
struct IsConstant<IndexP<P>>: std::false_type {};
template<typename Op, typename Lhs, typename Rhs, typename P>
struct IsConstant<IndexImpl<Pack<Op, Lhs, Rhs>, P>> {
static constexpr bool value = IsConstant<Lhs>::value && IsConstant<Rhs>::value;
};
template<typename Op, typename Rhs, typename P, typename InP>
struct IsConstant<IndexImpl<Pack<Op, IndexP<InP>, Rhs>, P>>: std::false_type {};
template<typename Op, typename Lhs, typename P, typename InP>
struct IsConstant<IndexImpl<Pack<Op, Lhs, IndexP<InP>>, P>>: std::false_type {};
template<typename Op, typename P, typename LhsP, typename RhsP>
struct IsConstant<IndexImpl<Pack<Op, IndexP<LhsP>, IndexP<RhsP>>, P>>: std::false_type {};
template<typename E>
constexpr bool isConstant = IsConstant<E>::value;
}
}
#endif