2#ifndef SXEVAL_OPERATIONS_HPP
3#define SXEVAL_OPERATIONS_HPP
61#include <unordered_map>
95 template <
typename OP>
96 typename std::enable_if<std::is_base_of<sxeval::AOperation<T>,
OP>
::value>
109 std::unique_ptr<AOperation<T>>
create(
const std::string&
key,
125 std::unordered_map<std::string,
126 const std::function<std::unique_ptr<AOperation<T>>(
127 const std::vector<IInstruction<T>*>&)>> _operations;
140 add<Subtraction<T>>();
141 add<Multiplication<T>>();
144 add<Exponentiation<T>>();
149 add<LessOrEqual<T>>();
150 add<GreaterOrEqual<T>>();
151 add<LogicalAnd<T>>();
153 add<LogicalNot<T>>();
154 add<LogicalXor<T>>();
155 add<LogicalXnor<T>>();
156 add<LogicalNand<T>>();
157 add<LogicalNor<T>>();
158 add<AbsoluteValue<T>>();
164 add<Hypotenuse<T>>();
165 add<NaturalLogarithm<T>>();
167 add<Logarithm10<T>>();
168 add<Logarithm1p<T>>();
169 add<Logarithm2<T>>();
170 add<LogarithmB<T>>();
174 add<SquareRoot<T>>();
180 add<ArcTangent<T>>();
181 add<ArcTangent2<T>>();
189 add<DegreesToRadians<T>>();
190 add<RadiansToDegrees<T>>();
191 add<DegreesToGradians<T>>();
192 add<GradiansToDegrees<T>>();
196template <
typename OP>
197typename std::enable_if<std::is_base_of<sxeval::AOperation<T>, OP>::value>::type
199 if (_operations.find(OP::KEY) != _operations.end()) {
200 _operations.erase(OP::KEY);
202 const std::function<std::unique_ptr<AOperation<T>>(
203 const std::vector<IInstruction<T>*>&)> f =
205 const auto nargs =
static_cast<int>(args.size());
206 if (nargs < OP::ARITY_MIN) {
207 std::ostringstream oss;
208 oss <<
"Operation " << OP::KEY <<
" requires at least "
209 << OP::ARITY_MIN <<
" arguments";
210 throw std::invalid_argument(oss.str());
213 && nargs > OP::ARITY_MAX)
215 std::ostringstream oss;
216 oss <<
"Operation " << OP::KEY <<
" requires at most "
217 << OP::ARITY_MAX <<
" arguments";
218 throw std::invalid_argument(oss.str());
220 return std::unique_ptr<AOperation<T>>(
new OP(args));
222 _operations.insert(std::make_pair(OP::KEY, f));
226std::unique_ptr<sxeval::AOperation<T>>
230 const auto it = _operations.find(key);
231 if (it == _operations.end()) {
232 throw std::invalid_argument(
"Unknown operation key: " + key);
234 return it->second(args);
241 const auto it = _operations.find(key);
242 if (it == _operations.end()) {
243 throw std::invalid_argument(
"Unknown operation key: " + key);
245 const auto op = it->second(args);
247 return op->getResult();
The AOperation class is an abstract base class for operations in the SXEval library.
Definition AOperation.hpp:22
The IInstruction class is an interface for any instructions.
Definition IInstruction.hpp:21
The OperationsFactory class is used to manage operations.
Definition OperationsFactory.hpp:81
T compute(const std::string &key, const std::vector< IInstruction< T > * > args) const
Compute the result of an operation from its key and arguments.
Definition OperationsFactory.hpp:238
std::unique_ptr< AOperation< T > > create(const std::string &key, const std::vector< IInstruction< T > * > args)
Instantiate an operation from its key and arguments.
Definition OperationsFactory.hpp:227
OperationsFactory()
Default constructor.
Definition OperationsFactory.hpp:138
std::enable_if< std::is_base_of< sxeval::AOperation< T >, OP >::value >::type add()
Register an operation.
Definition OperationsFactory.hpp:198
Definition AOperation.hpp:8
std::enable_if< std::is_unsigned< T >::value, T >::type Absolute(const T &a)
Perform an absolute value operation on types T.
Definition utils.hpp:262