#ifndef ALSK_ALSK_EDSL_OP_IMPL_SERIAL_H #define ALSK_ALSK_EDSL_OP_IMPL_SERIAL_H #include #include "../traits.h" #include "../../../skeleton/bone/serial.h" #include "../../../skeleton/struct/struct.h" #include "../../../skeleton/link/link.h" namespace alsk { namespace edsl { template struct Serial: OperandBase { std::tuple operands; constexpr Serial(Operands... operands): operands{operands...} {} template constexpr Serial(Serial const& o): operands{o.operands} {} template constexpr Serial(Serial&& o): operands{std::move(o.operands)} {} using Signature = Signature_; using Struct = S; using Links = L; template constexpr void setup(S& skeleton) const { setup(skeleton, std::make_index_sequence()); } template constexpr void setup(S& skeleton, std::index_sequence) const { using Expander = int[]; static_cast(Expander{(OperandBase::setupFor(std::get(operands), skeleton.template task()), 0)...}); } template constexpr auto link() const&& { return Serial{std::move(*this)}; } template constexpr auto link() const& { return Serial{*this}; } }; namespace impl { template constexpr auto mergeSerial(Lhs const& lhs, std::index_sequence, Rhs const& rhs, std::index_sequence) { return Serial..., std::tuple_element_t...>{ std::get(lhs)..., std::get(rhs)... }; } template constexpr auto mergeSerial(Lhs const& lhs, Rhs const& rhs) { return mergeSerial(lhs, std::make_index_sequence{}>(), rhs, std::make_index_sequence{}>()); } template constexpr auto operandTuple(T const& t) { return std::make_tuple(t); } template constexpr auto operandTuple(Serial const& s) noexcept { return s.operands; } template struct SerialBuilder; template struct SerialBuilder { static constexpr auto build(Arg const& arg, Args const&... args) { return mergeSerial(operandTuple(arg), operandTuple(SerialBuilder::build(args...))); } }; template struct SerialBuilder { static constexpr auto build(Arg const& arg) { return arg; } }; } template 1) and allOperands>* = nullptr> constexpr auto serial(Args const&... args) { return impl::SerialBuilder::build(args...); } template< typename Lhs, typename Rhs, std::enable_if_t and isOperand>* = nullptr > constexpr auto operator,(Lhs const& lhs, Rhs const& rhs) { return impl::mergeSerial(impl::operandTuple(lhs), impl::operandTuple(rhs)); } template< typename Lhs, typename Rhs, std::enable_if_t and isOperand>* = nullptr > constexpr auto operator&(Lhs const& lhs, Rhs const& rhs) { return impl::mergeSerial(impl::operandTuple(lhs), impl::operandTuple(rhs)); } } } #endif