Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:29:06

0001 #include "FWCore/Reflection/interface/ObjectWithDict.h"
0002 
0003 #include "FWCore/Reflection/interface/BaseWithDict.h"
0004 #include "FWCore/Reflection/interface/MemberWithDict.h"
0005 #include "FWCore/Reflection/interface/TypeWithDict.h"
0006 
0007 #ifndef _LIBCPP_VERSION
0008 #include <cxxabi.h>
0009 #endif
0010 
0011 namespace edm {
0012 
0013   ObjectWithDict ObjectWithDict::byType(TypeWithDict const& type) {
0014     ObjectWithDict obj(type.construct());
0015     return obj;
0016   }
0017 
0018   ObjectWithDict::ObjectWithDict() : type_(), address_(nullptr) {}
0019 
0020   ObjectWithDict::ObjectWithDict(TypeWithDict const& type, void* address) : type_(type), address_(address) {}
0021 
0022   ObjectWithDict::ObjectWithDict(std::type_info const& ti, void* address)
0023       : type_(TypeWithDict(ti)), address_(address) {}
0024 
0025   ObjectWithDict::operator bool() const { return bool(type_) && (address_ != nullptr); }
0026 
0027   void* ObjectWithDict::address() const { return address_; }
0028 
0029   TypeWithDict ObjectWithDict::typeOf() const { return type_; }
0030 
0031   class DummyVT {
0032   public:
0033     virtual ~DummyVT();
0034   };
0035 
0036   DummyVT::~DummyVT() {}
0037 
0038   TypeWithDict ObjectWithDict::dynamicType() const {
0039     if (!type_.isVirtual()) {
0040       return type_;
0041     }
0042     // Use a dirty trick, force the typeid() operator
0043     // to consult the virtual table stored at address_.
0044     return TypeWithDict::byTypeInfo(typeid(*(DummyVT*)address_));
0045   }
0046 
0047   ObjectWithDict ObjectWithDict::get(std::string const& memberName) const {
0048     return type_.dataMemberByName(memberName).get(*this);
0049   }
0050 
0051   ObjectWithDict ObjectWithDict::castObject(TypeWithDict const& to) const {
0052     TypeWithDict from = typeOf();
0053 
0054     // Same type
0055     if (from == to) {
0056       return *this;
0057     }
0058 
0059     if (to.hasBase(from)) {  // down cast
0060 #ifndef _LIBCPP_VERSION
0061       // use the internal dynamic casting of the compiler (e.g. libstdc++.so)
0062       void* address = abi::__dynamic_cast(address_,
0063                                           static_cast<abi::__class_type_info const*>(&from.typeInfo()),
0064                                           static_cast<abi::__class_type_info const*>(&to.typeInfo()),
0065                                           -1);
0066       return ObjectWithDict(to, address);
0067 #else
0068       return ObjectWithDict(to, address_);
0069 #endif
0070     }
0071 
0072     if (from.hasBase(to)) {  // up cast
0073       size_t offset = from.getBaseClassOffset(to);
0074       size_t address = reinterpret_cast<size_t>(address_) + offset;
0075       return ObjectWithDict(to, reinterpret_cast<void*>(address));
0076     }
0077 
0078     // if everything fails return the dummy object
0079     return ObjectWithDict();
0080   }  // castObject
0081 
0082   //ObjectWithDict
0083   //ObjectWithDict::construct() const {
0084   //  TypeWithDict ty(type_);
0085   //  TClass* cl = ty.getClass();
0086   //  if (cl != nullptr) {
0087   //    return ObjectWithDict(ty, cl->New());
0088   //  }
0089   //  return ObjectWithDict(ty, new char[ty.size()]);
0090   //}
0091 
0092   void ObjectWithDict::destruct(bool dealloc) const {
0093     TClass* cl = type_.getClass();
0094     if (cl != nullptr) {
0095       cl->Destructor(address_, !dealloc);
0096       //if (dealloc) {
0097       //  address_ = nullptr;
0098       //}
0099       return;
0100     }
0101     if (dealloc) {
0102       delete[] reinterpret_cast<char*>(address_);
0103       //address_ = nullptr;
0104     }
0105   }
0106 
0107 }  // namespace edm