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
 |