The Gaudi Framework
master (1a7a3838)
Toggle main menu visibility
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
\***********************************************************************************/
11
#include <
Gaudi/details/BranchReadHelper.h
>
12
#include <TClass.h>
13
#include <TDataType.h>
14
#include <TInterpreter.h>
15
#include <TInterpreterValue.h>
16
#include <sstream>
17
18
namespace
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
63
BranchReadHelper::BranchReadHelper
(
BranchReadHelper
&& other )
noexcept
{
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
72
BranchReadHelper
&
BranchReadHelper::operator=
(
BranchReadHelper
&& other )
noexcept
{
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
BranchReadHelper.h
DataObject
A DataObject is the base class of any identifiable object on any data store.
Definition
DataObject.h:37
Gaudi::details::BranchReadHelper::operator=
BranchReadHelper & operator=(const BranchReadHelper &other)=delete
Gaudi::details::BranchReadHelper::m_branch
TBranch * m_branch
Definition
BranchReadHelper.h:47
Gaudi::details::BranchReadHelper::BranchReadHelper
BranchReadHelper(gsl::not_null< TBranch * > b)
Definition
BranchReadHelper.cpp:20
Gaudi::details::BranchReadHelper::adoptValue
std::unique_ptr< DataObject > adoptValue()
Definition
BranchReadHelper.cpp:87
Gaudi::details::BranchReadHelper::m_extractor
DataObject *(* m_extractor)(void *)
Definition
BranchReadHelper.h:50
Gaudi::details::BranchReadHelper::~BranchReadHelper
~BranchReadHelper()
Definition
BranchReadHelper.cpp:85
Gaudi::details::BranchReadHelper::m_store
void * m_store
Definition
BranchReadHelper.h:48
Gaudi::details
Helper for type agnostic reading of data in branches.
Definition
Algorithm.h:16
GaudiUtils
src
Lib
BranchReadHelper.cpp
Generated on
for The Gaudi Framework by
1.17.0