ATLAS Offline Software
Public Types | Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
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. More...
 
 THolder (void *object, ::TClass *type, ::Bool_t owner=kTRUE)
 Constructor pointing to an object in memory. More...
 
 THolder (void *object, const std::type_info &type, ::Bool_t owner=kTRUE)
 Constructor pointing to an object in memory. More...
 
 THolder (const void *object, ::TClass *type, ::Bool_t owner=kTRUE)
 Constructor pointing to a const object in memory. More...
 
 THolder (const void *object, const std::type_info &type, ::Bool_t owner=kTRUE)
 Constructor pointing to a const object in memory. More...
 
 THolder (const THolder &parent)
 Copy constructor. More...
 
 THolder (THolder &&parent)
 Move constructor. More...
 
virtual ~THolder ()
 The destructor cleans out the memory used by the managed object. More...
 
THolderoperator= (const THolder &rhs)
 Assignment operator. More...
 
THolderoperator= (THolder &&rhs)
 Move operator. More...
 
const void * get () const
 Return a typeless const pointer to the held object. More...
 
void * get ()
 Return a typeless pointer to the held object. More...
 
void ** getPtr ()
 Return a typeless pointer to the held object's pointer. More...
 
virtual void set (void *obj)
 Replace the managed object. More...
 
::Bool_t isOwner () const
 Check whether the holder owns its object. More...
 
void setOwner (::Bool_t state=kTRUE)
 Set whether the holder should own its object. More...
 
::Bool_t isConst () const
 Check if the object is const. More...
 
void setConst ()
 Mark the object as const. More...
 
virtual void * getAs (const std::type_info &tid, ::Bool_t silent=kFALSE) const
 Return the object as a specific pointer. More...
 
virtual const void * getAsConst (const std::type_info &tid, ::Bool_t silent=kFALSE) const
 Return the object as a specific, constant pointer. More...
 
void renew ()
 Renew the object in memory. More...
 
TypeKind typeKind () const
 Return the type of the object held by this one. More...
 

Protected Member Functions

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

Protected Attributes

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

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,
106  AUXELEMENT
107  }; // enum TypeKind

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  }

◆ 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  }

