NRP Core  1.4.1
functional_node_factory.h
Go to the documentation of this file.
1 /* * NRP Core - Backend infrastructure to synchronize simulations
2  *
3  * Copyright 2020-2023 NRP Team
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * This project has received funding from the European Union’s Horizon 2020
18  * Framework Programme for Research and Innovation under the Specific Grant
19  * Agreement No. 945539 (Human Brain Project SGA3).
20  */
21 
22 #ifndef FUNCTIONAL_NODE_FACTORY_H
23 #define FUNCTIONAL_NODE_FACTORY_H
24 
26 
27 template<size_t, typename, typename, size_t>
28 struct sub_tuple;
29 
30 // Helper structure defining the type of a sub range of Tuple between indexes IDX1 and IDX2
31 template<size_t IDX1, typename... Tpack, typename Tuple, size_t IDX2>
32 struct sub_tuple<IDX1, std::tuple<Tpack...>, Tuple, IDX2>
33  : sub_tuple<IDX1 + 1, std::tuple<Tpack..., std::tuple_element_t<IDX1, Tuple>>, Tuple, IDX2>
34 { };
35 
36 // Base case
37 template<std::size_t IDX, typename... Tpack, typename Tuple>
38 struct sub_tuple<IDX, std::tuple<Tpack...>, Tuple, IDX>
39 { typedef std::tuple<Tpack...> type; };
40 
48 
49  // helper type to check if the declared input parameters are correct
50  template<class T>
51  using is_correct_input = std::conjunction<std::is_pointer<T>,
52  std::is_const<std::remove_pointer_t<T>>>; // const T*
53 
54  // helper type to check if the declared output parameters are correct
55  template<class T>
56  using is_correct_output = std::conjunction<std::is_lvalue_reference<T>,
57  std::negation<std::is_const<std::remove_reference<T>>>>; // (not const) T&
58 
59 public:
60 
67  template<size_t in_n, size_t out_n, typename... args>
68  static auto create(const std::string &id, std::function<bool(args...)> f, FunctionalNodePolicies::ExecutionPolicy policy = FunctionalNodePolicies::ExecutionPolicy::ON_NEW_INPUT) {
69  // Check that template types are correct
70  static_assert(in_n + out_n == sizeof...(args), "Wrong number of input and/or output parameters in Functional Node");
71 
72  // Declare helper types
73  using f_params_t = std::tuple<args...>;
74  using f_params_no_ref_t = std::tuple<std::remove_reference_t<args>...>;
75  using f_params_no_pointer_t = std::tuple<std::remove_const_t<std::remove_pointer_t<args>>...>;
76  using inputs_t = typename sub_tuple<0, std::tuple<>, f_params_t, in_n>::type;
77  using outputs_t = typename sub_tuple<in_n, std::tuple<>, f_params_t, in_n + out_n>::type;
78  using inputs_no_pointer_t = typename sub_tuple<0, std::tuple<>, f_params_no_pointer_t, in_n>::type;
79  using outputs_no_ref_t = typename sub_tuple<in_n, std::tuple<>, f_params_no_ref_t, in_n + out_n>::type;
80 
81  // Check that function arguments has the correct types
82  FunctionalNodeFactory::checkInputs<0, in_n, inputs_t>(); // const T*
83  FunctionalNodeFactory::checkOutputs<0, out_n, outputs_t>(); // T&
84 
85  // Instantiates FN
86  using params_t = decltype(std::tuple_cat(std::declval<inputs_t>(), std::declval<outputs_no_ref_t>()));
87  auto f_wrap = [f](params_t &p) { return std::apply(f, p); };
88  return new FunctionalNode<inputs_no_pointer_t, outputs_no_ref_t>(id, f_wrap, policy);
89  }
90 
91 private:
92 
96  template<size_t N, size_t MaxN, typename tuple_t>
97  static void checkInputs()
98  {
99  if constexpr (N < MaxN) {
100 
101  static_assert(is_correct_input<typename std::tuple_element<N, tuple_t>::type>::value, "Functional Node inputs must be \"constT*\"");
102  checkInputs<N+1, MaxN, tuple_t>();
103  }
104  }
105 
109  template<size_t N, size_t MaxN, typename tuple_t>
110  static void checkOutputs()
111  {
112  if constexpr (N < MaxN) {
113  static_assert(is_correct_output<typename std::tuple_element<N, tuple_t>::type>::value, "Functional Node outputs must be \"T&\"");
114  checkOutputs<N+1, MaxN, tuple_t>();
115  }
116  }
117 };
118 
119 
120 #endif //FUNCTIONAL_NODE_FACTORY_H
sub_tuple
Definition: functional_node_factory.h:28
sub_tuple< IDX, std::tuple< Tpack... >, Tuple, IDX >::type
std::tuple< Tpack... > type
Definition: functional_node_factory.h:39
FunctionalNodePolicies::ExecutionPolicy
ExecutionPolicy
Possible execution policies for this node.
Definition: computational_node_policies.h:41
FunctionalNodeFactory
Creates an instance of FunctionalNode with the right template given a function signature.
Definition: functional_node_factory.h:47
python_grpc_engine.type
type
Definition: python_grpc_engine.py:63
python_json_engine.args
Namespace args
Definition: python_json_engine.py:196
FunctionalNodeFactory::create
static auto create(const std::string &id, std::function< bool(args...)> f, FunctionalNodePolicies::ExecutionPolicy policy=FunctionalNodePolicies::ExecutionPolicy::ON_NEW_INPUT)
Instantiates a FunctionalNode.
Definition: functional_node_factory.h:68
FunctionalNode
Definition: functional_node.h:179
functional_node.h
FunctionalNodePolicies::ON_NEW_INPUT
@ ON_NEW_INPUT
Definition: computational_node_policies.h:43