rosa/inc/alsk/edsl/op/impl/operand.h

68 lines
1.5 KiB
C++

#ifndef ALSK_ALSK_EDSL_OP_IMPL_OPERAND_H
#define ALSK_ALSK_EDSL_OP_IMPL_OPERAND_H
#include <type_traits>
#include <utility>
#include "../../../skeleton/muscle/muscle.h"
namespace alsk {
namespace edsl {
struct OperandTag;
struct LeafTag;
struct OperandBase {
using IsOperand = OperandTag;
constexpr OperandBase() noexcept = default;
template<typename S, typename Operand, decltype(std::declval<Operand>().setup(std::declval<S&>()))* = nullptr>
constexpr void setupFor(Operand& operand, S& skeleton) const noexcept {
operand.setup(skeleton);
}
template<typename... Args>
constexpr void setupFor(Args&&...) const noexcept {}
};
template<typename Function_, typename Signature_>
struct Operand: OperandBase {
using IsLeaf = LeafTag;
using Function = Function_;
using Signature = Signature_;
using Struct = Function_;
using Links = Signature_;
constexpr Operand() noexcept = default;
template<typename Signature>
constexpr auto link() const noexcept { return Operand<Function, Signature>{}; }
};
template<typename Function>
constexpr auto makeOperand() noexcept {
return Operand<Function, void()>{};
}
template<typename Signature, typename Function>
constexpr auto makeOperand() noexcept {
return Operand<Function, Signature>{};
}
template<typename Signature, Signature function>
constexpr auto makeOperand() noexcept {
using Function = Fn<Signature, function>;
return Operand<Function, typename Function::Signature>{};
}
}
}
// TODO C++17
#define alskMakeOperand(f) makeOperand<decltype(f)&, f>()
#endif