83 lines
2.0 KiB
C++
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
|