ATLAS Offline Software
Loading...
Searching...
No Matches
xAOD::THolder Class Reference

This class takes care of holding EDM objects in memory. More...

#include <THolder.h>

Inheritance diagram for xAOD::THolder:
Collaboration diagram for xAOD::THolder:

Public Types

enum  TypeKind { OTHER , DATAVECTOR , AUXELEMENT }
 Type of the object held by this one. More...

Public Member Functions

 THolder ()
 Default constructor.
 THolder (void *object, ::TClass *type, ::Bool_t owner=kTRUE)
 Constructor pointing to an object in memory.
 THolder (void *object, const std::type_info &type, ::Bool_t owner=kTRUE)
 Constructor pointing to an object in memory.
 THolder (const void *object, ::TClass *type, ::Bool_t owner=kTRUE)
 Constructor pointing to a const object in memory.
 THolder (const void *object, const std::type_info &type, ::Bool_t owner=kTRUE)
 Constructor pointing to a const object in memory.
 THolder (const THolder &parent)
 Copy constructor.
 THolder (THolder &&parent)
 Move constructor.
virtual ~THolder ()
 The destructor cleans out the memory used by the managed object.
THolderoperator= (const THolder &rhs)
 Assignment operator.
THolderoperator= (THolder &&rhs)
 Move operator.
const void * get () const
 Return a typeless const pointer to the held object.
void * get ()
 Return a typeless pointer to the held object.
void ** getPtr ()
 Return a typeless pointer to the held object's pointer.
virtual void set (void *obj)
 Replace the managed object.
::Bool_t isOwner () const
 Check whether the holder owns its object.
void setOwner (::Bool_t state=kTRUE)
 Set whether the holder should own its object.
::Bool_t isConst () const
 Check if the object is const.
void setConst ()
 Mark the object as const.
virtual void * getAs (const std::type_info &tid, ::Bool_t silent=kFALSE) const
 Return the object as a specific pointer.
virtual const void * getAsConst (const std::type_info &tid, ::Bool_t silent=kFALSE) const
 Return the object as a specific, constant pointer.
void renew ()
 Renew the object in memory.
TypeKind typeKind () const
 Return the type of the object held by this one.
const ::TClass * getClass () const
::TClass * getClass ()
const std::type_info * getTypeInfo () const

Protected Member Functions

void deleteObject ()
 Internal function used to delete the managed object from memory.
void * getImpl (const std::type_info &tid, ::Bool_t silent=kFALSE) const
 Internal function to get an object.

Protected Attributes

void * m_object
 Typeless pointer to the object in memory.
::TClass * m_type
 Concrete type of the object being held on to.
const std::type_info * m_typeInfo
 Concrete type of the object, if it doesn't have a dictionary.
::Bool_t m_owner
 A flag for whether the object owns what it points to.
TypeKind m_typeKind
 Type of the object held.
::Bool_t m_const
 Is the held object const?

Detailed Description

This class takes care of holding EDM objects in memory.

In order to be able to access EDM objects easily as their concrete type, or as one of their base classes, a little trickery is needed.

We always access the branches of the input TTree as their concrete, transient types. It is then up to our own code to decide if the user is requesting the object as a type that it can be cast to, or not.

Author
Attila Krasznahorkay Attil.nosp@m.a.Kr.nosp@m.aszna.nosp@m.hork.nosp@m.ay@ce.nosp@m.rn.c.nosp@m.h

Definition at line 35 of file THolder.h.

Member Enumeration Documentation

◆ TypeKind

Type of the object held by this one.

Enumerator
OTHER 

Some non-specified type.

DATAVECTOR 

A DataVector container.

AUXELEMENT 

A type inheriting from SG::AuxElement.

Definition at line 103 of file THolder.h.

103 {
104 OTHER,
105 DATAVECTOR,
107 }; // enum TypeKind
@ DATAVECTOR
A DataVector container.
Definition THolder.h:105
@ AUXELEMENT
A type inheriting from SG::AuxElement.
Definition THolder.h:106
@ OTHER
Some non-specified type.
Definition THolder.h:104

Constructor & Destructor Documentation

◆ THolder() [1/7]

xAOD::THolder::THolder ( )

Default constructor.

Definition at line 54 of file THolder.cxx.

