diff --git a/DDG4/include/DDG4/ComponentUtils.h b/DDG4/include/DDG4/ComponentUtils.h index 88b4b660409629950cbcd9f092d2617d35b8b8aa..f214842def41ba78e33d7df196e2ecdcf904fb1b 100644 --- a/DDG4/include/DDG4/ComponentUtils.h +++ b/DDG4/include/DDG4/ComponentUtils.h @@ -58,11 +58,11 @@ namespace DD4hep { } /// Apply cast using typeinfo instead of dynamic_cast - void* apply_dynCast(const std::type_info& to, const void* ptr) const; + void* apply_dynCast(const ComponentCast& to, const void* ptr) const; /// Apply cast using typeinfo instead of dynamic_cast - void* apply_upCast(const std::type_info& to, const void* ptr) const; + void* apply_upCast(const ComponentCast& to, const void* ptr) const; /// Apply cast using typeinfo instead of dynamic_cast - void* apply_downCast(const std::type_info& to, const void* ptr) const; + void* apply_downCast(const ComponentCast& to, const void* ptr) const; }; } // End namespace DD4hep diff --git a/DDG4/include/DDG4/Geant4HitCollection.h b/DDG4/include/DDG4/Geant4HitCollection.h index 65a17d9a260f2735c5903de2462d14ab39c2815a..7393c0850f150dbfa1f51d38c695496e00691930 100644 --- a/DDG4/include/DDG4/Geant4HitCollection.h +++ b/DDG4/include/DDG4/Geant4HitCollection.h @@ -71,7 +71,7 @@ namespace DD4hep { return wrap; } // Need to ensure that the container types are the same! - wrap.first = me.apply_dynCast(cast.type, obj); + wrap.first = me.apply_dynCast(cast, obj); return wrap; } throw std::runtime_error("Invalid hit pointer passed to collection!"); @@ -146,7 +146,8 @@ namespace DD4hep { } /// Automatic conversion to the desired type template <typename TYPE> operator TYPE*() const { - return (TYPE*) m_data.second->cast.apply_downCast(typeid(TYPE), m_data.first); + return (TYPE*) m_data.second-> + cast.apply_downCast(ComponentCast::instance<TYPE>(),m_data.first); } }; diff --git a/DDG4/src/ComponentUtils.cpp b/DDG4/src/ComponentUtils.cpp index 98a7fc40e6aac82b5aba4cec15a491fd7daa29d7..495dc8aa4d20aed969a1e53c0ba24aa43fc310ff 100644 --- a/DDG4/src/ComponentUtils.cpp +++ b/DDG4/src/ComponentUtils.cpp @@ -19,6 +19,7 @@ #ifndef _WIN32 #include <cxxabi.h> typedef abi::__class_type_info class_t; +using abi::__dynamic_cast; #endif using namespace std; @@ -191,48 +192,61 @@ ComponentCast::~ComponentCast() { // -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 __class_type_info* __src_type,// Static type of object. - const __class_type_info* __dst_type,// Desired target type. - ptrdiff_t __src2dst);// How src and dst are related. + 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 +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); + // Don't know what to do on the damned MACs.... + //return (p && src && dst && src2dst) ? 0 : 0; +} + /// Apply cast using typeinfo instead of dynamic_cast -void* ComponentCast::apply_dynCast(const std::type_info& to, const void* ptr) const { - if (&to == &type) { +void* ComponentCast::apply_dynCast(const ComponentCast& to, const void* ptr) const { + if (&to == this) { return (void*) ptr; } - const class_t* src_type = dynamic_cast<const class_t*>(&to); + const class_t* src_type = (const class_t*)to.abi_class; if (src_type) { // First try down cast - void *r = abi::__dynamic_cast(ptr, src_type, (const class_t*) abi_class, -1); + void *r = cast_wrap(ptr, src_type, (const class_t*) abi_class, -1); if (r) return r; // Now try the up-cast - r = abi::__dynamic_cast(ptr, (const class_t*) abi_class, src_type, -1); + r = cast_wrap(ptr, (const class_t*) abi_class, src_type, -1); if (r) return r; - throw unrelated_type_error(type, to, "Failed to apply abi dynamic cast operation!"); + throw unrelated_type_error(type, to.type, "Failed to apply abi dynamic cast operation!"); } - throw unrelated_type_error(type, to, "Target type is not an abi class type!"); + throw unrelated_type_error(type, to.type, "Target type is not an abi class type!"); } /// Apply cast using typeinfo instead of dynamic_cast -void* ComponentCast::apply_upCast(const std::type_info& to, const void* ptr) const { +void* 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* ComponentCast::apply_downCast(const std::type_info& to, const void* ptr) const { - if (&to == &type) { +void* ComponentCast::apply_downCast(const ComponentCast& to, const void* ptr) const { + if (&to == this) { return (void*) ptr; } - const class_t* src_type = dynamic_cast<const class_t*>(&to); + const class_t* src_type = (const class_t*)to.abi_class; if (src_type) { - void *r = abi::__dynamic_cast(ptr, src_type, (const class_t*) abi_class, -1); + void *r = cast_wrap(ptr, src_type, (const class_t*)abi_class, -1); if (r) return r; - throw unrelated_type_error(type, to, "Failed to apply abi dynamic cast operation!"); + throw unrelated_type_error(type, to.type, "Failed to apply abi dynamic cast operation!"); } - throw unrelated_type_error(type, to, "Target type is not an abi class type!"); + throw unrelated_type_error(type, to.type, "Target type is not an abi class type!"); } diff --git a/DDG4/src/Geant4HitCollection.cpp b/DDG4/src/Geant4HitCollection.cpp index 03869842c2024a69fbe250833e34f38fee092831..f2953afe097484e48cbfcc413b12b275c34a6ce1 100644 --- a/DDG4/src/Geant4HitCollection.cpp +++ b/DDG4/src/Geant4HitCollection.cpp @@ -102,7 +102,7 @@ void Geant4HitCollection::releaseData(const ComponentCast& cast, std::vector<voi if (&cast == &m->cast) result->push_back(w.release()); else - result->push_back(m->cast.apply_downCast(cast.type, w.release())); + result->push_back(m->cast.apply_downCast(cast, w.release())); } } @@ -114,7 +114,7 @@ void Geant4HitCollection::getData(const ComponentCast& cast, std::vector<void*>* if (&cast == &m->cast) result->push_back(w.data()); else - result->push_back(m->cast.apply_downCast(cast.type, w.data())); + result->push_back(m->cast.apply_downCast(cast, w.data())); } }