DD4hep - The AIDA detector description toolkit for high energy physics experiments
DD4hep  Rev:Unversioneddirectory
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
BasicGrammar_inl.h
Go to the documentation of this file.
1 //==========================================================================
2 // AIDA Detector description implementation for LCD
3 //--------------------------------------------------------------------------
4 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
5 // All rights reserved.
6 //
7 // For the licensing terms see $DD4hepINSTALL/LICENSE.
8 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
9 //
10 // Author : M.Frank
11 //
12 //==========================================================================
13 //
14 // NOTE:
15 //
16 // This is an internal include file. It should only be included to
17 // instantiate code. Otherwise the BasicGrammar include file should be
18 // sufficient for all practical purposes.
19 //
20 //==========================================================================
21 #ifndef DD4HEP_DDCORE_BASICGRAMMAR_INL_H
22 #define DD4HEP_DDCORE_BASICGRAMMAR_INL_H
23 
24 // Framework include files
25 #include "DD4hep/Primitives.h"
26 #include "DD4hep/BasicGrammar.h"
27 
28 #ifdef DD4HEP_USE_BOOST
29 #if defined(DD4HEP_PARSER_HEADER)
30 
31 #define DD4HEP_NEED_EVALUATOR
32 // This is the case, if the parsers are externalized
33 // and the DD4hep namespace is renamed!
34 #include DD4HEP_PARSER_HEADER
35 
36 #else
37 
38 #include "XML/Evaluator.h"
39 #include "DD4hep/Parsers.h"
40 #include "DD4hep/ToStream.h"
41 namespace DD4hep { XmlTools::Evaluator& g4Evaluator(); }
42 #endif
43 #endif
44 namespace { static XmlTools::Evaluator& s__eval(DD4hep::g4Evaluator()); }
45 
46 // C/C++ include files
47 #include <string>
48 #include <vector>
49 #include <list>
50 #include <set>
51 #include <map>
52 #include <deque>
53 
55 namespace DD4hep {
56 
58 
63  template <typename TYPE> class Grammar : public BasicGrammar {
65  std::string m_typeName;
66  public:
68  Grammar();
70  virtual ~Grammar();
72  virtual const std::type_info& type() const;
74  virtual const std::string& type_name() const;
76  virtual size_t sizeOf() const;
78  virtual std::string str(const void* ptr) const;
80  virtual bool fromString(void* ptr, const std::string& value) const;
82  virtual int evaluate(void* ptr, const std::string& value) const;
83  };
84 
86  template <typename TYPE> Grammar<TYPE>::Grammar() {
87  m_typeName = typeName(typeid(TYPE));
88  }
89 
91  template <typename TYPE> Grammar<TYPE>::~Grammar() {
92  }
93 
95  template <typename TYPE> const std::type_info& Grammar<TYPE>::type() const {
96  return typeid(TYPE);
97  }
98 
100  template <typename TYPE> const std::string& Grammar<TYPE>::type_name() const {
101  return m_typeName;
102  }
103 
105  template <typename TYPE> size_t Grammar<TYPE>::sizeOf() const {
106  return sizeof(TYPE);
107  }
108 
110  template <typename TYPE> int Grammar<TYPE>::evaluate(void*, const std::string&) const {
111  return 0;
112  }
113 
115  template <typename TYPE> bool Grammar<TYPE>::fromString(void* ptr, const std::string& string_val) const {
116  int sc = 0;
117  TYPE temp;
118 #ifdef DD4HEP_USE_BOOST
119  sc = Parsers::parse(temp,string_val);
120 #endif
121  if ( !sc ) sc = evaluate(&temp,string_val);
122 #if 0
123  std::cout << "Sc=" << sc << " Converting value: " << string_val
124  << " to type " << typeid(TYPE).name()
125  << std::endl;
126 #endif
127  if ( sc ) {
128  *(TYPE*)ptr = temp;
129  return true;
130  }
131 #ifndef DD4HEP_USE_BOOST
132  throw std::runtime_error("This version of DD4HEP is not compiled to use boost::spirit.\n"
133  "To enable elaborated property handling set DD4HEP_USE_BOOST=ON\n"
134  "and BOOST_INCLUDE_DIR=<boost include path>");
135 #else
136  BasicGrammar::invalidConversion(string_val, typeid(TYPE));
137  return false;
138 #endif
139  }
140 
142  template <typename TYPE> std::string Grammar<TYPE>::str(const void* ptr) const {
143 #ifdef DD4HEP_USE_BOOST
144  std::stringstream string_rep;
145  Utils::toStream(*(TYPE*)ptr,string_rep);
146  return string_rep.str();
147 #else
148  if (ptr) {
149  }
150  throw std::runtime_error("This version of DD4HEP is not compiled to use boost::spirit.\n"
151  "To enable elaborated property handling set DD4HEP_USE_BOOST=ON\n"
152  "and BOOST_INCLUDE_DIR=<boost include path>");
153 #endif
154  }
155 
157  static inline std::string pre_parse_obj(const std::string& in) {
158  std::string res = "";
159  res.reserve(1024);
160  for(const char* c = in.c_str(); *c; ++c) {
161  switch(*c) {
162  case '\'':
163  return "Bad object representation";
164  case ',':
165  res += "','";
166  break;
167  case '(':
168  case '[':
169  res += "['";
170  break;
171  case ')':
172  case ']':
173  res += "']";
174  break;
175  default:
176  res += *c;
177  break;
178  }
179  }
180  //cout << "Pre-parsed:" << res << endl;
181  return res;
182  }
183 
185  template <typename TYPE> static int fill_data(std::vector<TYPE>* p,const std::vector<std::string>& temp) {
186  const BasicGrammar& g = BasicGrammar::instance<TYPE>();
187  TYPE val;
188  for(std::vector<std::string>::const_iterator i=temp.begin(); i != temp.end(); ++i) {
189  if ( !g.fromString(&val,*i) )
190  return 0;
191  p->push_back(val);
192  }
193  return 1;
194  }
195 
197  template <typename TYPE> static int fill_data(std::list<TYPE>* p,const std::vector<std::string>& temp) {
198  const BasicGrammar& g = BasicGrammar::instance<TYPE>();
199  TYPE val;
200  for(std::vector<std::string>::const_iterator i=temp.begin(); i != temp.end(); ++i) {
201  if ( !g.fromString(&val,*i) )
202  return 0;
203  p->push_back(val);
204  }
205  return 1;
206  }
207 
209  template <typename TYPE> static int fill_data(std::set<TYPE>* p,const std::vector<std::string>& temp) {
210  const BasicGrammar& g = BasicGrammar::instance<TYPE>();
211  TYPE val;
212  for(std::vector<std::string>::const_iterator i=temp.begin(); i != temp.end(); ++i) {
213  if ( !g.fromString(&val,*i) )
214  return 0;
215  p->insert(val);
216  }
217  return 1;
218  }
219 
221  template <typename TYPE> static int fill_data(std::deque<TYPE>* p,const std::vector<std::string>& temp) {
222  const BasicGrammar& g = BasicGrammar::instance<TYPE>();
223  TYPE val;
224  for(std::vector<std::string>::const_iterator i=temp.begin(); i != temp.end(); ++i) {
225  if ( !g.fromString(&val,*i) )
226  return 0;
227  p->push_back(val);
228  }
229  return 1;
230  }
231 
233  template <typename KEY, typename TYPE> static int fill_data(std::map<KEY,TYPE>* p,const std::vector<std::string>& temp) {
234  const BasicGrammar& g = BasicGrammar::instance<std::pair<KEY,TYPE> >();
235  std::pair<KEY,TYPE> val;
236  for(std::vector<std::string>::const_iterator i=temp.begin(); i != temp.end(); ++i) {
237  if ( !g.fromString(&val,*i) )
238  return 0;
239  p->insert(val);
240  }
241  return 1;
242  }
243 
245  template <typename TYPE> static int eval_container(TYPE* p, const std::string& str) {
246 #ifdef DD4HEP_USE_BOOST
247  std::vector<std::string> buff;
248  int sc = Parsers::parse(buff,str);
249  if ( sc ) {
250  return fill_data(p,buff);
251  }
252  else {
253  TYPE temp;
254  std::string temp_str = pre_parse_obj(str);
255  sc = Parsers::parse(temp,temp_str);
256  if ( sc ) {
257  *p = temp;
258  return 1;
259  }
260  buff.clear();
261  sc = Parsers::parse(buff,temp_str);
262  if ( sc ) {
263  return fill_data(p,buff);
264  }
265  }
266 #else
267  if ( p && str.empty() ) return 0;
268 #endif
269  return 0;
270  }
271 
273  template <typename T> inline int eval_item(T* p, std::string s) {
274  size_t idx = s.find("(int)");
275  if (idx != std::string::npos)
276  s.erase(idx, 5);
277  while (s[0] == ' ')
278  s.erase(0, 1);
279 #ifdef DD4HEP_USE_BOOST
280  double result = s__eval.evaluate(s.c_str());
281  if (s__eval.status() != XmlTools::Evaluator::OK) {
282  return 0;
283  }
284  *p = (T)result;
285  return 1;
286 #else
287  return 0;
288 #endif
289  }
290 
292  template <> inline int eval_item<std::string>(std::string* p, std::string s) {
293  *p = s;
294  return 1;
295  }
296 
298  template <typename T,typename Q> inline int eval_pair(std::pair<T,Q>* p, std::string s) {
299  const BasicGrammar& g = BasicGrammar::instance<std::pair<T,Q> >();
300  if ( !g.fromString(p,s) ) return 0;
301  return 1;
302  }
303 
305  template<typename T> inline int eval_obj(T* p, const std::string& str) {
306  return BasicGrammar::instance<T>().fromString(p,pre_parse_obj(str));
307  }
308 
311  template<typename T> inline int eval_none(T*, const std::string&) {
312  return 1;
313  }
314  template <typename T> inline int parse_none(T&, const std::string&) {
315  return 1;
316  }
317 
318  // Containers of objects are not handled!
319 
320 } // End namespace DD4hep
321 
322 #define DD4HEP_DEFINE_PARSER_GRAMMAR_TYPE(x) \
323  namespace DD4hep { \
324  template<> const BasicGrammar& BasicGrammar::instance<x>() { static Grammar<x> s; return s;}}
325 
326 #define DD4HEP_DEFINE_PARSER_GRAMMAR_EVAL(x,func) \
327  namespace DD4hep { \
328  template<> int Grammar<x >::evaluate(void* p, const std::string& v) const { return func ((x*)p,v); }}
329 
330 #define DD4HEP_DEFINE_PARSER_GRAMMAR(x,func) \
331  DD4HEP_DEFINE_PARSER_GRAMMAR_TYPE(x) \
332  DD4HEP_DEFINE_PARSER_GRAMMAR_EVAL(x,func)
333 
334 #if defined(DD4HEP_HAVE_ALL_PARSERS)
335 #define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(x,eval_func) \
336  DD4HEP_DEFINE_PARSER_GRAMMAR(x,eval_func) \
337  DD4HEP_DEFINE_PARSER_GRAMMAR(std::vector<x>, eval_container) \
338  DD4HEP_DEFINE_PARSER_GRAMMAR(std::list<x>, eval_container) \
339  DD4HEP_DEFINE_PARSER_GRAMMAR(std::set<x>, eval_container) \
340  DD4HEP_DEFINE_PARSER_GRAMMAR(std::deque<x>, eval_container) \
341  DD4HEP_DEFINE_PARSER_GRAMMAR(DD4hep::Primitive<x>::int_map_t, eval_container) \
342  DD4HEP_DEFINE_PARSER_GRAMMAR(DD4hep::Primitive<x>::ulong_map_t, eval_container) \
343  DD4HEP_DEFINE_PARSER_GRAMMAR(DD4hep::Primitive<x>::string_map_t, eval_container) \
344  DD4HEP_DEFINE_PARSER_GRAMMAR(DD4hep::Primitive<x>::int_pair_t, eval_pair) \
345  DD4HEP_DEFINE_PARSER_GRAMMAR(DD4hep::Primitive<x>::ulong_pair_t, eval_pair) \
346  DD4HEP_DEFINE_PARSER_GRAMMAR(DD4hep::Primitive<x>::string_pair_t, eval_pair)
347 
348 #define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_VL(x,eval_func) \
349  DD4HEP_DEFINE_PARSER_GRAMMAR(x,eval_func) \
350  DD4HEP_DEFINE_PARSER_GRAMMAR(std::vector<x>,eval_container) \
351  DD4HEP_DEFINE_PARSER_GRAMMAR(std::list<x>,eval_container)
352 
353 #define DD4HEP_DEFINE_PARSER_GRAMMAR_U_CONT(x) \
354  DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(x,eval_item) \
355  DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(unsigned x,eval_item)
356 
357 #else
358 
359 #define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(x,eval_func) \
360  DD4HEP_DEFINE_PARSER_GRAMMAR(x,eval_func) \
361  DD4HEP_DEFINE_PARSER_GRAMMAR(std::vector<x>, eval_container) \
362  DD4HEP_DEFINE_PARSER_GRAMMAR(std::list<x>, eval_container) \
363  DD4HEP_DEFINE_PARSER_GRAMMAR(std::set<x>, eval_container) \
364  DD4HEP_DEFINE_PARSER_GRAMMAR(DD4hep::Primitive<x>::int_map_t, eval_container) \
365  DD4HEP_DEFINE_PARSER_GRAMMAR(DD4hep::Primitive<x>::string_map_t, eval_container) \
366  DD4HEP_DEFINE_PARSER_GRAMMAR(DD4hep::Primitive<x>::int_pair_t, eval_pair) \
367  DD4HEP_DEFINE_PARSER_GRAMMAR(DD4hep::Primitive<x>::string_pair_t, eval_pair)
368 
369 #define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_VL(x,eval_func) \
370  DD4HEP_DEFINE_PARSER_GRAMMAR(x,eval_func) \
371  DD4HEP_DEFINE_PARSER_GRAMMAR(std::vector<x>,eval_container) \
372  DD4HEP_DEFINE_PARSER_GRAMMAR(std::list<x>,eval_container)
373 
374 #define DD4HEP_DEFINE_PARSER_GRAMMAR_U_CONT(x) \
375  DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(x,eval_item)
376 
377 #endif
378 
379 #endif /* DD4HEP_DDCORE_BASICGRAMMAR_INL_H */
virtual std::string str(const void *ptr) const
PropertyGrammar overload: Serialize a property to a string.
Grammar()
Standarsd constructor.
virtual ~Grammar()
Default destructor.
static std::string pre_parse_obj(const std::string &in)
Helper function to parse data type.
Base class describing string evaluation to C++ objects using boost::spirit.
Definition: BasicGrammar.h:37
std::string typeName(const std::type_info &type)
ABI information about type names.
Definition: Primitives.cpp:186
TGeoShape * s
Definition: Volumes.cpp:294
static void invalidConversion(const std::type_info &from, const std::type_info &to)
Error callback on invalid conversion.
std::string m_typeName
Cached type information name.
virtual size_t sizeOf() const
Access the object size (sizeof operator)
int eval_obj(T *p, const std::string &str)
Object evaluator.
int eval_item(T *p, std::string s)
Item evaluator.
virtual const std::type_info & type() const
PropertyGrammar overload: Access to the type information.
static int eval_container(TYPE *p, const std::string &str)
Container evaluator.
XmlTools::Evaluator & g4Evaluator()
Concrete type dependent grammar definition.
static int fill_data(std::vector< TYPE > *p, const std::vector< std::string > &temp)
Insertion function for std vectors.
virtual int evaluate(void *ptr, const std::string &value) const
Evaluate string value if possible before calling boost::spirit.
virtual bool fromString(void *ptr, const std::string &value) const =0
Set value from serialized string. On successful data conversion TRUE is returned. ...
static const double g
Definition: DD4hepUnits.h:162
std::ostream & toStream(const Property &result, std::ostream &os)
Evaluator of arithmetic expressions with an extendable dictionary.
Definition: Evaluator.h:38
int parse(Property &result, const std::string &input)
int eval_pair(std::pair< T, Q > *p, std::string s)
Item evaluator.
virtual bool fromString(void *ptr, const std::string &value) const
PropertyGrammar overload: Retrieve value from string.
int parse_none(T &, const std::string &)
int eval_none(T *, const std::string &)
virtual const std::string & type_name() const
Access to the type information name.