55 : m_object( 0 ), m_type( 0 ), m_typeInfo( 0 ), m_owner( kFALSE ),
56 m_typeKind( OTHER ), m_const( kFALSE ) {
57
58 }
TypeKind m_typeKind
Type of the object held.
Definition THolder.h:131
void * m_object
Typeless pointer to the object in memory.
Definition THolder.h:123
::TClass * m_type
Concrete type of the object being held on to.
Definition THolder.h:125
::Bool_t m_const
Is the held object const?
Definition THolder.h:133
const std::type_info * m_typeInfo
Concrete type of the object, if it doesn't have a dictionary.
Definition THolder.h:127
::Bool_t m_owner
A flag for whether the object owns what it points to.
Definition THolder.h:129

◆ THolder() [2/7]

xAOD::THolder::THolder ( void * object,
::TClass * type,
::Bool_t owner = kTRUE )

Constructor pointing to an object in memory.

Definition at line 60 of file THolder.cxx.

61 : m_object( object ), m_type( type ),
62 m_typeInfo( m_type ? m_type->GetTypeInfo() : 0 ), m_owner( owner ),
63 m_typeKind( getTypeKind( type ) ), m_const( kFALSE ) {
64
65 // Complain if the passed dictionary will be unusable later on:
66 if( m_type && ( ! m_type->IsLoaded() ) ) {
67 ::Warning( "xAOD::THolder::THolder", "Received an emulated dictionary "
68 "for type: %s", m_type->GetName() );
69 }
70
71 // Increase the object count:
72 if( m_object && m_owner ) {
74 }
75 }
static THolderCache & instance()
Singleton accessor.
int incRef(void *ptr)
Increment the reference count of an object in memory.

◆ THolder() [3/7]

xAOD::THolder::THolder ( void * object,
const std::type_info & type,
::Bool_t owner = kTRUE )

Constructor pointing to an object in memory.

Definition at line 77 of file THolder.cxx.

78 : m_object( object ), m_type( 0 ), m_typeInfo( &type ), m_owner( owner ),
79 m_typeKind( OTHER ), m_const( kFALSE ) {
80
81 // Increase the object count:
82 if( m_object && m_owner ) {
84 }
85 }

◆ THolder() [4/7]

xAOD::THolder::THolder ( const void * object,
::TClass * type,
::Bool_t owner = kTRUE )

Constructor pointing to a const object in memory.

Definition at line 87 of file THolder.cxx.

88 : THolder( safe_const_cast(object), type, owner ) {
89
90 m_const = kTRUE;
91 }
THolder()
Default constructor.
Definition THolder.cxx:54

◆ THolder() [5/7]

xAOD::THolder::THolder ( const void * object,
const std::type_info & type,
::Bool_t owner = kTRUE )

Constructor pointing to a const object in memory.

Definition at line 93 of file THolder.cxx.

94 : THolder( safe_const_cast(object), type, owner ) {
95
96 m_const = kTRUE;
97 }

◆ THolder() [6/7]

xAOD::THolder::THolder ( const THolder & parent)

Copy constructor.

The copy constructor takes the pointer from the parent object, and based on whether the parent owned the object or not, increments the shared count.

Parameters
parentThe parent object that should be copied

Definition at line 105 of file THolder.cxx.

106 : m_object( parent.m_object ), m_type( parent.m_type ),
107 m_typeInfo( parent.m_typeInfo ), m_owner( parent.m_owner ),
108 m_typeKind( parent.m_typeKind ), m_const( parent.m_const ) {
109
110 // Increase the object count:
111 if( m_object && m_owner ) {
113 }
114 }

◆ THolder() [7/7]

xAOD::THolder::THolder ( THolder && parent)

Move constructor.

This is a tricky one.

Since the object is being moved, meaning that the parent will be deleted right after this operation, instead of incrementing and then decrementing the shared count, we just tell the parent that it doesn't own its object anymore. In this case if it did own it, the shared count will remain valid. Since it's this object owning it now. If it didn't own the object in the first place, then no hard no foul.

Parameters
parentThe parent object that should be moved

Definition at line 126 of file THolder.cxx.

127 : m_object( parent.m_object ), m_type( parent.m_type ),
128 m_typeInfo( parent.m_typeInfo ), m_owner( parent.m_owner ),
129 m_typeKind( parent.m_typeKind ), m_const( parent.m_const ) {
130
131 // Tell the parent that it no longer owns the object:
132 parent.m_owner = kFALSE;
133 }

◆ ~THolder()

xAOD::THolder::~THolder ( )
virtual

The destructor cleans out the memory used by the managed object.

Definition at line 136 of file THolder.cxx.

136 {
137
138 // Delete the object using its dictionary:
139 if( m_object && m_owner &&
140 ( ! Internal::THolderCache::instance().decRef( m_object ) ) ) {
141 deleteObject();
142 }
143 }
void deleteObject()
Internal function used to delete the managed object from memory.
Definition THolder.cxx:438

