Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-21 09:58:01

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 // Author     : M.Frank
0011 //
0012 //==========================================================================
0013 //
0014 // NOTE:
0015 //
0016 // This is an internal include file. It should only be included to 
0017 // instantiate code. Otherwise the BasicGrammar include file should be
0018 // sufficient for all practical purposes.
0019 //
0020 //==========================================================================
0021 #ifndef DD4HEP_GRAMMARPARSED_H
0022 #define DD4HEP_GRAMMARPARSED_H
0023 
0024 #if defined(DD4HEP_GRAMMARUNPARSED_H)
0025 #error "The header files GrammarParsed.h and GrammarUnparsed.h may not be included in the same compilation unit!"
0026 #endif
0027 
0028 /// Framework include files
0029 #include <DD4hep/Grammar.h>
0030 #include <DD4hep/Printout.h>
0031 #include <Parsers/Parsers.h>
0032 #include <Evaluator/Evaluator.h>
0033 
0034 /// C/C++ include files
0035 #include <string>
0036 #include <sstream>
0037 #include <vector>
0038 #include <list>
0039 #include <set>
0040 #include <map>
0041 #include <deque>
0042 
0043 // Forward declarations
0044 
0045 /// Namespace for the AIDA detector description toolkit
0046 namespace dd4hep {
0047 
0048   /// Alignments internal namespace declaration
0049   namespace detail  {
0050 
0051     std::string grammar_pre_parse_map(const std::string& in);
0052     std::string grammar_pre_parse_cont(const std::string& in);
0053     std::string grammar_pre_parse_obj(const std::string& in);
0054     std::pair<int,double> grammar_evaluate_item(std::string val);
0055 
0056     /// PropertyGrammar overload: Retrieve value from string
0057     template <typename TYPE> bool grammar_fromString(const BasicGrammar& gr, void* ptr, const std::string& val)   {
0058       int sc = 0;
0059       TYPE temp;
0060       try   {
0061 #ifdef DD4HEP_DEBUG_PROPERTIES
0062         std::cout << "Parsing " << val << std::endl;
0063 #endif
0064         sc = ::dd4hep::Parsers::parse(temp, val);
0065         if ( sc )   {
0066           *(TYPE*)ptr = std::move(temp);
0067           return true;
0068         }
0069       }
0070       catch (...)  {
0071       }
0072 #ifdef DD4HEP_DEBUG_PROPERTIES
0073       std::cout << "Parsing " << val << "FAILED" << std::endl;
0074 #endif
0075       if ( !sc ) sc = gr.evaluate(&temp,val);
0076 #ifdef DD4HEP_DEBUG_PROPERTIES
0077       std::cout << "Sc=" << sc << "  Converting value: " << val 
0078                 << " to type " << typeid(TYPE).name() 
0079                 << std::endl;
0080 #endif
0081       if ( sc )   {
0082         *(TYPE*)ptr = std::move(temp);
0083         return true;
0084       }
0085       BasicGrammar::invalidConversion(val, typeid(TYPE));
0086       return false;
0087     }
0088 
0089     /// Serialize a property to a string
0090     template <typename TYPE> std::string grammar_str(const BasicGrammar&, const void* ptr)  {
0091       std::stringstream string_rep;
0092       Parsers::toStream(*(TYPE*)ptr,string_rep);
0093       return string_rep.str();
0094     }
0095 
0096     /// Item evaluator
0097     template <typename T> inline int eval_item(T* ptr, const std::string& val)  {
0098       /// First try to parse the value with spirit.
0099       try   {
0100         T temp;
0101         int sc = ::dd4hep::Parsers::parse(temp,val);
0102         if ( sc )  {
0103           *ptr = temp;
0104           return 1;
0105         }
0106       }
0107       catch (...)  {
0108       }
0109       /// If this failed: try to evaluate it with the expression parser
0110       auto result = grammar_evaluate_item(val);
0111       if (result.first == tools::Evaluator::OK) {
0112         *ptr = (T)result.second;
0113         return 1;
0114       }
0115       /// This also failed: Return error.
0116       return 0;
0117     }
0118 
0119     /// String evaluator: Nothing to do!
0120     template <> inline int eval_item<std::string>(std::string* ptr, const std::string& val)  {
0121       *ptr = val;
0122       return 1;
0123     }
0124 
0125     /// Insertion function for std vectors
0126     template <typename TYPE> static int fill_data(std::vector<TYPE>* p,const std::vector<std::string>& temp)  {
0127       TYPE val;
0128       const BasicGrammar& grammar = BasicGrammar::instance<TYPE>();
0129       for(auto i=std::begin(temp); i != std::end(temp); ++i)  {
0130         if ( !grammar.fromString(&val,*i) )
0131           return 0;
0132         p->emplace_back(val);
0133       }
0134       return 1;
0135     }
0136 
0137     /// Insertion function for std lists
0138     template <typename TYPE> static int fill_data(std::list<TYPE>* p,const std::vector<std::string>& temp)  {
0139       TYPE val;
0140       const BasicGrammar& grammar = BasicGrammar::instance<TYPE>();
0141       for(auto i=std::begin(temp); i != std::end(temp); ++i)  {
0142         if ( !grammar.fromString(&val,*i) )
0143           return 0;
0144         p->emplace_back(val);
0145       }
0146       return 1;
0147     }
0148 
0149     /// Insertion function for std sets
0150     template <typename TYPE> static int fill_data(std::set<TYPE>* p,const std::vector<std::string>& temp)  {
0151       TYPE val;
0152       const BasicGrammar& grammar = BasicGrammar::instance<TYPE>();
0153       for(auto i=std::begin(temp); i != std::end(temp); ++i)  {
0154         if ( !grammar.fromString(&val,*i) )
0155           return 0;
0156         p->emplace(val);
0157       }
0158       return 1;
0159     }
0160 
0161     /// Insertion function for std deque
0162     template <typename TYPE> static int fill_data(std::deque<TYPE>* p,const std::vector<std::string>& temp)  {
0163       TYPE val;
0164       const BasicGrammar& grammar = BasicGrammar::instance<TYPE>();
0165       for(auto i=std::begin(temp); i != std::end(temp); ++i)  {
0166         if ( !grammar.fromString(&val,*i) )
0167           return 0;
0168         p->emplace_back(val);
0169       }
0170       return 1;
0171     }
0172 
0173     /// Insertion function for std maps
0174     template <typename KEY, typename TYPE> static int fill_data(std::map<KEY,TYPE>* p,const std::vector<std::string>& temp)  {
0175       std::pair<KEY,TYPE> val;
0176       const BasicGrammar& grammar = BasicGrammar::instance<std::pair<KEY,TYPE> >();
0177       for(auto i=std::begin(temp); i != std::end(temp); ++i)  {
0178         if ( !grammar.fromString(&val,*i) )
0179           return 0;
0180         p->emplace(val);
0181       }
0182       return 1;
0183     }
0184 
0185     /// Container evaluator
0186     template <typename TYPE> static int eval_map(TYPE* p, const std::string& str)  {
0187       std::vector<std::string> buff;
0188       p->clear();
0189       int sc = Parsers::parse(buff,str);
0190       if ( sc )  {
0191         return fill_data(p,buff);
0192       }
0193       else   {
0194         TYPE temp;
0195         std::map<std::string,std::string> map_buff;
0196         // If we get called from python, the values and keys are already in string form
0197         sc = 0;
0198         try  {
0199           sc = ::dd4hep::Parsers::parse(map_buff,str);
0200         }
0201         catch(...)    {
0202         }
0203         if ( !sc )  {
0204           // Otherwise stringyfy the values
0205           std::string temp_str = grammar_pre_parse_map(str);
0206           try  {
0207             sc = ::dd4hep::Parsers::parse(map_buff,temp_str);
0208           }
0209           catch(...)    {
0210           }
0211         }
0212         if ( sc )   {
0213           for(const auto& _o : map_buff )    {
0214             typename TYPE::key_type    _k  {};
0215             typename TYPE::mapped_type _v  {};
0216             eval_item(&_k, _o.first);
0217             eval_item(&_v, _o.second);
0218             p->emplace(_k,_v);
0219           }
0220           return 1;
0221         }
0222       }
0223       return 0;
0224     }
0225 
0226     /// Container evaluator
0227     template <typename TYPE> static int eval_container(TYPE* p, const std::string& str)  {
0228       std::vector<std::string> buff;
0229       int sc = Parsers::parse(buff,str);
0230       if ( sc )  {
0231         return fill_data(p,buff);
0232       }
0233       else   {
0234         TYPE temp;
0235         /// First try with the simple object string transformation
0236         std::string temp_str = grammar_pre_parse_obj(str);
0237         sc = ::dd4hep::Parsers::parse(temp,temp_str);
0238         if ( sc )   {
0239           *p = std::move(temp);
0240           return 1;
0241         }
0242         /// Now the more complicated one:
0243         temp_str = grammar_pre_parse_cont(str);
0244         sc = ::dd4hep::Parsers::parse(temp,temp_str);
0245         if ( sc )   {
0246           *p = std::move(temp);
0247           return 1;
0248         }
0249         buff.clear();
0250         sc = Parsers::parse(buff,temp_str);
0251         if ( sc )  {
0252           return fill_data(p,buff);
0253         }
0254       }
0255       return 0;
0256     }
0257 
0258     /// Item evaluator
0259     template <typename T,typename Q> inline int eval_pair(std::pair<T,Q>* ptr, std::string str)  {
0260       const BasicGrammar& grammar = BasicGrammar::instance<std::pair<T,Q> >();
0261       if ( !grammar.fromString(ptr,str) ) return 0;
0262       return 1;
0263     }
0264 
0265     /// Object evaluator
0266     template<typename T> inline int eval_obj(T* ptr, const std::string& str)  {
0267       return BasicGrammar::instance<T>().fromString(ptr,grammar_pre_parse_obj(str));
0268     }
0269 
0270     template<typename T> inline int grammar_eval(const BasicGrammar&, void*, const std::string&) { return 0; }
0271   }
0272   
0273   /// Standarsd constructor
0274   template <typename TYPE> const BasicGrammar& BasicGrammar::instance()  {
0275     static Grammar<TYPE> *s_gr = 0;
0276     if ( 0 != s_gr )  {
0277       return *s_gr;
0278     }
0279     static Grammar<TYPE> gr;
0280     if ( 0 == gr.specialization.bind       ) gr.specialization.bind       = detail::constructObject<TYPE>;
0281     if ( 0 == gr.specialization.copy       ) gr.specialization.copy       = detail::copyObject<TYPE>;
0282     if ( 0 == gr.specialization.fromString )  {
0283       gr.specialization.fromString = detail::grammar_fromString<TYPE>;
0284       gr.specialization.eval       = detail::grammar_eval<TYPE>;
0285       gr.specialization.str        = detail::grammar_str<TYPE>;
0286     }
0287     s_gr = &gr;
0288     return *s_gr;
0289   }
0290 }      // End namespace dd4hep
0291 
0292 #define DD4HEP_PARSER_GRAMMAR_CNAME(serial,name)  namespace_dd4hep__grammar_##serial##_##name
0293 
0294 #define DD4HEP_DEFINE_PARSER_GRAMMAR_EVAL(xx,func)                      \
0295   namespace dd4hep { namespace detail {                                 \
0296       template<> int grammar_eval<xx>(const BasicGrammar&, void* _p, const std::string& _v) { \
0297         return func ((xx*)_p,_v);                                       \
0298       }}}
0299 
0300 
0301 #define DD4HEP_DEFINE_PARSER_GRAMMAR_INSTANCE(serial,xx)                \
0302   namespace dd4hep {                                                    \
0303     template class Grammar< xx >;                                       \
0304     template BasicGrammar const& BasicGrammar::instance< xx >();        \
0305     template const GrammarRegistry& GrammarRegistry::pre_note<xx>(int); \
0306   }                                                                     \
0307   namespace DD4HEP_PARSER_GRAMMAR_CNAME(serial,0) {                     \
0308     static auto s_reg = ::dd4hep::GrammarRegistry::pre_note< xx >(1);   \
0309   }
0310 
0311 #define DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,ctxt,xx,func)        \
0312   DD4HEP_DEFINE_PARSER_GRAMMAR_EVAL(xx,func)                            \
0313   DD4HEP_DEFINE_PARSER_GRAMMAR_INSTANCE(DD4HEP_PARSER_GRAMMAR_CNAME(serial,ctxt),xx)
0314 
0315 #if defined(DD4HEP_HAVE_ALL_PARSERS)
0316 #define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_SERIAL(serial,xx,eval_func)   \
0317   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,1,x,eval_func)             \
0318   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,2,std::vector<xx>, eval_container) \
0319   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,3,std::list<xx>,   eval_container) \
0320   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,4,std::set<xx>,    eval_container) \
0321   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,5,std::deque<xx>,  eval_container) \
0322   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,6,dd4hep::detail::Primitive<xx>::int_map_t,      eval_container) \
0323   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,7,dd4hep::detail::Primitive<xx>::ulong_map_t,    eval_container) \
0324   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,8,dd4hep::detail::Primitive<xx>::string_map_t,   eval_container) \
0325   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,9,dd4hep::detail::Primitive<xx>::int_pair_t,     eval_pair) \
0326   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,10,dd4hep::detail::Primitive<xx>::ulong_pair_t,  eval_pair) \
0327   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,11,dd4hep::detail::Primitive<xx>::string_pair_t, eval_pair) 
0328 
0329 #define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_VL_SERIAL(serial,xx,eval_func) \
0330   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,12,xx,eval_func)           \
0331   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,13,std::vector<xx>,eval_container) \
0332   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,14,std::list<xx>,eval_container)   
0333 
0334 #define DD4HEP_DEFINE_PARSER_GRAMMAR_U_CONT_SERIAL(serial,xx)           \
0335   DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_SERIAL(serial,xx,eval_item)         \
0336   DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_SERIAL(serial,unsigned xx,eval_item)
0337 
0338 #else
0339 
0340 #define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_SERIAL(serial,xx,eval_func)   \
0341   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,1,xx,eval_func)            \
0342   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,2,std::vector<xx>, eval_container) \
0343   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,3,std::list<xx>,   eval_container) \
0344   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,4,std::set<xx>,    eval_container) \
0345   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,5,dd4hep::detail::Primitive<xx>::int_map_t,     eval_map) \
0346   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,6,dd4hep::detail::Primitive<xx>::string_map_t,  eval_map) \
0347   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,7,dd4hep::detail::Primitive<xx>::int_pair_t,    eval_pair) \
0348   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,8,dd4hep::detail::Primitive<xx>::string_pair_t, eval_pair) 
0349 
0350 #define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_ROOTMATH(serial,xx,eval_func) \
0351   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,1,xx,eval_func)            \
0352   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,2,std::vector<xx>, eval_container) \
0353   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,3,std::list<xx>,   eval_container) \
0354   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,4,std::set<xx>,    eval_container) \
0355   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,5,dd4hep::detail::Primitive<xx>::int_map_t,     eval_container) \
0356   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,6,dd4hep::detail::Primitive<xx>::string_map_t,  eval_container) \
0357   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,7,dd4hep::detail::Primitive<xx>::int_pair_t,    eval_pair) \
0358   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,8,dd4hep::detail::Primitive<xx>::string_pair_t, eval_pair) 
0359 
0360 #define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_VL_SERIAL(serial,xx,eval_func) \
0361   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,9,xx,eval_func)            \
0362   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,10,std::vector<xx>,eval_container) \
0363   DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,11,std::list<xx>,eval_container)   
0364 
0365 #define DD4HEP_DEFINE_PARSER_GRAMMAR_U_CONT_SERIAL(serial,xx)   \
0366   DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_SERIAL(serial,xx,eval_item)
0367 
0368 #endif
0369 
0370 #define DD4HEP_DEFINE_PARSER_GRAMMAR(xx,func)               DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(__LINE__,__LINE__,xx,func)
0371 #define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(xx,eval_func)     DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_SERIAL(__LINE__,xx,eval_func)
0372 #define DD4HEP_DEFINE_PARSER_GRAMMAR_ROOTMATH(xx,eval_func) DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_ROOTMATH(__LINE__,xx,eval_func)
0373 #define DD4HEP_DEFINE_PARSER_GRAMMAR_U_CONT(xx)             DD4HEP_DEFINE_PARSER_GRAMMAR_U_CONT_SERIAL(__LINE__,xx)
0374 #define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_VL(xx,eval_func)  DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_VL_SERIAL(__LINE__,xx,eval_func)
0375 #define DD4HEP_DEFINE_PARSER_GRAMMAR_DUMMY(xx,func)         DD4HEP_DEFINE_PARSER_GRAMMAR_DUMMY_SERIAL(__LINE__,xx,func)
0376 
0377 #endif // DD4HEP_GRAMMARPARSED_H