◆ 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() [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 135 of file THolder.cxx.

135  {
136 
137  // Delete the object using its dictionary:
138  if( m_object && m_owner &&
139  ( ! Internal::THolderCache::instance().decRef( m_object ) ) ) {
140  deleteObject();
141  }
142  }

Member Function Documentation

◆ deleteObject()

void xAOD::THolder::deleteObject ( )
protected

Internal function used to delete the managed object from memory.

Definition at line 437 of file THolder.cxx.

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

◆ get() [1/2]

void * xAOD::THolder::get ( )

Return a typeless pointer to the held object.

Definition at line 220 of file THolder.cxx.

220  {
221 
222  return m_object;
223  }

◆ get() [2/2]

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

Return a typeless const pointer to the held object.

Definition at line 215 of file THolder.cxx.

215  {
216 
217  return m_object;
218  }

◆ 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 370 of file THolder.cxx.

371  {
372 
373  if( m_const ) {
374  if( ! silent ) {
375  ::Warning( "xAOD::THolder::getAs",
376  "Trying to retrieve const \"%s\" via non-const pointer \"%s\"",
377  m_type->GetName(),
378  SG::normalizedTypeinfoName( tid ).c_str() );
379  }
380  return nullptr;
381  }
382  return getImpl( tid, silent );
383  }

◆ 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 394 of file THolder.cxx.

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

◆ getClass() [1/2]

TClass * xAOD::THolder::getClass ( )

Definition at line 406 of file THolder.cxx.

406  {
407 
408  return m_type;
409  }

◆ getClass() [2/2]

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

Return the concrete type of the object

Definition at line 401 of file THolder.cxx.

401  {
402 
403  return m_type;
404  }

◆ 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 296 of file THolder.cxx.

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

◆ getPtr()

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

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

Definition at line 225 of file THolder.cxx.

225  {
226 
227  return &m_object;
228  }

◆ getTypeInfo()

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

Definition at line 411 of file THolder.cxx.

411  {
412 
413  return m_typeInfo;
414  }

◆ isConst()

Bool_t xAOD::THolder::isConst ( ) const

Check if the object is const.

Definition at line 279 of file THolder.cxx.

279  {
280 
281  return m_const;
282  }

◆ isOwner()

Bool_t xAOD::THolder::isOwner ( ) const

Check whether the holder owns its object.

Definition at line 252 of file THolder.cxx.

252  {
253 
254  return m_owner;
255  }

◆ 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 150 of file THolder.cxx.

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

◆ 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 187 of file THolder.cxx.

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

◆ 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 420 of file THolder.cxx.

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

◆ set()

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

Replace the managed object.

Reimplemented in xAOD::TCDVHolderT< T >.

Definition at line 230 of file THolder.cxx.

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

◆ setConst()

void xAOD::THolder::setConst ( )

Mark the object as const.

Definition at line 284 of file THolder.cxx.

284  {
285 
286  m_const = kTRUE;
287  }

◆ setOwner()

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

Set whether the holder should own its object.

Definition at line 257 of file THolder.cxx.

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

◆ 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:
xAOD::THolder::OTHER
@ OTHER
Some non-specified type.
Definition: THolder.h:104
xAOD::THolder::AUXELEMENT
@ AUXELEMENT
A type inheriting from SG::AuxElement.
Definition: THolder.h:106
xAOD::THolder::m_owner
::Bool_t m_owner
A flag for whether the object owns what it points to.
Definition: THolder.h:129
SG::normalizedTypeinfoName
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...
Definition: normalizedTypeinfoName.cxx:120
hist_file_dump.d
d
Definition: hist_file_dump.py:137
xAOD::THolder::DATAVECTOR
@ DATAVECTOR
A DataVector container.
Definition: THolder.h:105
xAOD::THolder::getImpl
void * getImpl(const std::type_info &tid, ::Bool_t silent=kFALSE) const
Internal function to get an object.
Definition: THolder.cxx:296
xAOD::THolder::deleteObject
void deleteObject()
Internal function used to delete the managed object from memory.
Definition: THolder.cxx:437
XAOD_MESSAGE
#define XAOD_MESSAGE(MESSAGE)
Simple macro for printing error/verbose messages.
Definition: Control/xAODRootAccess/xAODRootAccess/tools/Message.h:19
xAOD::Internal::THolderCache::addClass
void addClass(const std::type_info &ti, ::TClass *cl)
Add the dictionary for a given type.
Definition: THolderCache.cxx:49
xAOD::Internal::THolderCache::getClass
std::pair< bool, ::TClass * > getClass(const std::type_info &ti) const
Get the dictionary for a given type info.
Definition: THolderCache.cxx:35
xAOD::THolder::m_typeKind
TypeKind m_typeKind
Type of the object held.
Definition: THolder.h:131
xAOD::THolder::m_const
::Bool_t m_const
Is the held object const?
Definition: THolder.h:133
test_pyathena.parent
parent
Definition: test_pyathena.py:15
xAOD::THolder::m_object
void * m_object
Typeless pointer to the object in memory.
Definition: THolder.h:123
xAOD::TDestructorRegistry::instance
static TDestructorRegistry & instance()
Function accessing the singleton instance of this type.
Definition: TDestructorRegistry.cxx:16
xAOD::THolder::m_type
::TClass * m_type
Concrete type of the object being held on to.
Definition: THolder.h:125
xAOD::Internal::THolderCache::instance
static THolderCache & instance()
Singleton accessor.
Definition: THolderCache.cxx:29
xAOD::Internal::THolderCache::incRef
int incRef(void *ptr)
Increment the reference count of an object in memory.
Definition: THolderCache.cxx:72
xAOD::THolder::THolder
THolder()
Default constructor.
Definition: THolder.cxx:54
python.trfDecorators.silent
def silent(func)
Redirect stdout/err to /dev/null Useful wrapper to get rid of ROOT verbosity...
Definition: trfDecorators.py:24
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
convertTimingResiduals.offset
offset
Definition: convertTimingResiduals.py:71
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211
xAOD::THolder::m_typeInfo
const std::type_info * m_typeInfo
Concrete type of the object, if it doesn't have a dictionary.
Definition: THolder.h:127
python.PyAthena.obj
obj
Definition: PyAthena.py:135
dq_make_web_display.cl
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
Definition: dq_make_web_display.py:26
xAOD::TDestructorRegistry::get
const TVirtualDestructor * get(const std::type_info &ti) const
Get the destructor for a given type.
Definition: TDestructorRegistry.cxx:23