18 #include <type_traits>
29 virtual ~DynamicType() {}
32 typedef std::map<const void*, TClass*> ClassMap_t;
33 inline ClassMap_t *GetMap(
const void* p)
35 return (ClassMap_t*)p;
38 inline ClassMap_t::value_type* ToPair(
void*p)
40 return (ClassMap_t::value_type*)p;
47 TIsAProxy::TIsAProxy(
const std::type_info& typ)
48 : fType(&typ), fClass(nullptr), fLast(nullptr),
49 fSubTypesReaders(0), fSubTypesWriteLockTaken(kFALSE),
50 fVirtual(kFALSE), fInit(kFALSE)
52 static_assert(
sizeof(ClassMap_t)<=
sizeof(fSubTypes),
"ClassMap size is to large for array");
54 ::new(fSubTypes) ClassMap_t();
60 TIsAProxy::~TIsAProxy()
62 ClassMap_t* m = GetMap(fSubTypes);
71 void TIsAProxy::SetClass(TClass *cl)
73 GetMap(fSubTypes)->clear();
81 TClass* TIsAProxy::operator()(
const void *obj)
84 if ( !fClass.load() && fType ) {
85 auto cls = TClass::GetClass(*fType);
86 TClass* expected =
nullptr;
87 fClass.compare_exchange_strong(expected,cls);
89 if ( !fClass.load() )
return nullptr;
90 fVirtual = (*fClass).ClassProperty() & kClassHasVirtual;
93 if ( !obj || !fVirtual ) {
98 Long_t offset = **(Long_t**)obj;
100 return fClass.load();
103 DynamicType* ptr = (DynamicType*)obj;
104 const std::type_info* typ = &
typeid(*ptr);
106 if ( typ == fType ) {
107 return fClass.load();
109 auto last = ToPair(fLast.load());
110 if ( last && typ == last->first ) {
114 last = ToPair(FindSubType(typ));
115 if ( last ==
nullptr || last->second ==
nullptr ) {
117 auto cls = TClass::GetClass(*typ);
118 last = ToPair(CacheSubType(typ,cls));
122 return last ==
nullptr?
nullptr: last->second;
128 inline void* TIsAProxy::FindSubType(
const std::type_info* type)
const
130 bool needToWait = kTRUE;
136 if(fSubTypesWriteLockTaken) {
138 while(fSubTypesWriteLockTaken) {}
144 void* returnValue =
nullptr;
145 auto const map = GetMap(fSubTypes);
147 auto found = map->find(type);
148 if(found != map->end()) {
149 returnValue = &(*found);
158 void* TIsAProxy::CacheSubType(
const std::type_info* type, TClass* cls)
161 Bool_t expected = kFALSE;
162 while(! fSubTypesWriteLockTaken.compare_exchange_strong(expected,kTRUE) ) {
167 while(fSubTypesReaders > 0);
169 auto map = GetMap(fSubTypes);
170 auto ret = map->emplace(type,cls);
173 (*ret.first).second = cls;
176 fSubTypesWriteLockTaken = kFALSE;
177 return &(*(ret.first));