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

A Root collection proxy for DataVector containers. More...

#include <TDVCollectionProxy.h>

Inheritance diagram for xAOD::TDVCollectionProxy:
Collaboration diagram for xAOD::TDVCollectionProxy:

Public Types

typedef TGenCollectionProxy::Sizing_t Sizing_t
 Make the definition of Sizing_t public.

Public Member Functions

 TDVCollectionProxy (const char *conttype)
 Constructor.
 TDVCollectionProxy (const TDVCollectionProxy &rhs)
 Copy constructor.
virtual void PushProxy (void *objstart)
 Start working with a new collection.
virtual TVirtualCollectionProxy * Generate () const
 Clone this object.
void SetResize (Sizing_t func)
 Set the resize(...) function used by the proxy.

Private Member Functions

virtual TGenCollectionProxy * InitializeEx (Bool_t silent)
 Function initialising the proxy just in time.
void FindOffsets (const char *elttype, const char *conttype)
 Initialize the cached pointer offsets.
TDVCollectionProxyoperator= (const TDVCollectionProxy &)

Private Attributes

TString fName
 Name of the container that this class proxies.
Bool_t fInitialized
 Flag for knowing whether the class was initialised already.
ptrdiff_t fContoff
 The offset of the underlying DataVector in the declared type.
ptrdiff_t fOffset
 Offset between the DV base pointer and the full DV pointer.
TClass * fEltBase
 The element type to which the DV representation points.
TClass * fEltType
 The declared element type of the DV.

Detailed Description

A Root collection proxy for DataVector containers.

In order for a container type to be treated properly by TTree::Draw and friends, Root must recognize that it is in fact a container type, and generate an appropriate proxy for it. This doesn't happen automatically, though. This class serves as an appropriate proxy for DataVector classes. Like the Root proxy classes, it's based on making a hard cast to a dummy DataVector type. But because DataVector's can inherit, we need to be careful about pointer conversions, something the Root proxy classes could ignore. We extend the Root environment buffer to cache information about the pointer offsets.

Author
Scott Snyder Scott.nosp@m..Sny.nosp@m.der@c.nosp@m.ern..nosp@m.ch
Attila Krasznahorkay Attil.nosp@m.a.Kr.nosp@m.aszna.nosp@m.hork.nosp@m.ay@ce.nosp@m.rn.c.nosp@m.h
Revision
687822
Date
2015-08-06 09:58:06 +0200 (Thu, 06 Aug 2015)

Definition at line 45 of file TDVCollectionProxy.h.

Member Typedef Documentation

◆ Sizing_t

typedef TGenCollectionProxy::Sizing_t xAOD::TDVCollectionProxy::Sizing_t

Make the definition of Sizing_t public.

Definition at line 50 of file TDVCollectionProxy.h.

Constructor & Destructor Documentation

◆ TDVCollectionProxy() [1/2]

TDVCollectionProxy::TDVCollectionProxy ( const char * conttype)

Constructor.

Parameters
conttypeThe name of the container type we're proxying. Note that this may be different from a DataVector of elttype for classes which derive from DataVector.

Definition at line 329 of file TDVCollectionProxy.cxx.

330 : TGenCollectionProxy( typeid( DataVector< TDVCollectionProxyDummy > ),
331 sizeof( char* ) ),
332 fName( conttype ), fInitialized( kFALSE ),
333 fContoff( 0 ), fOffset( 0 ), fEltBase( nullptr ), fEltType( nullptr ) {
334
335 // Set up the element size. No offset, since this isn't a map.
336 fValDiff = sizeof( void* );
337 fValOffset = 0;
338
339 // Set up the worker functions.
340 fSize.call = TDVCollectionFuncs::size;
341 fNext.call = TDVCollectionFuncs::next;
342 fFirst.call = TDVCollectionFuncs::first;
343 fClear.call = TDVCollectionFuncs::clear;
345 fCreateEnv.call = TDVCollectionFuncs::create_env;
350
351 // Make sure that TGenCollectionProxy knows that it's not
352 // fully set up yet:
353 if( fValue ) {
354 delete fValue.exchange( nullptr );
355 }
356 if( fVal ) {
357 delete fVal;
358 fVal = nullptr;
359 }
360
361 // This container pretends to hold objects, not pointers:
362 fPointers = kFALSE;
363
364 // Remember that we are not initialized yet:
365 fProperties = 0;
366 }
static void * feed(void *, void *to, size_t size)
static void * next(void *env)
Return a following element of the container.
static void * create_env()
Return a new environment structure.
static void * clear(void *env)
Erase the container.
static void * first(void *env)
Return the first element of the container.
static void resize(void *, size_t)
Not implemented for xAOD.
static void * collect(void *, void *)
Not implemented for xAOD.
static void * size(void *env)
Return the size of the container.
static void destruct(void *, size_t)
Not implemented for xAOD.
static void * construct(void *, size_t)
Not implemented for xAOD.
TClass * fEltBase
The element type to which the DV representation points.
Bool_t fInitialized
Flag for knowing whether the class was initialised already.
TClass * fEltType
The declared element type of the DV.
TString fName
Name of the container that this class proxies.
ptrdiff_t fContoff
The offset of the underlying DataVector in the declared type.
ptrdiff_t fOffset
Offset between the DV base pointer and the full DV pointer.