Member Function Documentation

◆ deleteObject()

void xAOD::THolder::deleteObject ( )
protected

Internal function used to delete the managed object from memory.

Definition at line 438 of file THolder.cxx.

438 {
439
440 // Check if we even have an object:
441 if( ! m_object ) {
442 return;
443 }
444
445 // Delete the object then:
446 if( m_type ) {
447 if( m_type->IsLoaded() ) {
448 m_type->Destructor( m_object );
449 }
450 // In certain situations it can happen that the memory cleanup for a
451 // particular TEvent object happens after ROOT already started to
452 // unload libraries from memory. In this case, since the application
453 // is anyway on its final leg, let's not bother the user with
454 // additional warnings about not being able to clean up after the
455 // managed object.
456 } else if( m_typeInfo ) {
457 const TVirtualDestructor* d =
459 if( d ) {
460 d->destruct( m_object );
461 } else {
462 ::Error( "xAOD::THolder::deleteObject",
463 XAOD_MESSAGE( "Couldn't delete managed object" ) );
464 }
465 } else {
466 ::Error( "xAOD::THolder::deleteObject",
467 XAOD_MESSAGE( "Couldn't delete managed object" ) );
468 }
469
470 return;
471 }
#define XAOD_MESSAGE(MESSAGE)
Simple macro for printing error/verbose messages.
const TVirtualDestructor * get(const std::type_info &ti) const
Get the destructor for a given type.
static TDestructorRegistry & instance()
Function accessing the singleton instance of this type.

◆ get() [1/2]

void * xAOD::THolder::get ( )

Return a typeless pointer to the held object.

Definition at line 221 of file THolder.cxx.

221 {
222
223 return m_object;
224 }

◆ get() [2/2]

const void * xAOD::THolder::get ( ) const

Return a typeless const pointer to the held object.

Definition at line 216 of file THolder.cxx.

216 {
217
218 return m_object;
219 }

◆ getAs()

void * xAOD::THolder::getAs ( const std::type_info & tid,
::Bool_t silent = kFALSE ) const
virtual

Return the object as a specific pointer.

This function is used for retrieving an object as one of its bases.

It is used when the caller requires a non-const pointer to the managed object.

Parameters
tidThe type as which the object is to be retrieved
silentWhen kTRUE, the call will fail silently when unsuccessful
Returns
A non-const pointer that can be cast to the requested type

Reimplemented in xAOD::TCDVHolderT< T >.

Definition at line 371 of file THolder.cxx.

