GEGELATI

Loading...
Searching...
No Matches
lambdaInstruction.h
1
39#ifndef LAMBDA_INSTRUCTION_H
40#define LAMBDA_INSTRUCTION_H
41
42#include <functional>
43#include <typeinfo>
44
45#include "data/untypedSharedPtr.h"
46#include "instructions/instruction.h"
47
48namespace Instructions {
49
60 template <typename First, typename... Rest>
61 class LambdaInstruction : public Instructions::Instruction
62 {
63
64#ifdef CODE_GENERATION
65 public:
76 LambdaInstruction(std::function<double(First, Rest...)> function,
77 const std::string& printTemplate = "")
78 : Instructions::Instruction(printTemplate), func{function}
79 {
80 setUpOperand();
81 };
82
83#endif // CODE_GENERATION
84 protected:
88 const std::function<double(const First, const Rest...)> func;
89
90 public:
94 LambdaInstruction() = delete;
95#ifndef CODE_GENERATION
104 LambdaInstruction(std::function<double(First, Rest...)> function)
105 : Instructions::Instruction(), func{function}
106 {
107 setUpOperand();
108 };
109#endif // CODE_GENERATION
111 virtual bool checkOperandTypes(
112 const std::vector<Data::UntypedSharedPtr>& arguments) const override
113 {
114 if (arguments.size() != this->operandTypes.size()) {
115 return false;
116 }
117
118 // List of expected types
119 const std::vector<std::reference_wrapper<const std::type_info>>
120 expectedTypes{
121 // First
122 (!std::is_array<First>::value)
123 ? typeid(First)
124 : typeid(std::remove_all_extents_t<First>[]),
125 (!std::is_array<Rest>::value)
126 ? typeid(Rest)
127 : typeid(std::remove_all_extents_t<Rest>[])...};
128
129 for (auto idx = 0; idx < arguments.size(); idx++) {
130 // Argument Type
131 const std::type_info& argType = arguments.at(idx).getType();
132 if (argType != expectedTypes.at(idx).get()) {
133 return false;
134 }
135 }
136
137 return true;
138 };
139
141 virtual double execute(
142 const std::vector<Data::UntypedSharedPtr>& args) const override
143 {
144
145#ifndef NDEBUG
146 if (Instruction::execute(args) != 1.0) {
147 return 0.0;
148 }
149#endif
150 double result =
151 doExecution(args, std::index_sequence_for<Rest...>{});
152
153 return result;
154 };
155
156 private:
171 template <size_t... I>
172 double doExecution(const std::vector<Data::UntypedSharedPtr>& args,
173 std::index_sequence<I...>) const
174 {
175 return this->func(
176 getDataFromUntypedSharedPtr<First>(args, 0),
177 getDataFromUntypedSharedPtr<Rest>(args, I + 1)...);
178 }
179
194 template <typename T,
195 typename MINUS_EXTENT = typename std::remove_extent<T>::type,
196 typename RETURN_TYPE = typename std::conditional<
197 !std::is_array<MINUS_EXTENT>::value,
198 typename std::remove_all_extents<T>::type*,
199 MINUS_EXTENT*>::type>
200 constexpr auto getDataFromUntypedSharedPtr(
201 const std::vector<Data::UntypedSharedPtr>& args, size_t idx) const
202 {
203 if constexpr (!std::is_array<T>::value) {
204 return *(args.at(idx).getSharedPointer<const T>());
205 }
206 else {
207 auto returnedPtr =
208 args.at(idx)
209 .getSharedPointer<
210 const std::remove_all_extents_t<T>[]>();
211 return (RETURN_TYPE)returnedPtr.get();
212 };
213 };
214
215 void setUpOperand()
216 {
217 this->operandTypes.push_back(typeid(First));
218 // Fold expression to push all other types
219 (this->operandTypes.push_back(typeid(Rest)), ...);
220 }
221 };
222}; // namespace Instructions
223
224#endif
Instructions::Instruction
This abstract class is the base class for any instruction to be used in a Program.
Definition instruction.h:61
Instructions::Instruction::operandTypes
std::vector< std::reference_wrapper< const std::type_info > > operandTypes
List of the types of the operands needed to execute the instruction.
Definition instruction.h:213
Instructions::Instruction::execute
virtual double execute(const std::vector< Data::UntypedSharedPtr > &args) const =0
Execute the Instruction for the given arguments.
Definition instruction.cpp:82
Instructions::Instruction::printTemplate
std::string printTemplate
Definition instruction.h:112
Instructions::LambdaInstruction
Template instruction for simplifying the creation of an Instruction from a c++ lambda function.
Definition lambdaInstruction.h:62
Instructions::LambdaInstruction::func
const std::function< double(const First, const Rest...)> func
Function executed for this Instruction.
Definition lambdaInstruction.h:88
Instructions::LambdaInstruction::LambdaInstruction
LambdaInstruction()=delete
delete the default constructor.
Instructions::LambdaInstruction::execute
virtual double execute(const std::vector< Data::UntypedSharedPtr > &args) const override
Inherited from Instruction.
Definition lambdaInstruction.h:141
Instructions::LambdaInstruction::LambdaInstruction
LambdaInstruction(std::function< double(First, Rest...)> function, const std::string &printTemplate="")
Constructor of the class LambdaInstruction to create a printable Instruction.
Definition lambdaInstruction.h:76
Instructions
Definition addPrimitiveType.h:49