rosa/inc/alsk/edsl/op/traits.h

83 lines
2.0 KiB
C++

#ifndef ALSK_ALSK_EDSL_OP_TRAITS_H
#define ALSK_ALSK_EDSL_OP_TRAITS_H
#include <type_traits>
#include "impl/operand.h"
namespace alsk {
namespace edsl {
/**
* @brief true if the type is an operand for the EDSL
*/
template<typename, typename=void> struct IsOperand: std::false_type {};
template<typename T>
struct IsOperand<T, std::enable_if_t<std::is_same<typename T::IsOperand, OperandTag>{}>>: std::true_type {};
template<typename T>
constexpr bool isOperand = IsOperand<T>::value;
/**
* @brief true if all the types are operands for the EDSL
*/
template<typename...> struct AllOperands;
template<typename T, typename... Ts>
struct AllOperands<T, Ts...> {
static constexpr bool value = isOperand<T> && AllOperands<Ts...>::value;
};
template<>
struct AllOperands<>: std::true_type {};
template<typename... Ts>
constexpr bool allOperands = AllOperands<Ts...>::value;
/**
* @brief true if the type is a leaf
*/
template<typename, typename=void> struct IsLeaf: std::false_type {};
template<typename T>
struct IsLeaf<T, std::enable_if_t<std::is_same<typename T::IsLeaf, LeafTag>{}>>: std::true_type {};
template<typename T>
constexpr bool isLeaf = IsLeaf<T>::value;
/**
* @brief true if the type is a branch
*/
template<typename, typename=void> struct IsBranch: std::false_type {};
template<typename T>
struct IsBranch<T, std::enable_if_t<isOperand<T> and not isLeaf<T>>>: std::true_type {};
template<typename T>
constexpr bool isBranch = IsBranch<T>::value;
/**
* @brief get the return value from an operand's signature
*/
template<typename> struct GetReturnTypeFromSignatureImpl;
template<typename R, typename... Args>
struct GetReturnTypeFromSignatureImpl<R(Args...)> {
using type = R;
};
template<typename Signature>
using GetReturnTypeFromSignature = typename GetReturnTypeFromSignatureImpl<Signature>::type;
/**
* @brief get the return value from an operand
*/
template<typename T>
using GetReturnType = GetReturnTypeFromSignature<typename T::Signature>;
}
}
#endif