mbxmlutils  1.3.0
Multi-Body XML Utils
eval.h
1#ifndef _MBXMLUTILS_EVAL_H_
2#define _MBXMLUTILS_EVAL_H_
3
4#include <fmatvec/atom.h>
5#include <boost/filesystem.hpp>
6#include <xercesc/util/XercesDefs.hpp>
7#include <mbxmlutilshelper/dom.h>
8#include <mbxmlutilshelper/thislinelocation.h>
9#include <unordered_map>
10#include <stack>
11#include "mbxmlutilshelper/utils.h"
12
13#define MBXMLUTILS_EVAL_CONCAT1(X, Y) X##Y
14#define MBXMLUTILS_EVAL_CONCAT(X, Y) MBXMLUTILS_EVAL_CONCAT1(X, Y)
15#define MBXMLUTILS_EVAL_APPENDLINE(X) MBXMLUTILS_EVAL_CONCAT(X, __LINE__)
16
18#define MBXMLUTILS_EVAL_REGISTER(T) \
19 namespace { \
20 struct Reg { \
21 Reg() { Eval::registerEvaluator<T>(); } \
22 } MBXMLUTILS_EVAL_APPENDLINE(regDummy); \
23 }
24
25// Exception wrapping for DOMEvalException.
26// Rethrow a exception as DOMEvalException with context e, a DOMEvalException is just rethrown unchanged.
27#define MBXMLUTILS_RETHROW_AS_DOMEVALEXCEPTION(e) \
28 catch(MBXMLUtils::DOMEvalException &ex) { \
29 throw; \
30 } \
31 catch(const std::exception &ex) { \
32 throw DOMEvalException(ex.what(), e); \
33 }
34
35namespace XERCES_CPP_NAMESPACE {
36 class DOMElement;
37 class DOMAttr;
38 class DOMDocument;
39}
40
41namespace MBXMLUtils {
42
43bool tryDouble2Int(double d, int &i);
44
46class CodeString : public std::string {
47 public:
48 CodeString(const std::string &str) : std::string(str) {}
49};
50
51// Store the current directory in the ctor an restore in the dtor
53 public:
55 dir=MBXMLUtils::current_path();
56 }
58 MBXMLUtils::current_path(dir);
59 }
60 private:
61 boost::filesystem::path dir;
62};
63
64class Eval;
65
68 public:
70 NewParamLevel(std::shared_ptr<Eval> oe_, bool newLevel_=true);
73
74 NewParamLevel(const NewParamLevel& other) = delete; // copy constructor
75 NewParamLevel(NewParamLevel&& other) = delete; // move constructor
76 NewParamLevel& operator=(const NewParamLevel& other) = delete; // copy assignment
77 NewParamLevel& operator=(NewParamLevel&& other) = delete; // move assignment
78 protected:
79 static void* operator new(std::size_t); // no heap allocation allowed
80 static void* operator new[](std::size_t); // no heap allocation allowed
81
82 std::shared_ptr<Eval> oe;
83 bool newLevel;
84};
85
87class Eval : public std::enable_shared_from_this<Eval>, virtual public fmatvec::Atom {
88 public:
89 friend class NewParamLevel;
90
93 enum ValueType {
94 ScalarType,
95 VectorType,
96 MatrixType,
97 StringType,
98 FunctionType
99 };
100
102 using Value = std::shared_ptr<void>;
103
104 static boost::filesystem::path installPath;
105
106 protected:
108 Eval(std::vector<boost::filesystem::path> *dependencies_);
109 public:
111 ~Eval() override;
112
113 Eval(const Eval& other) = delete; // copy constructor
114 Eval(Eval&& other) = delete; // move constructor
115 Eval& operator=(const Eval& other) = delete; // copy assignment
116 Eval& operator=(Eval&& other) = delete; // move assignment
117
122 virtual void garbageCollect() {};
123
125 static std::shared_ptr<Eval> createEvaluator(const std::string &evalName, std::vector<boost::filesystem::path> *dependencies_=nullptr);
126
127 // Register a new evaluator.
128 template<class E>
129 static void registerEvaluator() {
130 getEvaluators()[E::getNameStatic()]=&newEvaluator<E>;
131 }
132
134 virtual std::string getName() const=0;
135
137 void addParam(const std::string &paramName, const Value& value);
141 void addParamSet(const xercesc::DOMElement *e);
142
145 virtual void addImport(const std::string &code, const xercesc::DOMElement *e, const std::string &action="")=0;
146
149 Value eval(const xercesc::DOMElement *e);
150
154 Value eval(const xercesc::DOMAttr *a);
155
158 Value eval(const std::string &str, const xercesc::DOMElement *e=nullptr, bool skipRet=false);
159
161 void checkIfValueMatchesElement(const Value& value, const xercesc::DOMElement *e);
162
230 template<typename T>
231 T cast(const Value &value) const;
232
234 virtual std::string getStringRepresentation(const Value &x) const;
235
242 virtual bool valueIsOfType(const Value &value, ValueType type) const=0;
243
247 Value stringToValue(const std::string &str, const xercesc::DOMElement *e=nullptr, bool fullEval=true, bool skipRet=false) const;
248
254 template<class T>
255 Value create(const T& v) const;
256
263 template<class T>
264 std::string createSourceCode(const T& v) const;
265
267 virtual std::map<boost::filesystem::path, std::pair<boost::filesystem::path, bool> >& requiredFiles() const=0;
268
272 virtual void convertIndex(Value &v, bool evalTo1Based)=0;
273
275 static void setValue(xercesc::DOMElement *e, const Value &v);
276
290 virtual Value callFunction(const std::string &name, const std::vector<Value>& args) const=0;
291
292 size_t getStackSize() { assert(paramStack.size()==importStack.size()); return paramStack.size(); }
293
294 protected:
296 virtual Value createFunctionIndep(int dim) const = 0;
298 virtual Value createFunctionDep(const std::vector<Value>& v) const=0;
300 virtual Value createFunctionDep(const std::vector<std::vector<Value> >& v) const=0;
302 virtual Value createFunction(const std::vector<Value> &indeps, const Value &dep) const = 0;
303
305 void pushContext();
306
308 void popContext();
309
310 std::vector<boost::filesystem::path> *dependencies;
311
312 // map of the current parameters
313 std::unordered_map<std::string, Value> currentParam;
314 // stack of parameters
315 std::stack<std::unordered_map<std::string, Value> > paramStack;
316
317 // current imports
318 std::unordered_map<std::string, Value> currentImport;
319 // stack of imports
320 std::stack<std::unordered_map<std::string, Value> > importStack;
321
323 virtual Value fullStringToValue(const std::string &str, const xercesc::DOMElement *e, bool skipRet=false) const=0;
324
326 std::string partialStringToString(const std::string &str, const xercesc::DOMElement *e) const;
327
328 template<class E>
329 static std::shared_ptr<Eval> newEvaluator(std::vector<boost::filesystem::path>* dependencies_) {
330 return std::shared_ptr<E>(new E(dependencies_));
331 }
332
333 void addStaticDependencies(const xercesc::DOMElement *e) const;
334
335 static void printEvaluatorMsg(const std::ostringstream &str, MsgType msgType);
336
337 private:
338 // virtual spezialization of cast(const Value &value)
339 virtual double cast_double (const Value &value) const=0;
340 virtual std::vector<double> cast_vector_double (const Value &value) const=0;
341 virtual std::vector<std::vector<double> > cast_vector_vector_double(const Value &value) const=0;
342 virtual std::string cast_string (const Value &value) const=0;
343 // spezialization of cast(const Value &value)
344 CodeString cast_CodeString (const Value &value) const;
345 int cast_int (const Value &value) const;
346
347 // virtual spezialization of create(...)
348 virtual Value create_double (const double& v) const=0;
349 virtual Value create_vector_double (const std::vector<double>& v) const=0;
350 virtual Value create_vector_vector_double (const std::vector<std::vector<double> >& v) const=0;
351 virtual Value create_string (const std::string& v) const=0;
352
353 // virtual spezialization of createSourceCode(...)
354 virtual std::string createSourceCode_double (const double& v) const=0;
355 virtual std::string createSourceCode_vector_double (const std::vector<double>& v) const=0;
356 virtual std::string createSourceCode_vector_vector_double (const std::vector<std::vector<double> >& v) const=0;
357 virtual std::string createSourceCode_string (const std::string& v) const=0;
358
359 virtual std::string serializeFunction(const Value &x) const = 0;
360
361 Value handleUnit(const xercesc::DOMElement *e, const Value &ret);
362
363 static std::map<std::string, std::string> units;
364
365 static std::map<std::string, std::function<std::shared_ptr<Eval>(std::vector<boost::filesystem::path>*)> >& getEvaluators();
366
367};
368
369// specializations
370template<> std::string Eval::cast<std::string>(const Value &value) const;
371template<> CodeString Eval::cast<CodeString>(const Value &value) const;
372template<> double Eval::cast<double>(const Value &value) const;
373template<> int Eval::cast<int>(const Value &value) const;
374template<> std::vector<double> Eval::cast<std::vector<double> >(const Value &value) const;
375template<> std::vector<std::vector<double> > Eval::cast<std::vector<std::vector<double> > >(const Value &value) const;
376
377// spezializations for create
378template<> Eval::Value Eval::create<double> (const double& v) const;
379template<> Eval::Value Eval::create<std::vector<double> > (const std::vector<double>& v) const;
380template<> Eval::Value Eval::create<std::vector<std::vector<double> > > (const std::vector<std::vector<double> >& v) const;
381template<> Eval::Value Eval::create<std::string> (const std::string& v) const;
382
383// spezializations for createSourceCode
384template<> std::string Eval::createSourceCode<double> (const double& v) const;
385template<> std::string Eval::createSourceCode<std::vector<double> > (const std::vector<double>& v) const;
386template<> std::string Eval::createSourceCode<std::vector<std::vector<double> > > (const std::vector<std::vector<double> >& v) const;
387template<> std::string Eval::createSourceCode<std::string> (const std::string& v) const;
388
389} // end namespace MBXMLUtils
390
391#endif
A dummy object representing a value as string in the syntax of the Eval (xmlflat).
Definition: eval.h:46
Definition: eval.h:87
std::string createSourceCode(const T &v) const
virtual std::string getName() const =0
Get the type of this evaluator.
ValueType
Definition: eval.h:93
void addParam(const std::string &paramName, const Value &value)
Add a value to the current parameters.
Definition: eval.cc:252
std::shared_ptr< void > Value
Typedef for a shared value.
Definition: eval.h:102
static std::shared_ptr< Eval > createEvaluator(const std::string &evalName, std::vector< boost::filesystem::path > *dependencies_=nullptr)
Create a evaluator.
Definition: eval.cc:116
virtual Value callFunction(const std::string &name, const std::vector< Value > &args) const =0
~Eval() override
Destructor.
T cast(const Value &value) const
void popContext()
Overwrite the current context with the top level context from the internal stack.
Definition: eval.cc:205
virtual Value createFunctionIndep(int dim) const =0
create a function independent variable. If dim == 0 a scalar is created else a vector.
virtual void convertIndex(Value &v, bool evalTo1Based)=0
virtual Value createFunctionDep(const std::vector< std::vector< Value > > &v) const =0
create a matrix function dependent
virtual std::map< boost::filesystem::path, std::pair< boost::filesystem::path, bool > > & requiredFiles() const =0
return a list of all required files of the evaluator (excluding dependent files of libraries)
void checkIfValueMatchesElement(const Value &value, const xercesc::DOMElement *e)
Check if the type of the value 'value' matches the type of DOMElement 'e'.
Definition: eval.cc:601
virtual std::string getStringRepresentation(const Value &x) const
Returns a evaluator specific string representation of x. This is only useful for display to the user.
Definition: eval.cc:743
static void setValue(xercesc::DOMElement *e, const Value &v)
Set value on DOMElement (is used by Eval::cast)
Definition: eval.cc:756
Value eval(const xercesc::DOMElement *e)
Value stringToValue(const std::string &str, const xercesc::DOMElement *e=nullptr, bool fullEval=true, bool skipRet=false) const
Definition: eval.cc:687
virtual void garbageCollect()
Definition: eval.h:122
virtual void addImport(const std::string &code, const xercesc::DOMElement *e, const std::string &action="")=0
Value create(const T &v) const
virtual Value fullStringToValue(const std::string &str, const xercesc::DOMElement *e, bool skipRet=false) const =0
evaluate the string str using the current parameters and return the result.
void pushContext()
Push the current context to a internal stack.
Definition: eval.cc:200
void addParamSet(const xercesc::DOMElement *e)
Definition: eval.cc:256
virtual bool valueIsOfType(const Value &value, ValueType type) const =0
Value eval(const std::string &str, const xercesc::DOMElement *e=nullptr, bool skipRet=false)
virtual Value createFunctionDep(const std::vector< Value > &v) const =0
create a vector function dependent
virtual Value createFunction(const std::vector< Value > &indeps, const Value &dep) const =0
create a Function with n independents and a dependent function (scalar, vector or matrix)
std::string partialStringToString(const std::string &str, const xercesc::DOMElement *e) const
evaluate str partially and return result as an std::string
Definition: eval.cc:639
Eval(std::vector< boost::filesystem::path > *dependencies_)
Constructor.
Create a new parameter level for a evaluator which is automatically resetted if the scope of this obj...
Definition: eval.h:67
~NewParamLevel()
Reset to the previous parameter level.
Definition: eval.cc:91
NewParamLevel(std::shared_ptr< Eval > oe_, bool newLevel_=true)
Create a new parameter level in the evaluator oe_.
Definition: eval.h:52