The Gaudi Framework  master (9f4fd0d1)
Loading...
Searching...
No Matches
BranchReadHelper.cpp
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 2026 CERN for the benefit of the LHCb and ATLAS collaborations *
3* *
4* This software is distributed under the terms of the Apache version 2 licence, *
5* copied verbatim in the file "LICENSE". *
6* *
7* In applying this licence, CERN does not waive the privileges and immunities *
8* granted to it by virtue of its status as an Intergovernmental Organization *
9* or submit itself to any jurisdiction. *
10\***********************************************************************************/
12#include <TClass.h>
13#include <TDataType.h>
14#include <TInterpreter.h>
15#include <TInterpreterValue.h>
16#include <sstream>
17
18namespace Gaudi::details {
19
20 BranchReadHelper::BranchReadHelper( gsl::not_null<TBranch*> b ) : 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 }
62
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 }
71
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 }
84
85 BranchReadHelper::~BranchReadHelper() { m_branch->SetAddress( nullptr ); }
86
87 std::unique_ptr<DataObject> BranchReadHelper::adoptValue() {
88 std::unique_ptr<DataObject> out( ( *m_extractor )( m_store ) );
89 m_store = nullptr;
90 return out;
91 }
92
93} // namespace Gaudi::details
A DataObject is the base class of any identifiable object on any data store.
Definition DataObject.h:37
BranchReadHelper & operator=(const BranchReadHelper &other)=delete
BranchReadHelper(gsl::not_null< TBranch * > b)
std::unique_ptr< DataObject > adoptValue()
DataObject *(* m_extractor)(void *)
Helper for type agnostic reading of data in branches.
Definition Algorithm.h:16