372 {
373
374 if( m_const ) {
375 if( ! silent ) {
376 ::Warning( "xAOD::THolder::getAs",
377 "Trying to retrieve const \"%s\" via non-const pointer \"%s\"",
378 m_type->GetName(),
379 SG::normalizedTypeinfoName( tid ).c_str() );
380 }
381 return nullptr;
382 }
383 return getImpl( tid, silent );
384 }
void * getImpl(const std::type_info &tid, ::Bool_t silent=kFALSE) const
Internal function to get an object.
Definition THolder.cxx:297
std::string normalizedTypeinfoName(const std::type_info &info)
Convert a type_info to a normalized string representation (matching the names used in the root dictio...

◆ getAsConst()

const void * xAOD::THolder::getAsConst ( const std::type_info & tid,
::Bool_t silent = kFALSE ) const
virtual

Return the object as a specific, constant pointer.

This function is used for retrieving an object as one of its bases.

It is used when the caller need a const pointer to the managed object.

Parameters
tidThe type as which the object is to be retrieved
silentWhen kTRUE, the call will fail silently when unsuccessful
Returns
A const pointer that can be cast to the requested type

Reimplemented in xAOD::TCDVHolderT< T >.

Definition at line 395 of file THolder.cxx.

396 {
397
398 // In the generic case we just forward this call:
399 return getImpl( tid, silent );
400 }

◆ getClass() [1/2]

TClass * xAOD::THolder::getClass ( )

Definition at line 407 of file THolder.cxx.

407 {
408
409 return m_type;
410 }

◆ getClass() [2/2]

const::TClass * xAOD::THolder::getClass ( ) const

Return the concrete type of the object

Definition at line 402 of file THolder.cxx.

402 {
403
404 return m_type;
405 }

◆ getImpl()

void * xAOD::THolder::getImpl ( const std::type_info & tid,
::Bool_t silent = kFALSE ) const
protected

Internal function to get an object.

Internal helper or getAs and getAsConst.

Parameters
tidThe type as which the object is to be retrieved
silentWhen kTRUE, the call will fail silently when unsuccessful
Returns
A pointer that can be cast to the requested type

Definition at line 297 of file THolder.cxx.

298 {
299
300 // If there is no dictionary for the object, then the logic is pretty
301 // simple:
302 if( ! m_type ) {
303 // Check if the user asked for the right type. Remember that in this
304 // case we can't return an object as its base type.
305 if( tid != *m_typeInfo ) {
306 if( ! silent ) {
307 const std::string heldType =
309 const std::string reqType =
311 ::Warning( "xAOD::THolder::getAs",
312 "Trying to retrieve %s object with a %s pointer",
313 heldType.c_str(), reqType.c_str() );
314 }
315 return 0;
316 }
317 // The user did ask for the correct type:
318 return m_object;
319 }
320
321 // Check if we already know about this type:
322 auto userClass = Internal::THolderCache::instance().getClass( tid );
323 // If not, look for it now:
324 if( ! userClass.first ) {
325 userClass.second = ::TClass::GetClass( tid );
326 Internal::THolderCache::instance().addClass( tid, userClass.second );
327 }
328
329 // If we still don't have a dictionary, that's an issue:
330 if( ! userClass.second ) {
331 if( ! silent ) {
332 ::Error( "xAOD::THolder::getAs",
333 XAOD_MESSAGE( "Couldn't access the dictionary for user "
334 "type: %s" ),
335 SG::normalizedTypeinfoName( tid ).c_str() );
336 }
337 return 0;
338 }
339
340 // Check if the user requested a valid base class for the held type.
341 //
342 // Calling GetBaseClassOffset is in general not thread-safe as it could
343 // trigger the loading and parsing of StreamerInfo. However, we assume
344 // that this has already been done once we get here.
345 TClass* cl ATLAS_THREAD_SAFE = m_type;
346 const Int_t offset = cl->GetBaseClassOffset( userClass.second );
347 if( offset < 0 ) {
348 if( ! silent ) {
349 ::Warning( "xAOD::THolder::getAs",
350 "User class \"%s\" is not a valid base "
351 "of \"%s\"",
352 SG::normalizedTypeinfoName( tid ).c_str(),
353 m_type->GetName() );
354 }
355 return 0;
356 }
357
358 // If all is fine, do the cast:
359 return ( static_cast< char* >( m_object ) + offset );
360 }
#define ATLAS_THREAD_SAFE
void addClass(const std::type_info &ti, ::TClass *cl)
Add the dictionary for a given type.
std::pair< bool, ::TClass * > getClass(const std::type_info &ti) const
Get the dictionary for a given type info.
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]

◆ getPtr()

void ** xAOD::THolder::getPtr ( )

Return a typeless pointer to the held object's pointer.

Definition at line 226 of file THolder.cxx.

226 {
227
228 return &m_object;
229 }

◆ getTypeInfo()

const std::type_info * xAOD::THolder::getTypeInfo ( ) const

Definition at line 412 of file THolder.cxx.

412 {
413
414 return m_typeInfo;
415 }

◆ isConst()

Bool_t xAOD::THolder::isConst ( ) const

Check if the object is const.

Definition at line 280 of file THolder.cxx.

280 {
281
282 return m_const;
283 }

◆ isOwner()

Bool_t xAOD::THolder::isOwner ( ) const

Check whether the holder owns its object.

Definition at line 253 of file THolder.cxx.

253 {
254
255 return m_owner;
256 }

◆ operator=() [1/2]

THolder & xAOD::THolder::operator= ( const THolder & rhs)

Assignment operator.

The copy operator, just like the copy constructor makes the object aware that it doesn't own the object that it has the pointer to.

Parameters
rhsThe object that has to be copied
Returns
A reference to this same object

Definition at line 151 of file THolder.cxx.

151 {
152
153 // Check if we need to do anything:
154 if( &rhs == this ) return *this;
155
156 // Clean up the previously managed object:
157 if( m_object && m_owner &&
158 ( ! Internal::THolderCache::instance().decRef( m_object ) ) ) {
159 deleteObject();
160 }
161
162 // Do the copy:
163 m_object = rhs.m_object;
164 m_type = rhs.m_type;
165 m_typeInfo = rhs.m_typeInfo;
166 m_owner = rhs.m_owner;
167 m_typeKind = rhs.m_typeKind;
168 m_const = rhs.m_const;
169
170 // Increase the object count:
171 if( m_object && m_owner ) {
173 }
174
175 // Return this same object:
176 return *this;
177 }

◆ operator=() [2/2]

THolder & xAOD::THolder::operator= ( THolder && rhs)

Move operator.

This move operator is necessary to be able to use this type as a value type of STL containers.

See the comments given for the move constructor for an explanation of the behaviour of this operator.

Parameters
rhsThe object that has to be moved
Returns
A reference to this same object

Definition at line 188 of file THolder.cxx.

188 {
189
190 // Check if we need to do anything:
191 if( &rhs == this ) return *this;
192
193 // Clean up the previously managed object:
194 if( m_object && m_owner &&
195 ( ! Internal::THolderCache::instance().decRef( m_object ) ) ) {
196 deleteObject();
197 }
198
199 // Do the copy:
200 m_object = rhs.m_object;
201 m_type = rhs.m_type;
202 m_typeInfo = rhs.m_typeInfo;
203 m_owner = rhs.m_owner;
204 m_typeKind = rhs.m_typeKind;
205 m_const = rhs.m_const;
206
207 // Instead of doing anything with the shared count here, just make the
208 // parent not own the object anymore. The logic is the same as discussed
209 // in the move constructor.
210 rhs.m_owner = kFALSE;
211
212 // Return this same object:
213 return *this;
214 }

◆ renew()

void xAOD::THolder::renew ( )

Renew the object in memory.

This function is mostly used in "Athena access mode", to delete the managed objects from memory between events, and recreate them from scratch.

Definition at line 421 of file THolder.cxx.

421 {
422
423 // Delete the object using its dictionary:
424 if( m_object && m_owner &&
425 ( ! Internal::THolderCache::instance().decRef( m_object ) ) ) {
426 deleteObject();
427 }
428
429 // Create a new object:
430 m_owner = kTRUE;
431 m_object = m_type->New();
433
434 // Return gracefuly:
435 return;
436 }

◆ set()

void xAOD::THolder::set ( void * obj)
virtual

Replace the managed object.

Reimplemented in xAOD::TCDVHolderT< T >.

Definition at line 231 of file THolder.cxx.

231 {
232
233 // Check if we need to do anything:
234 if( m_object == obj ) return;
235
236 // Delete the previous object:
237 if( m_object && m_owner &&
238 ( ! Internal::THolderCache::instance().decRef( m_object ) ) ) {
239 deleteObject();
240 }
241
242 // Hold on to the new object from now on:
243 m_object = obj;
244
245 // Increase the object count:
246 if( m_object && m_owner ) {
248 }
249
250 return;
251 }

◆ setConst()

void xAOD::THolder::setConst ( )

Mark the object as const.

Definition at line 285 of file THolder.cxx.

285 {
286
287 m_const = kTRUE;
288 }

◆ setOwner()

void xAOD::THolder::setOwner ( ::Bool_t state = kTRUE)

Set whether the holder should own its object.

Definition at line 258 of file THolder.cxx.

258 {
259
260 // Check if anything needs to be done:
261 if( state == m_owner ) return;
262
263 if( m_object && m_owner &&
264 ( ! Internal::THolderCache::instance().decRef( m_object ) ) ) {
265 ::Warning( "xAOD::THolder::setOwner",
266 "Deleting object %p no longer held by any owner",
267 m_object );
268 deleteObject();
269 }
270
271 m_owner = state;
272
273 if( m_object && m_owner ) {
275 }
276
277 return;
278 }

◆ typeKind()

TypeKind xAOD::THolder::typeKind ( ) const
inline

Return the type of the object held by this one.

Definition at line 110 of file THolder.h.

110 {
111 return m_typeKind;
112 }

Member Data Documentation

◆ m_const

::Bool_t xAOD::THolder::m_const
protected

Is the held object const?

Definition at line 133 of file THolder.h.

◆ m_object

void* xAOD::THolder::m_object
protected

Typeless pointer to the object in memory.

Definition at line 123 of file THolder.h.

◆ m_owner

::Bool_t xAOD::THolder::m_owner
protected

A flag for whether the object owns what it points to.

Definition at line 129 of file THolder.h.

◆ m_type

::TClass* xAOD::THolder::m_type
protected

Concrete type of the object being held on to.

Definition at line 125 of file THolder.h.

◆ m_typeInfo

const std::type_info* xAOD::THolder::m_typeInfo
protected

Concrete type of the object, if it doesn't have a dictionary.

Definition at line 127 of file THolder.h.

◆ m_typeKind

TypeKind xAOD::THolder::m_typeKind
protected

Type of the object held.

Definition at line 131 of file THolder.h.


The documentation for this class was generated from the following files: