diff --git a/DDCore/include/DD4hep/Grammar.h b/DDCore/include/DD4hep/Grammar.h index b8f6c29a11b83a2cdc6b53ef84076d1a7bb593ba..d518b09cbcf78122063ade918f9f64a2f54792a2 100644 --- a/DDCore/include/DD4hep/Grammar.h +++ b/DDCore/include/DD4hep/Grammar.h @@ -57,15 +57,18 @@ namespace dd4hep { public: typedef unsigned long long int key_type; /// Instance type name - const std::string name; + const std::string name; /// Instance hash code - const key_type hash_value = 0; + const key_type hash_value = 0; /// Cached TClass reference for speed improvements - mutable TClass* root_class = 0; + mutable TClass* root_class = 0; /// Cached TDataType information for fundamental types - mutable int root_data_type = -1; + mutable int root_data_type = -1; /// Initialization flag - mutable bool inited = false; + mutable bool inited = false; + /// ABI cast object + const Cast& abi_cast; + /// Structure to be filled if automatic object parsing from string is supposed to be supported struct specialization_t { /// Bind opaque address to object @@ -94,7 +97,7 @@ namespace dd4hep { protected: /// Default constructor - BasicGrammar(const std::string& typ); + BasicGrammar(const Cast& cast, const std::string& typ); /// Default destructor virtual ~BasicGrammar(); @@ -123,6 +126,8 @@ namespace dd4hep { key_type hash() const { return hash_value; } /// Access to the type information name const std::string& type_name() const { return name; } + /// Access ABI object cast + virtual const Cast& cast() const { return abi_cast; } /// Access ROOT data type for fundamentals int data_type() const { if ( inited ) return root_data_type; @@ -182,7 +187,7 @@ namespace dd4hep { /// Standarsd constructor template <typename TYPE> Grammar<TYPE>::Grammar() - : BasicGrammar(typeName(typeid(TYPE))) + : BasicGrammar(Cast::instance<TYPE>(), typeName(typeid(TYPE))) { } diff --git a/DDCore/include/DD4hep/OpaqueData.h b/DDCore/include/DD4hep/OpaqueData.h index e614e3e6f93b9235f9278eefcde38e43dae7b5f2..3819727f85b3c8ba76b253ef6d7ab81c8751c335 100644 --- a/DDCore/include/DD4hep/OpaqueData.h +++ b/DDCore/include/DD4hep/OpaqueData.h @@ -56,18 +56,6 @@ namespace dd4hep { /// Pointer to object data void* pointer = 0; //! No ROOT persistency - /// Helper class to perform resolution of non-polymorph types - /** - * - * \author M.Frank - * \version 1.0 - * \ingroup DD4HEP_CONDITIONS - */ - class dyn_cast { - public: - virtual ~dyn_cast() = default; - }; - public: /// Create data block from string representation bool fromString(const std::string& rep); @@ -168,25 +156,19 @@ namespace dd4hep { /// Generic getter. Specify the exact type, not a polymorph type template <typename T> inline T& OpaqueData::as() { - union _cast { - void* ptr; - dyn_cast* dynamic; - _cast(void* p) { ptr = p; } - } cast(this->pointer); - T* obj = dynamic_cast<T*>(cast.dynamic); - if ( obj ) return *obj; + if ( grammar ) { + T* obj = (T*)(grammar->cast().apply_dynCast(Cast::instance<T>(), this->pointer)); + if ( obj ) return *obj; + } throw std::bad_cast(); } /// Generic getter (const version). Specify the exact type, not a polymorph type template <typename T> inline const T& OpaqueData::as() const { - union _cast { - const void* ptr; - const dyn_cast* dynamic; - _cast(const void* p) { ptr = p; } - } cast(this->pointer); - const T* obj = dynamic_cast<const T*>(cast.dynamic); - if ( obj ) return *obj; + if ( grammar ) { + const T* obj = (const T*)(grammar->cast().apply_dynCast(Cast::instance<T>(), this->pointer)); + if ( obj ) return *obj; + } throw std::bad_cast(); } diff --git a/DDCore/include/Parsers/Primitives.h b/DDCore/include/Parsers/Primitives.h index 410fe129a25d5dd4f26962067c0030c231255184..3494b4e0d05ded2fa7901b905506d35a6271ab6a 100644 --- a/DDCore/include/Parsers/Primitives.h +++ b/DDCore/include/Parsers/Primitives.h @@ -99,105 +99,6 @@ namespace dd4hep { /// Throw exception when handles are check for validity void notImplemented(const std::string& msg); - /// Class to perform dynamic casts using unknown pointers. - /** @class Cast Primitives.h dd4hep/Primitives.h - * - * It is mandatory that the pointers referred do actually - * support the asked functionalty. - * Miracles also I cannot do..... - * - * @author M.Frank - * @date 13.08.2013 - */ - class Cast { - public: - typedef void (*destroy_t)(void*); - typedef void* (*cast_t)(const void*); -#ifdef __CINT__ - const std::type_info* type; -#else - const std::type_info& type; -#endif -#ifdef __APPLE__ - cast_t cast; - protected: - /// Initializing Constructor - Cast(const std::type_info& t, cast_t c); - public: - template <typename TYPE> static void* _cast(const void* arg) { - TYPE* ptr = (TYPE*)arg; - ptr = dynamic_cast<TYPE*>(ptr); - return (void*)ptr; - } - /// Instantiation method - template <typename TYPE> static Cast& instance() { - static Cast c(typeid(TYPE),_cast<TYPE>); - return c; - } -#else - const void* abi_class; - protected: - /// Initializing Constructor - Cast(const std::type_info& t); - /// Instantiation method - template <typename TYPE> static Cast& instance() { - static Cast c(typeid(TYPE)); - return c; - } -#endif - /// Defautl destructor - virtual ~Cast(); - - public: - /// Apply cast using typeinfo instead of dynamic_cast - void* apply_dynCast(const Cast& to, const void* ptr) const; - /// Apply cast using typeinfo instead of dynamic_cast - void* apply_upCast(const Cast& to, const void* ptr) const; - /// Apply cast using typeinfo instead of dynamic_cast - void* apply_downCast(const Cast& to, const void* ptr) const; - }; - - /// Class to perform dynamic casts using unknown pointers. - /** @class ComponentCast Primitives.h dd4hep/Primitives.h - * - * It is mandatory that the pointers referred do actually - * support the asked functionalty. - * Miracles also I cannot do..... - * - * @author M.Frank - * @date 13.08.2013 - */ - class ComponentCast : public Cast { - public: - typedef void (*destroy_t)(void*); - destroy_t destroy; - - private: - /// Defautl destructor - virtual ~ComponentCast(); - template <typename TYPE> static void _destroy(void* arg) { - TYPE* ptr = (TYPE*)arg; - if (ptr) delete ptr; - } -#ifdef __APPLE__ - /// Initializing Constructor - ComponentCast(const std::type_info& t, destroy_t d, cast_t c); - public: - template <typename TYPE> static ComponentCast& instance() { - static ComponentCast c(typeid(TYPE),_destroy<TYPE>,_cast<TYPE>); - return c; - } -#else - /// Initializing Constructor - ComponentCast(const std::type_info& t, destroy_t d); - public: - template <typename TYPE> static ComponentCast& instance() { - static ComponentCast c(typeid(TYPE),_destroy<TYPE>); - return c; - } -#endif - }; - /// Convert volumeID to string format (016X) std::string volumeID(VolumeID vid); @@ -682,7 +583,6 @@ namespace dd4hep { { return v.second; } }; - /// Data structure to manipulate a bitmask held by reference and represented by an integer /** * @author M.Frank @@ -724,5 +624,114 @@ namespace dd4hep { template <typename T> ReferenceBitMask<T>::ReferenceBitMask(T& arg) : mask(arg) {} } // End namespace detail + + /// Class to perform dynamic casts using unknown pointers. + /** @class Cast Primitives.h dd4hep/Primitives.h + * + * It is mandatory that the pointers referred do actually + * support the asked functionalty. + * Miracles also I cannot do..... + * + * @author M.Frank + * @date 13.08.2013 + */ + class Cast { + public: +#ifdef __CINT__ + const std::type_info* type; +#else + const std::type_info& type; +#endif +#ifdef __APPLE__ + typedef void* (*cast_t)(const void*); + cast_t cast; + protected: + /// Initializing Constructor + Cast(const std::type_info& t, cast_t c); + public: + template <typename TYPE> static void* _cast(const void* arg) { + TYPE* ptr = (TYPE*)arg; + ptr = dynamic_cast<TYPE*>(ptr); + return (void*)ptr; + } + /// Instantiation method + template <typename TYPE> static const Cast& instance() { + static Cast c(typeid(TYPE),_cast<TYPE>); + return c; + } +#else + const void* abi_class; + protected: + /// Initializing Constructor + Cast(const std::type_info& t); + public: + /// Instantiation method + template <typename TYPE> static const Cast& instance() { + static Cast c(typeid(TYPE)); + return c; + } +#endif + protected: + /// Defautl destructor + virtual ~Cast(); + + public: + /// Apply cast using typeinfo instead of dynamic_cast + void* apply_dynCast(const Cast& to, const void* ptr) const; + /// Apply cast using typeinfo instead of dynamic_cast + void* apply_upCast(const Cast& to, const void* ptr) const; + /// Apply cast using typeinfo instead of dynamic_cast + void* apply_downCast(const Cast& to, const void* ptr) const; + }; + + /// Class to perform dynamic casts using unknown pointers. + /** @class ComponentCast Primitives.h dd4hep/Primitives.h + * + * It is mandatory that the pointers referred do actually + * support the asked functionalty. + * Miracles also I cannot do..... + * + * @author M.Frank + * @date 13.08.2013 + */ + class ComponentCast { + public: + + typedef void (*destroy_t)(void*); + destroy_t destroy; + private: + const Cast& cast; + + private: + /// Initializing Constructor + ComponentCast(const Cast& c, destroy_t d) : destroy(d), cast(c) {} + /// Defautl destructor + virtual ~ComponentCast() = default; + /// Function template to create destructor + template <typename TYPE> static void _destroy(void* arg) { + TYPE* ptr = (TYPE*)arg; + if (ptr) delete ptr; + } + public: + template <typename TYPE> static ComponentCast& instance() { + static ComponentCast c(Cast::instance<TYPE>(),_destroy<TYPE>); + return c; + } + const std::type_info& type() const { + return cast.type; + } + /// Apply cast using typeinfo instead of dynamic_cast + void* apply_dynCast(const ComponentCast& to, const void* ptr) const { + return cast.apply_dynCast(to.cast, ptr); + } + /// Apply cast using typeinfo instead of dynamic_cast + void* apply_upCast(const ComponentCast& to, const void* ptr) const { + return cast.apply_upCast(to.cast, ptr); + } + /// Apply cast using typeinfo instead of dynamic_cast + void* apply_downCast(const ComponentCast& to, const void* ptr) const { + return cast.apply_downCast(to.cast, ptr); + } + }; } // End namespace dd4hep #endif // PARSERS_PRIMITIVES_H diff --git a/DDCore/src/Grammar.cpp b/DDCore/src/Grammar.cpp index 806c9581210a9b04a94a1a6ea706982d9ba90779..317de336d6fdccaff9cd860585b94980abb21c42 100644 --- a/DDCore/src/Grammar.cpp +++ b/DDCore/src/Grammar.cpp @@ -53,8 +53,8 @@ bool dd4hep::BasicGrammar::specialization_t::operator==(const specialization_t& } /// Default constructor -dd4hep::BasicGrammar::BasicGrammar(const std::string& typ) - : name(typ), hash_value(dd4hep::detail::hash64(typ)) +dd4hep::BasicGrammar::BasicGrammar(const Cast& c, const std::string& typ) + : name(typ), hash_value(dd4hep::detail::hash64(typ)), abi_cast(c) { auto j = prenote_registry().find(hash_value); if ( j != prenote_registry().end() ) { diff --git a/DDCore/src/Parsers/Exceptions.cpp b/DDCore/src/Parsers/Exceptions.cpp deleted file mode 100755 index 29d1f7397525edc161b871eaa81c345afa08df4f..0000000000000000000000000000000000000000 --- a/DDCore/src/Parsers/Exceptions.cpp +++ /dev/null @@ -1,29 +0,0 @@ -//========================================================================== -// AIDA Detector description implementation -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see $DD4hepINSTALL/LICENSE. -// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. -// -// Author : M.Frank -// -//========================================================================== - -// Framework include files -#include "Parsers/Exceptions.h" -#include "Parsers/Primitives.h" - -using namespace std; -using namespace dd4hep; - -string unrelated_type_error::msg(const type_info& typ1, const type_info& typ2, const string& text) { - string m = "The types " + typeName(typ1) + " and " + typeName(typ2) + " are not related. " + text; - return m; -} - -string unrelated_value_error::msg(const type_info& typ, const string& text) { - string m = "The type " + typeName(typ) + " cannot be converted: " + text; - return m; -} diff --git a/DDCore/src/Parsers/Primitives.cpp b/DDCore/src/Parsers/Primitives.cpp deleted file mode 100755 index 7af056d34f6021310a1124a45d823314e7dbec65..0000000000000000000000000000000000000000 --- a/DDCore/src/Parsers/Primitives.cpp +++ /dev/null @@ -1,531 +0,0 @@ -//========================================================================== -// AIDA Detector description implementation -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see $DD4hepINSTALL/LICENSE. -// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. -// -// Author : M.Frank -// -//========================================================================== - -// Framework include files -#include "Parsers/Primitives.h" -#include "Parsers/Exceptions.h" -#include "Parsers/Printout.h" - -// C/C++ include files -#include <algorithm> -#include <functional> -#include <numeric> -#include <stdexcept> -#include <cstdint> -#include <cstring> -#include <map> - -#if defined(__linux) || defined(__APPLE__) -#include <cxxabi.h> -#ifndef __APPLE__ -typedef abi::__class_type_info class_t; -using abi::__dynamic_cast; -#endif -#endif - -/// Local Utilities -namespace { - -#if 0 -//----------------------------------------------------------------------------- -// MurmurHash2, 64-bit versions, by Austin Appleby -// -// The same caveats as 32-bit MurmurHash2 apply here - beware of alignment -// and endian-ness issues if used across multiple platforms. - inline uint64_t murmur_hash_64 ( const void * key, int len) { -#define seed 0xFEEDBABE - typedef unsigned long long int uint64; - -#if INTPTR_MAX == INT32_MAX - const unsigned int * data = (const unsigned int *)key; - const unsigned int m = 0x5bd1e995; - const int r = 24; - - unsigned int h1 = seed ^ len; - unsigned int h2 = 0; - - while(len >= 8) - { - unsigned int k1 = *data++; - k1 *= m; k1 ^= k1 >> r; k1 *= m; - h1 *= m; h1 ^= k1; - len -= 4; - - unsigned int k2 = *data++; - k2 *= m; k2 ^= k2 >> r; k2 *= m; - h2 *= m; h2 ^= k2; - len -= 4; - } - - if(len >= 4) - { - unsigned int k1 = *data++; - k1 *= m; k1 ^= k1 >> r; k1 *= m; - h1 *= m; h1 ^= k1; - len -= 4; - } - - switch(len) - { - case 3: h2 ^= ((unsigned char*)data)[2] << 16; - case 2: h2 ^= ((unsigned char*)data)[1] << 8; - case 1: h2 ^= ((unsigned char*)data)[0]; - h2 *= m; - }; - - h1 ^= h2 >> 18; h1 *= m; - h2 ^= h1 >> 22; h2 *= m; - h1 ^= h2 >> 17; h1 *= m; - h2 ^= h1 >> 19; h2 *= m; - - uint64 h = h1; - - h = (h << 32) | h2; -#elif INTPTR_MAX == INT64_MAX - const uint64* data = (const uint64*)key; - const uint64 m = 0xc6a4a7935bd1e995; - const int r = 47; - - uint64 h = seed ^ (len * m); - - const uint64 * end = data + (len/8); - - while(data != end) - { - uint64 k = *data++; - - k *= m; - k ^= k >> r; - k *= m; - - h ^= k; - h *= m; - } - - const unsigned char * data2 = (const unsigned char*)data; - - switch(len & 7) - { - case 7: h ^= uint64(data2[6]) << 48; - case 6: h ^= uint64(data2[5]) << 40; - case 5: h ^= uint64(data2[4]) << 32; - case 4: h ^= uint64(data2[3]) << 24; - case 3: h ^= uint64(data2[2]) << 16; - case 2: h ^= uint64(data2[1]) << 8; - case 1: h ^= uint64(data2[0]); - h *= m; - }; - - h ^= h >> r; - h *= m; - h ^= h >> r; - -#else -#error "Environment not 32 or 64-bit." -#endif - return h; - } -#endif - - struct FNV1a_64 { - static const unsigned long long int hashinit = 14695981039346656037ull; - static constexpr unsigned long long int doByte(unsigned long long int hash,unsigned char val) - { return (hash ^ val) * 1099511628211ull; } - }; -} - -/// Convert volumeID to string format (016X) -std::string dd4hep::volumeID(VolumeID vid) { - char text[32]; - ::snprintf(text,sizeof(text),"%016llx",vid); - return text; -} - -/// We need it so often: one-at-time 64 bit hash function -unsigned long long int dd4hep::detail::hash64(const char* key) { - //return murmur_hash_64(key, strlen(key)); - unsigned char* str = (unsigned char*)key; - unsigned long long int hash = FNV1a_64::hashinit; - for ( ; *str; ++str) hash = FNV1a_64::doByte(hash, *str); - return hash; -} - -unsigned long long int dd4hep::detail::hash64(const std::string& key) { - //return murmur_hash_64(key.data(), key.length()); - return std::accumulate(begin(key),end(key),FNV1a_64::hashinit,FNV1a_64::doByte); -} - -long int dd4hep::detail::makeTime(int year, int month, int day, - int hour, int minutes, int seconds) -{ - struct tm tm_init; - ::memset(&tm_init,0,sizeof(tm_init)); - tm_init.tm_year = year > 1900 ? year-1900 : year; - tm_init.tm_mon = month; - tm_init.tm_mday = day; - tm_init.tm_hour = hour; - tm_init.tm_min = minutes; - tm_init.tm_sec = seconds; - tm_init.tm_isdst = -1; - long int ti = ::mktime(&tm_init); - if ( ti >= 0 ) return ti; - except("dd4hep","Invalid time data given for conversion to epoch: %d-%d-%d %02d:%02d:%02d", - year, month, day, hour, minutes, seconds); - return ti; -} - -/// Convert date into epoch time (seconds since 1970) -long int dd4hep::detail::makeTime(const std::string& date, const char* fmt) { - struct tm tm; - char* c = ::strptime(date.c_str(),fmt,&tm); - if ( 0 == c ) { - except("dd4hep", - "Invalid time format given for update:%s should be: %s", - date.c_str(), fmt); - } - long ti = ::mktime(&tm); - if ( ti >= 0 ) return ti; - except("dd4hep", - "Invalid time string given for conversion to epoch: %s (fmt='%s')", - date.c_str(), fmt); - return ti; -} - -static const std::string __typeinfoName(const std::type_info& tinfo) { - const char* class_name = tinfo.name(); - std::string result; -#ifdef WIN32 - std::size_t off = 0; - if ( ::strncmp(class_name, "class ", 6) == 0 ) { - // The returned name is prefixed with "class " - off = 6; - } - if ( ::strncmp(class_name, "struct ", 7) == 0 ) { - // The returned name is prefixed with "struct " - off = 7; - } - if ( off != std::string::npos ) { - std::string tmp = class_name + off; - size_t loc = 0; - while( (loc = tmp.find("class ")) != std::string::npos ) { - tmp.erase(loc, 6); - } - loc = 0; - while( (loc = tmp.find("struct ")) != std::string::npos ) { - tmp.erase(loc, 7); - } - result = tmp; - } - else { - result = class_name; - } - // Change any " *" to "*" - while ( (off=result.find(" *")) != std::string::npos ) { - result.replace(off, 2, "*"); - } - // Change any " &" to "&" - while ( (off=result.find(" &")) != std::string::npos ) { - result.replace(off, 2, "&"); - } -#elif defined(sun) - result = class_name; -#elif !defined(__ICC) - if (::strlen(class_name) == 1) { - // See http://www.realitydiluted.com/mirrors/reality.sgi.com/dehnert_engr/cxx/abi.pdf - // for details - switch (class_name[0]) { - case 'v': - result = "void"; - break; - case 'w': - result = "wchar_t"; - break; - case 'b': - result = "bool"; - break; - case 'c': - result = "char"; - break; - case 'h': - result = "unsigned char"; - break; - case 's': - result = "short"; - break; - case 't': - result = "unsigned short"; - break; - case 'i': - result = "int"; - break; - case 'j': - result = "unsigned int"; - break; - case 'l': - result = "long"; - break; - case 'm': - result = "unsigned long"; - break; - case 'x': - result = "long long"; - break; - case 'y': - result = "unsigned long long"; - break; - case 'n': - result = "__int128"; - break; - case 'o': - result = "unsigned __int128"; - break; - case 'f': - result = "float"; - break; - case 'd': - result = "double"; - break; - case 'e': - result = "long double"; - break; - case 'g': - result = "__float128"; - break; - case 'z': - result = "ellipsis"; - break; - } - } - else { - char buff[16 * 1024]; - std::size_t len = sizeof(buff); - int status = 0; - result = __cxxabiv1::__cxa_demangle(class_name, buff, &len, &status); - } -#else - result = class_name; - throw std::runtime_error("CXXABI is missing for ICC!"); -#endif - return result; -} - -std::string dd4hep::typeName(const std::type_info& typ) { - return __typeinfoName(typ); -} - -void dd4hep::invalidHandleError(const std::type_info& type) -{ - throw invalid_handle_exception("Attempt to access invalid object of type "+typeName(type)+" [Invalid Handle]"); -} - -void dd4hep::invalidHandleAssignmentError(const std::type_info& from, - const std::type_info& to) -{ - std::string msg = "Wrong assingment from "; - msg += typeName(from); - msg += " to "; - msg += typeName(to); - msg += " not possible!!"; - throw invalid_handle_exception(msg); -} - -/// Throw exception when handles are check for validity -void dd4hep::notImplemented(const std::string& msg) -{ - std::string m = "The requested feature " + msg + " is not implemented!"; - throw std::runtime_error(m); -} - -void dd4hep::typeinfoCheck(const std::type_info& typ1, const std::type_info& typ2, const std::string& text) -{ - if (typ1 != typ2) { - throw unrelated_type_error(typ1, typ2, text); - } -} - -namespace dd4hep { - namespace detail { - template<> const char* Primitive<bool>::default_format() { return "%d"; } - template<> const char* Primitive<char>::default_format() { return "%c"; } - template<> const char* Primitive<unsigned char>::default_format() { return "%02X"; } - template<> const char* Primitive<short>::default_format() { return "%d"; } - template<> const char* Primitive<unsigned short>::default_format() { return "%04X"; } - template<> const char* Primitive<int>::default_format() { return "%d"; } - template<> const char* Primitive<unsigned int>::default_format() { return "%08X"; } - template<> const char* Primitive<long>::default_format() { return "%ld"; } - template<> const char* Primitive<unsigned long>::default_format() { return "%016X"; } - template<> const char* Primitive<float>::default_format() { return "%f"; } - template<> const char* Primitive<double>::default_format() { return "%g"; } - template<> const char* Primitive<char*>::default_format() { return "%s"; } - template<> const char* Primitive<const char*>::default_format() { return "%s"; } - template<> const char* Primitive<std::string>::default_format() { return "%s"; } - - /// Generic function to convert to string - template <typename T> std::string Primitive<T>::toString(T value) { - char text[1024]; - ::snprintf(text,sizeof(text),default_format(),value); - return text; - } - - /// Convert string to string - template <> std::string Primitive<const char*>::toString(const char* value) { - if ( value ) { - return value; - } - throw std::runtime_error("Failed to convert (char*)NULL to std::string!"); - } - /// Convert string to string - template <> std::string Primitive<char*>::toString(char* value) { - if ( value ) { - return value; - } - throw std::runtime_error("Failed to convert (char*)NULL to std::string!"); - } - /// Convert string to string - template <> std::string Primitive<std::string>::toString(std::string value) { - return value; - } - - template std::string Primitive<bool>::toString(bool value); - template std::string Primitive<char>::toString(char value); - template std::string Primitive<unsigned char>::toString(unsigned char value); - template std::string Primitive<short>::toString(short value); - template std::string Primitive<unsigned short>::toString(unsigned short value); - template std::string Primitive<int>::toString(int value); - template std::string Primitive<unsigned int>::toString(unsigned int value); - template std::string Primitive<long>::toString(long value); - template std::string Primitive<unsigned long>::toString(unsigned long value); - template std::string Primitive<float>::toString(float value); - template std::string Primitive<double>::toString(double value); - } -} - -/// Initializing Constructor -dd4hep::ComponentCast::ComponentCast(const std::type_info& t, destroy_t d, cast_t c) - : type(t), destroy(d), cast(c) { -#ifdef __APPLE__ - abi_class = 0; -#else - abi_class = dynamic_cast<const class_t*>(&type); - if (!abi_class) { - throw std::runtime_error("Class type " + typeName(type) + " is not an abi object type!"); - } -#endif -} - -/// Defautl destructor -dd4hep::ComponentCast::~ComponentCast() { -} - -#if 0 -// Dynamic cast runtime. -// src2dst has the following possible values -// >-1: src_type is a unique public non-virtual base of dst_type -// dst_ptr + src2dst == src_ptr -// -1: unspecified relationship -// -2: src_type is not a public base of dst_type -// -3: src_type is a multiple public non-virtual base of dst_type -extern "C" void* -__dynamic_cast(const void* __src_ptr,// Starting object. - const abi::__class_type_info* __src_type,// Static type of object. - const abi::__class_type_info* __dst_type,// Desired target type. - ptrdiff_t __src2dst);// How src and dst are related. -#endif -#if 0 -#ifndef __APPLE__ -static inline void* cast_wrap(const void* p, - const abi::__class_type_info* src, - const abi::__class_type_info* dst, - ptrdiff_t src2dst) -{ - return abi::__dynamic_cast(p,src,dst,src2dst); -} -#endif -#endif - -/// Apply cast using typeinfo instead of dynamic_cast -void* dd4hep::ComponentCast::apply_dynCast(const ComponentCast& to, const void* ptr) const -{ - if (&to == this) { - return (void*) ptr; - } -#ifdef __APPLE__ - // First try down cast - void *r = (*to.cast)(ptr); - if (r) - return r; - // Now try the up-cast - r = (*cast)(ptr); - if (r) return r; - throw unrelated_type_error(type, to.type, "Failed to apply abi dynamic cast operation!"); -#else - void* r = (void*)ptr; - if ( to.abi_class ) { - bool cast_worked = type.__do_upcast((const class_t*)to.abi_class,&r); - if ( cast_worked ) return r; - r = (void*)ptr; - cast_worked = to.type.__do_upcast((const class_t*)abi_class,&r); - if ( cast_worked ) return r; -#if 0 - const class_t* src_type = (const class_t*)to.abi_class; - if (src_type) { - // First try down cast - void *r = cast_wrap(ptr, src_type, (const class_t*) abi_class, -1); - if ( r ) return r; - // Now try the up-cast - r = cast_wrap(ptr, (const class_t*) abi_class, src_type, -1); - if (r) return r; - } -#endif - throw unrelated_type_error(type, to.type, "Failed to apply abi dynamic cast operation!"); - } - throw unrelated_type_error(type, to.type, "Target type is not an abi class type!"); -#endif -} - -/// Apply cast using typeinfo instead of dynamic_cast -void* dd4hep::ComponentCast::apply_upCast(const ComponentCast& to, const void* ptr) const -{ - if (&to == this) { - return (void*) ptr; - } - return apply_dynCast(to, ptr); -} - -/// Apply cast using typeinfo instead of dynamic_cast -void* dd4hep::ComponentCast::apply_downCast(const ComponentCast& to, const void* ptr) const -{ - if (&to == this) { - return (void*) ptr; - } -#ifdef __APPLE__ - void *r = (*to.cast)(ptr); - if (r) return r; - throw unrelated_type_error(type, to.type, "Failed to apply abi dynamic cast operation!"); -#else - if ( to.abi_class ) { - // Since we have to cast a 'to' pointer up to the real pointer - // no virtual inheritance can be supported! - void* r = (void*)ptr; - bool cast_worked = type.__do_upcast((const class_t*)to.abi_class,&r); - if ( cast_worked ) return r; -#if 0 - void *r = cast_wrap(ptr, src_type, (const class_t*)abi_class, -1); - if (r) return r; -#endif - throw unrelated_type_error(type, to.type, "Failed to apply abi dynamic cast operation!"); - } - throw unrelated_type_error(type, to.type, "Target type is not an abi class type!"); -#endif -} - diff --git a/DDCore/src/Parsers/Printout.cpp b/DDCore/src/Parsers/Printout.cpp deleted file mode 100755 index 27ed3b149454d84c7821bff35ca17297c8859a7d..0000000000000000000000000000000000000000 --- a/DDCore/src/Parsers/Printout.cpp +++ /dev/null @@ -1,414 +0,0 @@ -//========================================================================== -// AIDA Detector description implementation -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see $DD4hepINSTALL/LICENSE. -// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. -// -// Author : M.Frank -// -//========================================================================== - -// Framework include files -#include "Parsers/Printout.h" - -// C/C++ include files -#include <cstring> -#include <cstdarg> -#include <sstream> -#include <stdexcept> - -// Disable some diagnostics for ROOT dictionaries -#ifdef __GNUC__ -#pragma GCC diagnostic ignored "-Wvarargs" -#endif - -using namespace std; - -namespace { - size_t _the_printer_1(void*, dd4hep::PrintLevel lvl, const char* src, const char* text); - size_t _the_printer_2(void* par, dd4hep::PrintLevel lvl, const char* src, const char* fmt, va_list& args); - - std::string print_fmt = "%-16s %5s %s"; - dd4hep::PrintLevel print_lvl = dd4hep::INFO; - void* print_arg = 0; - dd4hep::output_function1_t print_func_1 = 0; - dd4hep::output_function2_t print_func_2 = _the_printer_2; - - const char* print_level(dd4hep::PrintLevel lvl) { - switch(lvl) { - case dd4hep::NOLOG: return "NOLOG"; - case dd4hep::VERBOSE: return "VERB "; - case dd4hep::DEBUG: return "DEBUG"; - case dd4hep::INFO: return "INFO "; - case dd4hep::WARNING: return "WARN "; - case dd4hep::ERROR: return "ERROR"; - case dd4hep::FATAL: return "FATAL"; - case dd4hep::ALWAYS: return " "; - default: - if ( lvl> dd4hep::ALWAYS ) - return print_level(dd4hep::ALWAYS); - return print_level(dd4hep::NOLOG); - } - } - - size_t _the_printer_1(void*, dd4hep::PrintLevel lvl, const char* src, const char* text) { - ::fflush(stdout); - ::fflush(stderr); - cout << flush; - cerr << flush; - size_t len = ::fprintf(stdout, print_fmt.c_str(), src, print_level(lvl), text); - ::fputc('\n',stdout); - return len; - } - - size_t _the_printer_2(void* par, dd4hep::PrintLevel lvl, const char* src, const char* fmt, va_list& args) { - if ( !print_func_1 ) { - char text[4096]; - ::fflush(stdout); - ::fflush(stderr); - cout << flush; - cerr << flush; - ::snprintf(text,sizeof(text),print_fmt.c_str(),src,print_level(lvl),fmt); - size_t len = ::vfprintf(stdout, text, args); - ::fputc('\n',stdout); - return len; - } - char str[4096]; - ::vsnprintf(str, sizeof(str), fmt, args); - return print_func_1(par, lvl, src, str); - } - - string __format(const char* fmt, va_list& args) { - char str[4096]; - ::vsnprintf(str, sizeof(str), fmt, args); - return string(str); - } -} - -/// Helper function to serialize argument list to a single string -/** - * \arg argc [int,read-only] Number of arguments. - * \arg argv [char**,read-only] Argument strings - * \return String containing the concatenated arguments - */ -string dd4hep::arguments(int argc, char** argv) { - stringstream str; - for(int i=0; i<argc;) { - str << argv[i]; - if ( ++i < argc ) str << " "; - } - return str.str(); -} - -/// Calls the display action with a given severity level -/** - * @arg severity [int,read-only] Display severity flag (see enum) - * @arg src [string,read-only] Information source (component, etc.) - * @arg str [stringstream, RW] string stream containing data to be printed. - * Object is reset after use. - * @return Status code indicating success or failure - */ -int dd4hep::printout(PrintLevel severity, const char* src, std::stringstream& str) { - int ret = 1; - if (severity >= print_lvl) { - ret = printout(severity, src, str.str().c_str()); - } - str.str(""); - return ret; -} - -/// Calls the display action with a given severity level -/** - * @arg severity [int,read-only] Display severity flag (see enum) - * @arg src [string,read-only] Information source (component, etc.) - * @arg str [stringstream, RW] string stream containing data to be printed. - * Object is reset after use. - * @return Status code indicating success or failure - */ -int dd4hep::printout(PrintLevel severity, const std::string& src, std::stringstream& str) { - int ret = 1; - if (severity >= print_lvl) { - ret = printout(severity, src, str.str().c_str()); - } - str.str(""); - return ret; -} - -/** Calls the display action - * \arg severity [int,read-only] Display severity flag - * \arg src [string,read-only] Information source (component, etc.) - * \arg fmt [string,read-only] Format string for ellipsis args - * \return Status code indicating success or failure - */ -int dd4hep::printout(PrintLevel severity, const char* src, const char* fmt, ...) { - if (severity >= print_lvl) { - va_list args; - va_start(args, fmt); - printout(severity, src, fmt, args); - va_end(args); - } - return 1; -} - -/** Calls the display action - * \arg severity [int,read-only] Display severity flag - * \arg src [string,read-only] Information source (component, etc.) - * \arg fmt [string,read-only] Format string for ellipsis args - * \return Status code indicating success or failure - */ -int dd4hep::printout(PrintLevel severity, const string& src, const char* fmt, ...) { - if (severity >= print_lvl) { - va_list args; - va_start(args, fmt); - printout(severity, src.c_str(), fmt, args); - va_end(args); - } - return 1; -} - -/** Calls the display action - * \arg severity [int,read-only] Display severity flag - * \arg src [string,read-only] Information source (component, etc.) - * \arg fmt [string,read-only] Format string for ellipsis args - * \return Status code indicating success or failure - */ -int dd4hep::printout(PrintLevel severity, const char* src, const string& fmt, ...) { - if (severity >= print_lvl) { - va_list args; - va_start(args, &fmt); - printout(severity, src, fmt.c_str(), args); - va_end(args); - } - return 1; -} - -/** Calls the display action - * \arg severity [int,read-only] Display severity flag - * \arg src [string,read-only] Information source (component, etc.) - * \arg fmt [string,read-only] Format string for ellipsis args - * \return Status code indicating success or failure - */ -int dd4hep::printout(PrintLevel severity, const string& src, const string& fmt, ...) { - if (severity >= print_lvl) { - va_list args; - va_start(args, &fmt); - printout(severity, src.c_str(), fmt.c_str(), args); - va_end(args); - } - return 1; -} - -/** Calls the display action - * \arg severity [int,read-only] Display severity flag - * \arg src [string,read-only] Information source (component, etc.) - * \arg fmt [string,read-only] Format string for ellipsis args - * \return Status code indicating success or failure - */ -int dd4hep::printout(PrintLevel severity, const char* src, const char* fmt, va_list& args) { - if (severity >= print_lvl) { - print_func_2(print_arg, severity,src,fmt,args); - } - return 1; -} - -/** Calls the display action - * \arg severity [int,read-only] Display severity flag - * \arg src [string,read-only] Information source (component, etc.) - * \arg fmt [string,read-only] Format string for ellipsis args - * \return Status code indicating success or failure - */ -int dd4hep::printout(PrintLevel severity, const string& src, const char* fmt, va_list& args) { - return printout(severity, src.c_str(), fmt, args); -} - -/** Calls the display action - * \arg severity [int,read-only] Display severity flag - * \arg src [string,read-only] Information source (component, etc.) - * \arg fmt [string,read-only] Format string for ellipsis args - * \return Status code indicating success or failure - */ -int dd4hep::printout(PrintLevel severity, const char* src, const string& fmt, va_list& args) { - return printout(severity, src, fmt.c_str(), args); -} - -/** Calls the display action - * \arg severity [int,read-only] Display severity flag - * \arg src [string,read-only] Information source (component, etc.) - * \arg fmt [string,read-only] Format string for ellipsis args - * \return Status code indicating success or failure - */ -int dd4hep::printout(PrintLevel severity, const string& src, const string& fmt, va_list& args) { - return printout(severity, src.c_str(), fmt.c_str(), args); -} - -/** Calls the display action with ERROR and throws an std::runtime_error exception - * \arg src [string,read-only] Information source (component, etc.) - * \arg fmt [string,read-only] Format string for ellipsis args - * \return Status code indicating success or failure - */ -int dd4hep::except(const string& src, const string& fmt, ...) { - va_list args; - va_start(args, &fmt); - return except(src.c_str(),fmt.c_str(), args); -} - -/** Calls the display action with ERROR and throws an std::runtime_error exception - * \arg src [string,read-only] Information source (component, etc.) - * \arg fmt [string,read-only] Format string for ellipsis args - * \return Status code indicating success or failure - */ -int dd4hep::except(const char* src, const char* fmt, ...) { - va_list args; - va_start(args, fmt); - return except(src, fmt, args); -} - -/** Calls the display action with ERROR and throws an std::runtime_error exception - * \arg src [string,read-only] Information source (component, etc.) - * \arg fmt [string,read-only] Format string for ellipsis args - * \arg args [ap_list,read-only] List with variable number of arguments to fill format string. - * \return Status code indicating success or failure - */ -int dd4hep::except(const string& src, const string& fmt, va_list& args) { - string msg = __format(fmt.c_str(), args); - va_end(args); - printout(ERROR, src.c_str(), "%s", msg.c_str()); - // No return. Must call va_end here! - throw runtime_error((src+": "+msg).c_str()); -} - -/** Calls the display action with ERROR and throws an std::runtime_error exception - * \arg src [string,read-only] Information source (component, etc.) - * \arg fmt [string,read-only] Format string for ellipsis args - * \arg args [ap_list,read-only] List with variable number of arguments to fill format string. - * \return Status code indicating success or failure - */ -int dd4hep::except(const char* src, const char* fmt, va_list& args) { - string msg = __format(fmt, args); - va_end(args); - printout(ERROR, src, "%s", msg.c_str()); - // No return. Must call va_end here! - throw runtime_error((string(src)+": "+msg).c_str()); -} - -/** Build exception string - * \arg src [string,read-only] Information source (component, etc.) - * \arg fmt [string,read-only] Format string for ellipsis args - * \return Status code indicating success or failure - */ -string dd4hep::format(const string& src, const string& fmt, ...) { - va_list args; - va_start(args, &fmt); - string str = format(src, fmt, args); - va_end(args); - return str; -} - -/** Build exception string - * \arg src [string,read-only] Information source (component, etc.) - * \arg fmt [string,read-only] Format string for ellipsis args - * \return Status code indicating success or failure - */ -string dd4hep::format(const char* src, const char* fmt, ...) { - va_list args; - va_start(args, fmt); - string str = format(src, fmt, args); - va_end(args); - return str; -} - -/** Build exception string and throw std::runtime_error - * \arg src [string,read-only] Information source (component, etc.) - * \arg fmt [string,read-only] Format string for ellipsis args - * \arg args [ap_list,read-only] List with variable number of arguments to fill format string. - * \return Status code indicating success or failure - */ -string dd4hep::format(const string& src, const string& fmt, va_list& args) { - return format(src.c_str(), fmt.c_str(), args); -} - -/** Build exception string and throw std::runtime_error - * \arg src [string,read-only] Information source (component, etc.) - * \arg fmt [string,read-only] Format string for ellipsis args - * \arg args [ap_list,read-only] List with variable number of arguments to fill format string. - * \return Status code indicating success or failure - */ -string dd4hep::format(const char* src, const char* fmt, va_list& args) { - char str[4096]; - size_t len1 = ::snprintf(str, sizeof(str), "%s: ", src); - size_t len2 = ::vsnprintf(str + len1, sizeof(str) - len1, fmt, args); - if ( len2 > sizeof(str) - len1 ) { - len2 = sizeof(str) - len1 - 1; - str[sizeof(str)-1] = 0; - } - return string(str); -} - -/// Set new print level. Returns the old print level -dd4hep::PrintLevel dd4hep::setPrintLevel(PrintLevel new_level) { - PrintLevel old = print_lvl; - print_lvl = new_level; - return old; -} - -/// Access the current printer level -dd4hep::PrintLevel dd4hep::printLevel() { - return print_lvl; -} - -/// Translate the printer level from string to value -dd4hep::PrintLevel dd4hep::printLevel(const char* value) { - if ( !value ) except("Printout","Invalid printlevel requested [EINVAL: Null-pointer argument]"); - // Explicit values - if ( strcmp(value,"NOLOG") == 0 ) return dd4hep::NOLOG; - if ( strcmp(value,"VERBOSE") == 0 ) return dd4hep::VERBOSE; - if ( strcmp(value,"DEBUG") == 0 ) return dd4hep::DEBUG; - if ( strcmp(value,"INFO") == 0 ) return dd4hep::INFO; - if ( strcmp(value,"WARNING") == 0 ) return dd4hep::WARNING; - if ( strcmp(value,"ERROR") == 0 ) return dd4hep::ERROR; - if ( strcmp(value,"FATAL") == 0 ) return dd4hep::FATAL; - if ( strcmp(value,"ALWAYS") == 0 ) return dd4hep::ALWAYS; - // Numeric values - if ( strcmp(value,"0") == 0 ) return dd4hep::NOLOG; - if ( strcmp(value,"1") == 0 ) return dd4hep::VERBOSE; - if ( strcmp(value,"2") == 0 ) return dd4hep::DEBUG; - if ( strcmp(value,"3") == 0 ) return dd4hep::INFO; - if ( strcmp(value,"4") == 0 ) return dd4hep::WARNING; - if ( strcmp(value,"5") == 0 ) return dd4hep::ERROR; - if ( strcmp(value,"6") == 0 ) return dd4hep::FATAL; - if ( strcmp(value,"7") == 0 ) return dd4hep::ALWAYS; - except("Printout","Unknown printlevel requested:%s",value); - return dd4hep::ALWAYS; -} - -/// Translate the printer level from string to value -dd4hep::PrintLevel dd4hep::printLevel(const std::string& value) { - return printLevel(value.c_str()); -} - -/// Check if this print level would result in some output -bool dd4hep::isActivePrintLevel(int severity) { - return severity >= print_lvl; -} - -/// Set new printout format for the 3 fields: source-level-message. All 3 are strings -string dd4hep::setPrintFormat(const string& new_format) { - string old = print_fmt; - print_fmt = new_format; - return old; -} - -/// Customize printer function -void dd4hep::setPrinter(void* arg, output_function1_t fcn) { - print_arg = arg; - print_func_1 = fcn ? fcn : _the_printer_1; -} - -/// Customize printer function -void dd4hep::setPrinter2(void* arg, output_function2_t fcn) { - print_arg = arg; - print_func_2 = fcn ? fcn : _the_printer_2; -} diff --git a/DDCore/src/Primitives.cpp b/DDCore/src/Primitives.cpp index 6412e130ca6587cfffba0a0e7b8ca4abd92b83b8..a9f34639c7bedac2a4817d11e142ac76627c429e 100644 --- a/DDCore/src/Primitives.cpp +++ b/DDCore/src/Primitives.cpp @@ -414,10 +414,6 @@ namespace dd4hep { /// Initializing Constructor dd4hep::Cast::Cast(const std::type_info& t, cast_t c) : type(t), cast(c) { } -/// Initializing Constructor -dd4hep::ComponentCast::ComponentCast(const std::type_info& t, destroy_t d, cast_t c) - : Cast(t, c), destroy(d) { -} #else /// Initializing Constructor dd4hep::Cast::Cast(const std::type_info& t) : type(t) { @@ -426,20 +422,12 @@ dd4hep::Cast::Cast(const std::type_info& t) : type(t) { throw std::runtime_error("Class type " + typeName(type) + " is not an abi object type!"); } } -/// Initializing Constructor -dd4hep::ComponentCast::ComponentCast(const std::type_info& t, destroy_t d) - : Cast(t), destroy(d) { -} #endif /// Defautl destructor dd4hep::Cast::~Cast() { } -/// Defautl destructor -dd4hep::ComponentCast::~ComponentCast() { -} - /// Apply cast using typeinfo instead of dynamic_cast void* dd4hep::Cast::apply_dynCast(const Cast& to, const void* ptr) const { @@ -473,11 +461,11 @@ void* dd4hep::Cast::apply_dynCast(const Cast& to, const void* ptr) const r = cast_wrap(ptr, (const class_t*) abi_class, src_type, -1); if (r) return r; } +#endif #endif throw unrelated_type_error(type, to.type, "Failed to apply abi dynamic cast operation!"); } throw unrelated_type_error(type, to.type, "Target type is not an abi class type!"); -#endif } /// Apply cast using typeinfo instead of dynamic_cast @@ -515,4 +503,3 @@ void* dd4hep::Cast::apply_downCast(const Cast& to, const void* ptr) const throw unrelated_type_error(type, to.type, "Target type is not an abi class type!"); #endif } - diff --git a/DDG4/lcio/LCIOConversions.cpp b/DDG4/lcio/LCIOConversions.cpp index 607231a44d990445639bc25f365e76b698c2349f..d93aae4ff8b56857739fce8daf7442757c94467d 100644 --- a/DDG4/lcio/LCIOConversions.cpp +++ b/DDG4/lcio/LCIOConversions.cpp @@ -82,7 +82,7 @@ namespace dd4hep { if ( coll ) { typedef pair<arg_t::first_type,Geant4HitCollection*> _A; typedef Geant4Conversion<output_t,_A> _C; - const _C& cnv= _C::converter(coll->type().type); + const _C& cnv= _C::converter(coll->type().type()); return cnv(_A(args.first,coll)); } throw unrelated_type_error(typeid(Geant4HitCollection),typeid(*c), diff --git a/DDG4/src/Geant4Output2ROOT.cpp b/DDG4/src/Geant4Output2ROOT.cpp index db3b74adfc7e0ccfe8d4b4bada2a2b9f675fd130..10a92b70c4c18fb7bc3afd5a5f200bb179b5e9b1 100644 --- a/DDG4/src/Geant4Output2ROOT.cpp +++ b/DDG4/src/Geant4Output2ROOT.cpp @@ -85,14 +85,15 @@ int Geant4Output2ROOT::fill(const string& nam, const ComponentCast& type, void* TBranch* b = 0; Branches::const_iterator i = m_branches.find(nam); if (i == m_branches.end()) { - TClass* cl = TBuffer::GetClass(type.type); + const std::type_info& typ = type.type(); + TClass* cl = TBuffer::GetClass(typ); if (cl) { b = m_tree->Branch(nam.c_str(), cl->GetName(), (void*) 0); b->SetAutoDelete(false); m_branches.emplace(nam, b); } else { - throw runtime_error("No ROOT TClass object availible for object type:" + typeName(type.type)); + throw runtime_error("No ROOT TClass object availible for object type:" + typeName(typ)); } } else { diff --git a/examples/ClientTests/src/Check_ABI_Cast.cpp b/examples/ClientTests/src/Check_ABI_Cast.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ad10d0b62d9764161aea48d2a8e2cf3b5caf0781 --- /dev/null +++ b/examples/ClientTests/src/Check_ABI_Cast.cpp @@ -0,0 +1,139 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework includes +#include "DD4hep/DetFactoryHelper.h" +#include "DD4hep/Printout.h" +#include "DD4hep/Detector.h" +#include "DD4hep/Objects.h" +#include "DD4hep/World.h" + +using namespace dd4hep; +using namespace dd4hep::detail; + +namespace { + + class base_0 { + public: + int data_0 {0}; + base_0() = default; + base_0(base_0&& copy) = default; + base_0(const base_0& copy) = default; + virtual ~base_0() = default; + base_0& operator=(base_0&& copy) = default; + base_0& operator=(const base_0& copy) = default; + }; + + template <typename T> class base_1: virtual public base_0 { + public: + T data_1; + base_1() = default; + base_1(base_1&& copy) = default; + base_1(const base_1& copy) = default; + virtual ~base_1() = default; + base_1& operator=(base_1&& copy) = default; + base_1& operator=(const base_1& copy) = default; + }; + template <typename T> class base_2: virtual public base_0 { + public: + T data_2; + base_2() = default; + base_2(base_2&& copy) = default; + base_2(const base_2& copy) = default; + virtual ~base_2() = default; + base_2& operator=(base_2&& copy) = default; + base_2& operator=(const base_2& copy) = default; + }; + + class payload : virtual public base_1<int>, virtual public base_2<double> { + public: + payload() = default; + payload(payload&& copy) = default; + payload(const payload& copy) = default; + virtual ~payload() = default; + payload& operator=(payload&& copy) = default; + payload& operator=(const payload& copy) = default; + }; +} + +/// Plugin function: Condition program example +/** + * Factory: DD4hep_Conditions_dynamic + * + * \author M.Frank + * \version 1.0 + * \date 01/12/2016 + */ +static int test_example (Detector& /* description */, int /* argc */, char** /* argv */) { + using namespace std; + + payload p; + p.data_0 = 12345; + p.data_1 = 54321; + p.data_2 = 2e1; + + payload* pl = &p; + base_0* b0 = pl; + base_1<int>* b1 = pl; + base_2<double>* b2 = pl; + cout << "Payload: " << (void*)pl + << " b0: " << (void*)b0 + << " b1: " << (void*)b1 + << " b2: " << (void*)b2 + << endl; + + b0 = (base_0*)(Cast::instance<payload>().apply_dynCast(Cast::instance<base_0>(), pl)); + cout << "Payload(payload -> base_0): " << (void*)b0 << " data: " << b0->data_0 << endl; + +#if 0 + pl = (payload*)(Cast::instance<base_0>().apply_dynCast(Cast::instance<payload>(), b0)); + if ( pl ) { + cout << "Payload(base_0 -> payload): " << (void*)pl << " data: " << pl->data_0 << endl; + } + pl = &p; +#endif + + b1 = (base_1<int>*)(Cast::instance<payload>().apply_dynCast(Cast::instance<base_1<int> >(), pl)); + cout << "Payload(payload -> base_1): " << (void*)b1 << " data: " << b1->data_1 << endl; + + b2 = (base_2<double>*)(Cast::instance<payload>().apply_dynCast(Cast::instance<base_2<double> >(), pl)); + cout << "Payload(payload -> base_2): " << (void*)b2 << " data: " << b2->data_2 << endl; + + try { + b0 = (base_0*)(Cast::instance<base_2<double> >().apply_dynCast(Cast::instance<base_0>(), b2)); + cout << "Payload(base_2 -> base_0): " << (void*)b2 << " -> " << (void*)b0 << " data: " << b0->data_0 << endl; + + b2 = (base_2<double>*)(Cast::instance<base_0>().apply_dynCast(Cast::instance<base_2<double> >(), b0)); + cout << "Payload(base_0 -> base_2): " << (void*)b0 << " -> " << (void*)b2 << " data: " << b2->data_2 << endl; + + b0 = (base_0*)(Cast::instance<base_1<int> >().apply_dynCast(Cast::instance<base_0>(), b1)); + cout << "Payload(base_1 -> base_0): " << (void*)b2 << " -> " << (void*)b0 << " data: " << b0->data_0 << endl; + + b1 = (base_1<int>*)(Cast::instance<base_0>().apply_dynCast(Cast::instance<base_1<int> >(), b0)); + cout << "Payload(base_0 -> base_1): " << (void*)b0 << " -> " << (void*)b1 << " data: " << b1->data_1 << endl; + + /// Cross cast fails: + //b1 = (base_1<int>*)(Cast::instance<base_2<double> >().apply_dynCast(Cast::instance<base_1<int> >(), b2)); + //cout << "Payload(base_2 -> base_1): " << (void*)b1 << " data: " << b1->data_1 << endl; + } + catch(const exception& e) { + cout << "bad cast: " << e.what() << endl; + } + + cout << "Test PASSED" << endl; + // All done. + return 1; +} + +// first argument is the type from the xml file +DECLARE_APPLY(DD4hep_test_ABI_cast,test_example) diff --git a/examples/Conditions/CMakeLists.txt b/examples/Conditions/CMakeLists.txt index 9eaec544a058b3d0196cbf8f468dc553029a6bf6..1d42e62759a940d1efa7b14279f9d7d7f204ce04 100644 --- a/examples/Conditions/CMakeLists.txt +++ b/examples/Conditions/CMakeLists.txt @@ -37,6 +37,14 @@ dd4hep_configure_scripts ( Conditions DEFAULT_SETUP WITH_TESTS ) #-------------------------------------------------------------------------- # #---Testing: Load Telescope geometry and read conditions ------------------ +dd4hep_add_test_reg( Conditions_dynamic_payload + COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_Conditions.sh" + EXEC_ARGS geoPluginRun -volmgr -destroy -plugin DD4hep_Conditions_dynamic + REGEX_PASS "Test PASSED" + REGEX_FAIL " ERROR ;EXCEPTION;Exception" + ) +# +#---Testing: Load Telescope geometry and read conditions ------------------ dd4hep_add_test_reg( Conditions_Telescope_cond_dump_by_pool COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_Conditions.sh" EXEC_ARGS geoPluginRun -volmgr -destroy diff --git a/examples/Conditions/src/Conditions_dynamic.cpp b/examples/Conditions/src/Conditions_dynamic.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7b52f9bfa53bf1ac83eb043a2e8c1c9915c8db01 --- /dev/null +++ b/examples/Conditions/src/Conditions_dynamic.cpp @@ -0,0 +1,106 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +/* + Plugin invocation: + ================== + This plugin behaves like a main program. + Invoke the plugin with something like this: + + geoPluginRun -volmgr -destroy -plugin DD4hep_ConditionExample_populate \ + -input file:${DD4hep_DIR}/examples/AlignDet/compact/Telescope.xml + + Populate the conditions store by hand for a set of IOVs. + Then compute the corresponding alignment entries.... + +*/ + +namespace { + + template <typename T> class base_1 { + public: + T data_1; + base_1() = default; + base_1(base_1&& copy) = default; + base_1(const base_1& copy) = default; + virtual ~base_1() = default; + base_1& operator=(base_1&& copy) = default; + base_1& operator=(const base_1& copy) = default; + }; + template <typename T> class base_2 { + public: + T data_2; + base_2() = default; + base_2(base_2&& copy) = default; + base_2(const base_2& copy) = default; + virtual ~base_2() = default; + base_2& operator=(base_2&& copy) = default; + base_2& operator=(const base_2& copy) = default; + }; + class payload : public base_1<int>, public base_2<double> { + public: + payload() = default; + payload(payload&& copy) = default; + payload(const payload& copy) = default; + virtual ~payload() = default; + payload& operator=(payload&& copy) = default; + payload& operator=(const payload& copy) = default; + }; +} + +// Framework include files +#include "ConditionExampleObjects.h" +#include "DD4hep/GrammarUnparsed.h" +#include "DD4hep/Factories.h" + +using namespace std; +using namespace dd4hep; +using namespace dd4hep::ConditionExamples; + +/// Plugin function: Condition program example +/** + * Factory: DD4hep_Conditions_dynamic + * + * \author M.Frank + * \version 1.0 + * \date 01/12/2016 + */ +static int condition_example (Detector& /* description */, int /* argc */, char** /* argv */) { + Condition cond("Cond","payload"); + payload& p = cond.bind<payload>(); + p.data_1 = 1; + p.data_2 = 2e1; + + { + const base_1<int>* b1 = &p; + const base_2<double>* b2 = &p; + cout << "Payload: " << (void*)&p << " b1: " << (void*)b1 << " b2: " << (void*)b2 << endl; + } + + const auto& pl = cond.as<payload>(); + cout << "Payload: " << pl.data_1 << " " << pl.data_2 << endl; + + const auto& b1 = cond.as<base_1<int> >(); + cout << "Payload(base_1): " << (void*)&b1 << " data: " << b1.data_1 << endl; + + const auto& b2 = cond.as<base_2<double> >(); + cout << "Payload(base_2): " << (void*)&b2 << " data: " << b2.data_2 << endl; + + delete cond.ptr(); + cout << "Test PASSED" << endl; + + // All done. + return 1; +} + +// first argument is the type from the xml file +DECLARE_APPLY(DD4hep_Conditions_dynamic,condition_example)