◆ TDVCollectionProxy() [2/2]

TDVCollectionProxy::TDVCollectionProxy ( const TDVCollectionProxy & rhs)

Copy constructor.

Parameters
rhsThe proxy to copy.

Definition at line 371 of file TDVCollectionProxy.cxx.

372 : TGenCollectionProxy( rhs ),
373 fName( rhs.fName ),
374 fInitialized( rhs.fInitialized ),
375 fContoff( rhs.fContoff ),
376 fOffset( rhs.fOffset ),
377 fEltBase( rhs.fEltBase ),
378 fEltType( rhs.fEltType ) {
379
380 // If we're not initialised yet, make sure that the base class is
381 // on the same page...
382 if( ! fInitialized ) {
383 if( fValue ) {
384 delete fValue.exchange( nullptr );
385 }
386 if( fVal ) {
387 delete fVal;
388 fVal = nullptr;
389 }
390 }
391 }

Member Function Documentation

◆ FindOffsets()

void TDVCollectionProxy::FindOffsets ( const char * elttype,
const char * conttype )
private

Initialize the cached pointer offsets.

Suppose we have D deriving from B, and thus DataVector<D> deriving from DataVector<B>. In general, inheritance may be multiple or virtual, so we need to adjust the pointer offsets.

Suppose we're setting up the proxy for DataVector<D>. Then fContoff will be set to the offset of the DataVector<B> base within DataVector<D> — this is the amount we need to shift the container pointer by before applying the proxy. Originally, we cached an offset for the element conversions as well. But that doesn't work for the case of virtual derivation. Instead, we save the Reflex types for the base and derived types, and use Reflex to convert. (We can get away with caching the offset for the container because we know what the fully-derived type will be. We don't know that for the elements.)

Parameters
elttypeThe name of the contained type (including a trailing '*').
conttypeThe name of the container type we're proxying. Note that this may be different from a DataVector of elttype for classes which derive from DataVector.

Definition at line 530 of file TDVCollectionProxy.cxx.

531 {
532
533 // Start by assuming no offsets.
534 fContoff = 0;
535 fOffset = 0;
536
537 // Find its TClass.
538 TClass* dvclass = TClass::GetClass( conttype );
539 if( ! dvclass ) {
540 ::Fatal( "xAOD::TDVCollectionProxy::FindOffsets",
541 "Cannot find class %s", conttype );
542 return;
543 }
544
545 // Find the TClass for the base DataVector class.
546 TClass* dvbase = findDVBase( dvclass );
547 if( ! dvbase ) {
548 TClass* elclass = classFromDVClass( dvclass );
549 if( ! elclass ) {
550 ::Fatal( "xAOD::TDVCollectionProxy::FindOffsets",
551 "Couldn't find element type of %s",
552 dvclass->GetName() );
553 return;
554 }
555 fEltBase = elclass;
557
558 // No inheritance --- offsets are zero.
559 return;
560 }
561
562 // Find the container offset.
563 fContoff = safeGetBaseOffset( dvclass, dvbase );
564
565 // Now, find the base and derived element classes.
566 std::string elttype2 = elttype;
567 if( elttype2[ elttype2.size() - 1 ] == '*' ) {
568 elttype2.erase( elttype2.size() - 1 );
569 }
570 fEltType = TClass::GetClass( elttype2.c_str() );
571 fEltBase = classFromDVClass( dvbase );
572
573 if( ( ! fEltType ) || ( ! fEltBase ) ) {
574 ::Fatal( "xAOD::TDVCollectionProxy::FindOffsets",
575 "Couldn't find dictionaries for DV element "
576 "type(s) for %s", conttype );
577 return;
578 }
579
580 // Get the offset needed for the pointer operations:
582
583 return;
584 }
int safeGetBaseOffset(TClass *cls, TClass *base)
Find base class offset using Reflex.
TClass * classFromDVClass(TClass *dvclass)
Find the contained class in a DataVector.
TClass * findDVBase(TClass *dvclass)
Find the unique base DataVector class.

◆ Generate()

TVirtualCollectionProxy * TDVCollectionProxy::Generate ( ) const
virtual

Clone this object.

Definition at line 429 of file TDVCollectionProxy.cxx.

429 {
430
431 return new TDVCollectionProxy( *this );
432 }
TDVCollectionProxy(const char *conttype)
Constructor.

◆ InitializeEx()

TGenCollectionProxy * TDVCollectionProxy::InitializeEx ( Bool_t silent)
privatevirtual

Function initialising the proxy just in time.

Definition at line 446 of file TDVCollectionProxy.cxx.

446 {
447
448 // Check if we're initialised already:
449 if( fInitialized ) return this;
450
451 // Check for the class's dictionary, and for its element type:
452 TClass* cl = TClass::GetClass( fName );
453 if( ! cl ) {
454 ::Fatal( "xAOD::TDVCollectionProxy::InitializeEx",
455 "Couldn't find dictionary for class %s",
456 fName.Data() );
457 return nullptr;
458 }
459
460 // Check if it is a DataVector:
461 const std::string eltname = findDVElement( cl );
462 if( eltname.empty() ) {
463 ::Fatal( "xAOD::TDVCollectionProxy::InitializeEx",
464 "Class \"%s\" doesn't seem to be a DataVector",
465 cl->GetName() );
466 return nullptr;
467 }
468 /*
469 * CID 20575: (#1 of 1): String converted to C pointer then back to string
470 * (UNNECESSARY_STRING_COPY)
471 * string_to_ptr_and_back: In eltname.c_str(), a C++ string is converted to
472 * a C-style pointer, then passed to a function that uses this pointer to construct
473 * one or more strings.
474 */
475 // Find the container and element offsets.
476 //coverity[UNNECESSARY_STRING_COPY]
477 FindOffsets( eltname.c_str(), fName );
478
479 // Set up the element size. No offset, since this isn't a map.
480 fValDiff = sizeof( void* );
481 fValOffset = 0;
482
483 // Do the base class initialization.
484 CheckFunctions();
485 TGenCollectionProxy::InitializeEx( silent );
486 // xAODRootAccess/THolder relies on the setting below
487 // to be able to skip some inheritance tests.
488 fSTL_type = ROOT::kSTLlist;
489
490 // Need to override what that set up for fValue and fVal.
491 if( fValue ) {
492 delete fValue.exchange( nullptr );
493 }
494 if( fVal ) delete fVal;
495 fValue = new TGenCollectionProxy::Value( eltname.c_str(), false );
496 fVal = new TGenCollectionProxy::Value( *fValue );
497 fClass = cl;
498
499 // This container pretends to hold objects, not pointers:
500 fPointers = kFALSE;
501
502 // Remember that the initialisation succeeded:
503 fInitialized = kTRUE;
504 return this;
505 }
void FindOffsets(const char *elttype, const char *conttype)
Initialize the cached pointer offsets.
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]

◆ operator=()

TDVCollectionProxy & xAOD::TDVCollectionProxy::operator= ( const TDVCollectionProxy & )
private

◆ PushProxy()

virtual void xAOD::TDVCollectionProxy::PushProxy ( void * objstart)
virtual

Start working with a new collection.

Parameters
objstartThe address of the collection.

◆ SetResize()

void TDVCollectionProxy::SetResize ( Sizing_t func)

Set the resize(...) function used by the proxy.

The resize(...) functions need to be specific for the different classes.

This function is used to supply a specific resize(...) function for this proxy's class.

Parameters
funcThe function to use

Definition at line 440 of file TDVCollectionProxy.cxx.

440 {
441
442 fResize = func;
443 return;
444 }

Member Data Documentation

◆ fContoff

ptrdiff_t xAOD::TDVCollectionProxy::fContoff
private

The offset of the underlying DataVector in the declared type.

Definition at line 85 of file TDVCollectionProxy.h.

◆ fEltBase

TClass* xAOD::TDVCollectionProxy::fEltBase
private

The element type to which the DV representation points.

Definition at line 90 of file TDVCollectionProxy.h.

◆ fEltType

TClass* xAOD::TDVCollectionProxy::fEltType
private

The declared element type of the DV.

Definition at line 92 of file TDVCollectionProxy.h.

◆ fInitialized

Bool_t xAOD::TDVCollectionProxy::fInitialized
private

Flag for knowing whether the class was initialised already.

Definition at line 82 of file TDVCollectionProxy.h.

◆ fName

TString xAOD::TDVCollectionProxy::fName
private

Name of the container that this class proxies.

Definition at line 80 of file TDVCollectionProxy.h.

◆ fOffset

ptrdiff_t xAOD::TDVCollectionProxy::fOffset
private

Offset between the DV base pointer and the full DV pointer.

Definition at line 87 of file TDVCollectionProxy.h.


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