From 25259d129a3ead6e76ad42752b74e78906a7cfb6 Mon Sep 17 00:00:00 2001
From: Sebastien Ponce <sebastien.ponce@cern.ch>
Date: Tue, 4 Feb 2020 13:59:30 +0100
Subject: [PATCH] Fixed Grammar declaration location and defined a default
 grammar

Moved all declarations of templated method of Grammar inside Grammar.h
(instead of BasicGrammar_inl.h)
And added the missing default implementation for parse and
BasicGrammar::instance so that the defaults are complete and one does
not need to use DD4HEP_DEFINE_ macros anymroe in most cases
---
 .../include/DD4hep/detail/BasicGrammar_inl.h  | 71 ----------------
 DDCore/include/DD4hep/detail/Grammar.h        | 81 ++++++++++++++++++-
 2 files changed, 79 insertions(+), 73 deletions(-)

diff --git a/DDCore/include/DD4hep/detail/BasicGrammar_inl.h b/DDCore/include/DD4hep/detail/BasicGrammar_inl.h
index 993ff83ab..89ade560d 100644
--- a/DDCore/include/DD4hep/detail/BasicGrammar_inl.h
+++ b/DDCore/include/DD4hep/detail/BasicGrammar_inl.h
@@ -52,77 +52,6 @@ namespace {  static dd4hep::tools::Evaluator& s__eval(dd4hep::g4Evaluator());  }
 /// Namespace for the AIDA detector description toolkit
 namespace dd4hep {
 
-  /// Standarsd constructor
-  template <typename TYPE> Grammar<TYPE>::Grammar() : BasicGrammar(typeName(typeid(TYPE)))  {
-  }
-
-  /// Default destructor
-  template <typename TYPE> Grammar<TYPE>::~Grammar() {
-  }
-
-  /// PropertyGrammar overload: Access to the type information
-  template <typename TYPE> const std::type_info& Grammar<TYPE>::type() const {
-    return typeid(TYPE);
-  }
-
-  /// Access to the type information
-  template <typename TYPE> bool Grammar<TYPE>::equals(const std::type_info& other_type) const  {
-    return other_type == typeid(TYPE);
-  }
-  
-  /// Access the object size (sizeof operator)
-  template <typename TYPE> size_t Grammar<TYPE>::sizeOf() const   {
-    return sizeof(TYPE);
-  }
-
-  /// Bind opaque address to object
-  template <typename TYPE> void Grammar<TYPE>::bind(void* pointer)  const  {
-    new(pointer) TYPE();
-  }
-
-  /// Evaluate string value if possible before calling boost::spirit
-  template <typename TYPE> int Grammar<TYPE>::evaluate(void*, const std::string&) const {
-    return 0;
-  }
-
-  /// PropertyGrammar overload: Retrieve value from string
-  template <typename TYPE> bool Grammar<TYPE>::fromString(void* ptr, const std::string& string_val) const {
-    int sc = 0;
-    TYPE temp;
-    sc = ::dd4hep::Parsers::parse(temp,string_val);
-    if ( !sc ) sc = evaluate(&temp,string_val);
-#if 0
-    std::cout << "Sc=" << sc << "  Converting value: " << string_val 
-              << " to type " << typeid(TYPE).name() 
-              << std::endl;
-#endif
-    if ( sc )   {
-      *(TYPE*)ptr = temp;
-      return true;
-    }
-    BasicGrammar::invalidConversion(string_val, typeid(TYPE));
-    return false;
-  }
-
-  /// Serialize a property to a string
-  template <typename TYPE> std::string Grammar<TYPE>::str(const void* ptr) const {
-    std::stringstream string_rep;
-    Utils::toStream(*(TYPE*)ptr,string_rep);
-    return string_rep.str();
-  }
-
-  /// Opaque object destructor
-  template <typename TYPE> void Grammar<TYPE>::destruct(void* pointer) const   {
-    TYPE* obj = (TYPE*)pointer;
-    obj->~TYPE();
-  }
-
-  /// Opaque object destructor
-  template <typename TYPE> void Grammar<TYPE>::copy(void* to, const void* from) const   {
-    const TYPE* from_obj = (const TYPE*)from;
-    new (to) TYPE(*from_obj);
-  }
-
   /// Helper function to parse data type
   static inline std::string pre_parse_obj(const std::string& in)   {
     std::string res = "";
diff --git a/DDCore/include/DD4hep/detail/Grammar.h b/DDCore/include/DD4hep/detail/Grammar.h
index a2b6f79ef..51bea4997 100644
--- a/DDCore/include/DD4hep/detail/Grammar.h
+++ b/DDCore/include/DD4hep/detail/Grammar.h
@@ -23,6 +23,8 @@
 
 // Framework include files
 #include "DD4hep/BasicGrammar.h"
+#include "Parsers/spirit/Parsers.h"
+#include "Parsers/spirit/ToStream.h"
 
 /// Namespace for the AIDA detector description toolkit
 namespace dd4hep {
@@ -38,9 +40,10 @@ namespace dd4hep {
     
     friend class BasicGrammar;
     /// Default destructor
-    virtual ~Grammar();
+    virtual ~Grammar() {};
     /// Standard constructor
-    Grammar();
+    Grammar() : BasicGrammar(typeName(typeid(TYPE))) {}
+
 
   public:
 
@@ -67,4 +70,78 @@ namespace dd4hep {
     virtual int evaluate(void* ptr, const std::string& value) const;
   };
 }
+
+/// PropertyGrammar overload: Access to the type information
+template <typename TYPE> const std::type_info& dd4hep::Grammar<TYPE>::type() const {
+  return typeid(TYPE);
+}
+
+/// Access to the type information
+template <typename TYPE> bool dd4hep::Grammar<TYPE>::equals(const std::type_info& other_type) const  {
+  return other_type == typeid(TYPE);
+}
+
+/// Access the object size (sizeof operator)
+template <typename TYPE> size_t dd4hep::Grammar<TYPE>::sizeOf() const   {
+  return sizeof(TYPE);
+}
+
+/// Bind opaque address to object
+template <typename TYPE> void dd4hep::Grammar<TYPE>::bind(void* pointer)  const  {
+  new(pointer) TYPE();
+}
+
+/// Evaluate string value if possible before calling boost::spirit
+template <typename TYPE> int dd4hep::Grammar<TYPE>::evaluate(void*, const std::string&) const {
+  return 0;
+}
+
+/// default empty parsing function for types not having a specialization
+namespace dd4hep {
+  namespace Parsers {
+    template<typename TYPE>
+    int parse(TYPE&, const std::string&) {
+      return 1;
+    }
+  }
+}
+
+/// PropertyGrammar overload: Retrieve value from string
+template <typename TYPE> bool dd4hep::Grammar<TYPE>::fromString(void* ptr, const std::string& string_val) const {
+  int sc = 0;
+  TYPE temp;
+  sc = dd4hep::Parsers::parse(temp,string_val);
+  if ( !sc ) sc = evaluate(&temp,string_val);
+  if ( sc )   {
+    *(TYPE*)ptr = temp;
+    return true;
+  }
+  BasicGrammar::invalidConversion(string_val, typeid(TYPE));
+  return false;
+}
+
+/// Serialize a property to a string
+template <typename TYPE> std::string dd4hep::Grammar<TYPE>::str(const void* ptr) const {
+  std::stringstream string_rep;
+  Utils::toStream(*(TYPE*)ptr,string_rep);
+  return string_rep.str();
+}
+
+/// Opaque object destructor
+template <typename TYPE> void dd4hep::Grammar<TYPE>::destruct(void* pointer) const   {
+  TYPE* obj = (TYPE*)pointer;
+  obj->~TYPE();
+}
+
+/// Opaque object destructor
+template <typename TYPE> void dd4hep::Grammar<TYPE>::copy(void* to, const void* from) const   {
+  const TYPE* from_obj = (const TYPE*)from;
+  new (to) TYPE(*from_obj);
+}
+
+/// default intanciation of BasicGrammar, using Grammar concrete class
+template<typename TYPE> const dd4hep::BasicGrammar& dd4hep::BasicGrammar::instance() {
+  static dd4hep::Grammar<TYPE> gr;
+  return gr;
+}
 #endif  /* DD4HEP_DDCORE_DETAIL_GRAMMAR_H */
-- 
GitLab