The Gaudi Framework  master (d4ee5f7d)
Loading...
Searching...
No Matches
Gaudi::details::BranchReadHelper Class Referencefinal

#include </builds/gaudi/Gaudi/GaudiUtils/include/Gaudi/details/BranchReadHelper.h>

Collaboration diagram for Gaudi::details::BranchReadHelper:

Public Member Functions

 BranchReadHelper (gsl::not_null< TBranch * > b)
 BranchReadHelper (const BranchReadHelper &other)=delete
BranchReadHelperoperator= (const BranchReadHelper &other)=delete
 BranchReadHelper (BranchReadHelper &&other) noexcept
BranchReadHelperoperator= (BranchReadHelper &&other) noexcept
std::unique_ptr< DataObjectadoptValue ()
 ~BranchReadHelper ()

Private Attributes

TBranch * m_branch { nullptr }
void * m_store { nullptr }
DataObject *(* m_extractor )(void *) = nullptr

Detailed Description

Definition at line 34 of file BranchReadHelper.h.

Constructor & Destructor Documentation

◆ BranchReadHelper() [1/3]

Gaudi::details::BranchReadHelper::BranchReadHelper ( gsl::not_null< TBranch * > b)
explicit

Definition at line 20 of file BranchReadHelper.cpp.

20 : m_branch( b ) {
21 TClass* clptr = nullptr;
22 EDataType datatype = kNoType_t;
23 b->GetExpectedType( clptr, datatype );
24 // 64 bits of storage are enough for reading from the TBranch:
25 // for simple types, we can just read the value directly into
26 // this storage, and for complex types, we can read the address
27 // of the object into this storage
28 b->SetAddress( &m_store );
29
30 // Here we compile a function that converts the value hold in m_store
31 // into a DataObject. This is done by directly returning the pointer
32 // if the type inherits from DataObject, or by creating a new AnyDataWrapper.
33 std::ostringstream code;
34 code << "static_cast<DataObject*(*)(void*)>([] (void* store) -> DataObject* {";
35 if ( clptr ) {
36 // complex type case: store points to an instance of the object
37 code << "auto ptr = reinterpret_cast<" << clptr->GetName() << "*>(store);";
38 if ( clptr->InheritsFrom( TClass::GetClass<DataObject>() ) ) {
39 // for DataObject, just return the pointer
40 code << "return ptr;";
41 } else {
42 // for other complex types, create a new AnyDataWrapper from the object
43 code << "return new AnyDataWrapper(std::move(*ptr));";
44 }
45 } else {
46 // simple type case: store is the actual value.
47 // std::memcpy is safe because ROOT stores simple small types directly in void*,
48 // while for complex objects clptr != nullptr. The check on clptr is equivalent to
49 // verifying that the type is trivially copyable and size(value) <= sizeof(void*).
50 code << TDataType::GetTypeName( datatype ) << " value;";
51 code << "std::memcpy(&value, &store, sizeof(value));";
52 code << "return new AnyDataWrapper(std::move(value));";
53 }
54 code << "})";
55 gInterpreter->Declare( "#include <cstring>\n#include <functional>\n#include <GaudiKernel/AnyDataWrapper.h>\n" );
56 auto val = gInterpreter->MakeInterpreterValue();
57 if ( gInterpreter->Evaluate( code.str().c_str(), *val ) == 0 ) {
58 throw std::runtime_error( "Failed to compile code" );
59 }
60 m_extractor = reinterpret_cast<DataObject* (*)( void* )>( val->GetAsPointer() );
61 }
DataObject *(* m_extractor)(void *)

◆ BranchReadHelper() [2/3]

Gaudi::details::BranchReadHelper::BranchReadHelper ( const BranchReadHelper & other)
delete

◆ BranchReadHelper() [3/3]

Gaudi::details::BranchReadHelper::BranchReadHelper ( BranchReadHelper && other)
noexcept

Definition at line 63 of file BranchReadHelper.cpp.

63 {
64 m_branch = other.m_branch;
65 m_store = other.m_store;
66 m_extractor = std::move( other.m_extractor );
67
68 other.m_branch = nullptr;
69 other.m_store = nullptr;
70 }

◆ ~BranchReadHelper()

Gaudi::details::BranchReadHelper::~BranchReadHelper ( )

Definition at line 85 of file BranchReadHelper.cpp.

85{ m_branch->SetAddress( nullptr ); }

Member Function Documentation

◆ adoptValue()

std::unique_ptr< DataObject > Gaudi::details::BranchReadHelper::adoptValue ( )

Definition at line 87 of file BranchReadHelper.cpp.

87 {
88 std::unique_ptr<DataObject> out( ( *m_extractor )( m_store ) );
89 m_store = nullptr;
90 return out;
91 }

◆ operator=() [1/2]

BranchReadHelper & Gaudi::details::BranchReadHelper::operator= ( BranchReadHelper && other)
noexcept

Definition at line 72 of file BranchReadHelper.cpp.

72 {
73 if ( this == &other ) { return *this; }
74
75 m_branch = other.m_branch;
76 m_store = other.m_store;
77 m_extractor = std::move( other.m_extractor );
78
79 other.m_branch = nullptr;
80 other.m_store = nullptr;
81
82 return *this;
83 }

◆ operator=() [2/2]

BranchReadHelper & Gaudi::details::BranchReadHelper::operator= ( const BranchReadHelper & other)
delete

Member Data Documentation

◆ m_branch

TBranch* Gaudi::details::BranchReadHelper::m_branch { nullptr }
private

Definition at line 47 of file BranchReadHelper.h.

47{ nullptr };

◆ m_extractor

DataObject *(* Gaudi::details::BranchReadHelper::m_extractor) (void *) = nullptr
private

Definition at line 50 of file BranchReadHelper.h.

◆ m_store

void* Gaudi::details::BranchReadHelper::m_store { nullptr }
private

Definition at line 48 of file BranchReadHelper.h.

48{ nullptr };

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