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.
TDVCollectionProxy & operator= (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 332 of file TDVCollectionProxy.cxx.

333 : TGenCollectionProxy( typeid( DataVector< TDVCollectionProxyDummy > ),
334 sizeof( char* ) ),
335 fName( conttype ), fInitialized( kFALSE ),
336 fContoff( 0 ), fOffset( 0 ), fEltBase( nullptr ), fEltType( nullptr ) {
337
338 // Set up the element size. No offset, since this isn't a map.
339 fValDiff = sizeof( void* );
340 fValOffset = 0;
341
342 // Set up the worker functions.
343 fSize.call = TDVCollectionFuncs::size;
344 fNext.call = TDVCollectionFuncs::next;
345 fFirst.call = TDVCollectionFuncs::first;
346 fClear.call = TDVCollectionFuncs::clear;
348 fCreateEnv.call = TDVCollectionFuncs::create_env;
353
354 // Make sure that TGenCollectionProxy knows that it's not
355 // fully set up yet:
356 if( fValue ) {
357 delete fValue.exchange( nullptr );
358 }
359 if( fVal ) {
360 delete fVal;
361 fVal = nullptr;
362 }
363
364 // This container pretends to hold objects, not pointers:
365 fPointers = kFALSE;
366
367 // Remember that we are not initialized yet:
368 fProperties = 0;
369 }
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 374 of file TDVCollectionProxy.cxx.

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

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 533 of file TDVCollectionProxy.cxx.

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

432 {
433
434 return new TDVCollectionProxy( *this );
435 }
TDVCollectionProxy(const char *conttype)
Constructor.

◆ InitializeEx()

TGenCollectionProxy * TDVCollectionProxy::InitializeEx ( Bool_t silent)
privatevirtual

Function initialising the proxy just in time.

Definition at line 449 of file TDVCollectionProxy.cxx.

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

443 {
444
445 fResize = func;
446 return;
447 }

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: