Loading [MathJax]/extensions/TeX/AMSmath.js
Radium Engine  1.5.29
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
BinaryOpNode.hpp
1#pragma once
2#include "Core/CoreMacros.hpp"
3#include "Dataflow/Core/Port.hpp"
4#include <Dataflow/Core/Node.hpp>
5
6#include <functional>
7
8namespace Ra {
9namespace Dataflow {
10namespace Core {
11namespace Functionals {
12
16namespace internal {
17
23template <typename A, bool is_container = false>
25 using value_type = A;
26 using const_value_ref = const A&;
27};
28
33template <typename A>
34struct ArgTypeHelperInternal<A, true> {
35 using value_type = typename A::value_type;
36 using const_value_ref = const typename A::value_type&;
37};
38
43template <typename A>
44struct ArgTypeHelper : public ArgTypeHelperInternal<A, Ra::Core::Utils::is_container<A>::value> {};
45
46// Find a way to evaluate the copy/move semantic of t_out
57template <typename t_a,
58 typename t_b,
59 typename t_out,
60 typename funcType,
61 bool it_a = Ra::Core::Utils::is_container<t_a>::value,
62 bool it_b = Ra::Core::Utils::is_container<t_b>::value,
63 bool it_out = Ra::Core::Utils::is_container<t_out>::value>
65 static t_out executeInternal( t_a&, t_b&, funcType ) {
66 static_assert( ( ( it_a || it_b ) ? it_out : !it_out ), "Invalid template parameter " );
67 }
68};
69
73template <typename t_a, typename t_b, typename t_out, typename funcType>
74struct ExecutorHelper<t_a, t_b, t_out, funcType, true, true, true> {
75 static t_out executeInternal( t_a& a, t_b& b, funcType f ) {
76 t_out res;
77 std::transform( a.begin(),
78 a.end(),
79 b.begin(),
80 std::back_inserter( res ),
81 [f]( typename ArgTypeHelper<t_a>::const_value_ref x,
82 typename ArgTypeHelper<t_b>::const_value_ref y ) ->
83 typename ArgTypeHelper<t_out>::value_type { return f( x, y ); } );
84 return res;
85 }
86};
87
91template <typename t_a, typename t_b, typename t_out, typename funcType>
92struct ExecutorHelper<t_a, t_b, t_out, funcType, true, false, true> {
93 static t_out executeInternal( t_a& a, t_b& b, funcType f ) {
94 t_out res;
95 std::transform( a.begin(),
96 a.end(),
97 std::back_inserter( res ),
98 [&b, f]( typename ArgTypeHelper<t_a>::const_value_ref x ) ->
99 typename ArgTypeHelper<t_out>::value_type { return f( x, b ); } );
100 return res;
101 }
102};
103
107template <typename t_a, typename t_b, typename t_out, typename funcType>
108struct ExecutorHelper<t_a, t_b, t_out, funcType, false, true, true> {
109 static t_out executeInternal( t_a& a, t_b& b, funcType f ) {
110 t_out res;
111 std::transform( b.begin(),
112 b.end(),
113 std::back_inserter( res ),
114 [&a, f]( typename ArgTypeHelper<t_b>::const_value_ref x ) ->
115 typename ArgTypeHelper<t_out>::value_type { return f( a, x ); } );
116 return res;
117 }
118};
119
123template <typename t_a, typename t_b, typename t_out, typename funcType>
124struct ExecutorHelper<t_a, t_b, t_out, funcType, false, false, false> {
125 static t_out executeInternal( t_a& a, t_b& b, funcType f ) { return f( a, b ); }
126};
127} // namespace internal
128
154template <typename t_a, typename t_b = t_a, typename t_result = t_a>
155class BinaryOpNode : public Node
156{
157 public:
161 using Arg1_type = typename internal::ArgTypeHelper<t_a>::const_value_ref;
162 using Arg2_type = typename internal::ArgTypeHelper<t_b>::const_value_ref;
163 using Res_type = typename internal::ArgTypeHelper<t_result>::value_type;
164 using BinaryOperator = std::function<Res_type( Arg1_type, Arg2_type )>;
165
171 BinaryOpNode( const std::string& instanceName, std::optional<BinaryOperator> op = {} ) :
172 BinaryOpNode( instanceName, node_typename(), op ) {}
173
174 void init() override {
175 m_result = t_result {};
176 Node::init();
177 }
178
179 bool execute() override {
180
181 const auto& f = m_port_in_op->data();
183 m_port_in_a->data(), m_port_in_b->data(), f );
184 return true;
185 }
186
188 void set_operator( BinaryOperator op ) { m_port_in_op->set_default_value( op ); }
189
190 static const std::string& node_typename() {
191 static std::string demangledName =
192 std::string { "BinaryOp<" } + Ra::Core::Utils::simplifiedDemangledType<t_a>() + " x " +
193 Ra::Core::Utils::simplifiedDemangledType<t_b>() + " -> " +
194 Ra::Core::Utils::simplifiedDemangledType<t_result>() + ">";
195 return demangledName;
196 }
197
198 protected:
199 BinaryOpNode( const std::string& instanceName,
200 const std::string& typeName,
201 std::optional<BinaryOperator> op ) :
202 Node( instanceName, typeName ) {
203 if ( op ) m_port_in_op->set_default_value( *op );
204 }
205
206 void toJsonInternal( nlohmann::json& data ) const override { Node::toJsonInternal( data ); }
207
208 bool fromJsonInternal( const nlohmann::json& data ) override {
209 return Node::fromJsonInternal( data );
210 }
211
212 private:
214
215 RA_NODE_PORT_IN( t_a, a );
216 RA_NODE_PORT_IN( t_b, b );
217 RA_NODE_PORT_IN( BinaryOperator, op );
218 RA_NODE_PORT_OUT_WITH_DATA( t_result, result );
219};
220
221} // namespace Functionals
222} // namespace Core
223} // namespace Dataflow
224} // namespace Ra
T back_inserter(T... args)
Apply a binary operation on its input.
bool fromJsonInternal(const nlohmann::json &data) override
Internal json representation of the Node.
BinaryOpNode(const std::string &instanceName, std::optional< BinaryOperator > op={})
Construct a BinaryOpNode with the given operator.
bool execute() override
Executes the node.
void toJsonInternal(nlohmann::json &data) const override
Internal json representation of the Node.
void init() override
Initializes the node content.
void set_operator(BinaryOperator op)
Sets the operator to be evaluated by the node.
typename internal::ArgTypeHelper< t_a >::const_value_ref Arg1_type
Base abstract class for all the nodes added and used by the node system.
Definition Node.hpp:40
virtual void init()
Initializes the node content.
Definition Node.hpp:428
virtual bool fromJsonInternal(const nlohmann::json &data)
Internal json representation of the Node.
Definition Node.cpp:91
virtual void toJsonInternal(nlohmann::json &data) const
Internal json representation of the Node.
Definition Node.cpp:109
hepler function to manage enum as underlying types in VariableSet
Definition Cage.cpp:4
Type traits giving access to value_type and const ref type.
Manage the call to y = f(a, b) according to inputs aand ouput types of the node.
T transform(T... args)