ATLAS Offline Software
Loading...
Searching...
No Matches
TAuxVectorFactory.cxx
Go to the documentation of this file.
1// Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2
3// ROOT include(s):
4#include <TClass.h>
5#include <TError.h>
6#include <TMethodCall.h>
7#include <TString.h>
8#include <TVirtualCollectionProxy.h>
9#include <TInterpreter.h>
10
11// Local include(s):
17#include "CxxUtils/ClassName.h"
19
20namespace xAOD {
21
23 : m_class( cl ), m_proxy( cl->GetCollectionProxy() ),
24 m_defElt( 0 ) {
25
26 // A little sanity check:
27 if( ! m_proxy ) {
28 ::Fatal( "xAOD::TAuxVectorFactory::TAuxVectorFactory",
29 XAOD_MESSAGE( "No collection proxy found for type %s" ),
30 cl->GetName() );
31 }
32 else {
33 // Check if the elements of the vector are objects:
34 ::TClass* eltClass = m_proxy->GetValueClass();
35 if( eltClass ) {
36 // Initialise the assignment operator's method call:
37 std::string proto = "const ";
38 proto += eltClass->GetName();
39 proto += "&";
40 m_assign.setProto( eltClass, "operator=", proto );
41 if( m_assign.call() == nullptr ) {
42 ::Warning( "xAOD::TAuxVectorFactory::TAuxVectorFactory",
43 XAOD_MESSAGE( "Can't get assignment operator for "
44 "class %s" ),
45 eltClass->GetName() );
46 }
47 m_defElt = eltClass->New();
48 }
49 }
50 }
51
53
54 // Remove the default element from memory if it exists:
55 if( m_defElt ) {
56 m_proxy->GetValueClass()->Destructor( m_defElt );
57 }
58 }
59
60 std::unique_ptr< SG::IAuxTypeVector >
61 TAuxVectorFactory::create( SG::auxid_t auxid, size_t size, size_t capacity,
62 bool isLinked ) const {
63
64 return std::make_unique< TAuxVector >( this, auxid,
66 size, capacity,
67 isLinked );
68 }
69
70 std::unique_ptr< SG::IAuxTypeVector >
72 void* /*data*/,
73 SG::IAuxTypeVector* /*linkedVector*/,
74 bool /*isPacked*/,
75 bool /*ownFlag*/,
76 bool /*isLinked*/ ) const {
77
78 std::abort();
79 }
80
82 SG::AuxVectorData& dst, size_t dst_index,
83 const SG::AuxVectorData& src, size_t src_index,
84 size_t n ) const {
85
86 if (n == 0) return;
87
88 // The size of one element in memory:
89 const size_t eltsz = m_proxy->GetIncrement();
90
91 // Get the location of the source and target element in memory:
92 char* dstptr = reinterpret_cast<char*> (dst.getDataArray (auxid));
93 const char* srcptr = &dst == &src ? dstptr : reinterpret_cast<const char*>(src.getDataArray (auxid));
94 dstptr += eltsz * dst_index;
95 srcptr += eltsz * src_index;
96
97 // Do the copy either using the assignment operator of the type, or using
98 // simple memory copying:
99 TMethodCall* mc = m_assign.call();
100 if( mc ) {
101 auto copyone = [mc] (void* dst_, const void* src_)
102 {
103 mc->ResetParam();
104 mc->SetParam( ( Long_t ) src_ );
105 mc->Execute( dst_ );
106 };
107
108 // If the source range doesn't overlap with the destination:
109 if( dstptr > srcptr && ( srcptr + n * eltsz ) > dstptr ) {
110 for( size_t i = n - 1; i < n; --i ) {
111 copyone( dstptr + i*eltsz, srcptr + i*eltsz );
112 }
113 }
114 // If it does:
115 else {
116 for( size_t i = 0; i < n; ++i ) {
117 copyone( dstptr + i*eltsz, srcptr + i*eltsz );
118 }
119 }
120
121 } else {
122 memmove( dstptr, srcptr, n * eltsz );
123 }
124
125 return;
126 }
127
129 SG::AuxVectorData& dst, size_t dst_index,
130 const SG::AuxVectorData& src,
131 size_t src_index,
132 size_t n) const {
133
134 // Do a "regular" copy.
135 copy( auxid, dst, dst_index, src, src_index, n );
136
137 ::Warning( "xAOD::TAuxVectorFactory::TAuxVectorFactory",
138 XAOD_MESSAGE( "copyForOutput called; should only be used "
139 "with pool converters." ) );
140 }
141
143 SG::AuxVectorData& a, size_t aindex,
144 SG::AuxVectorData& b, size_t bindex,
145 size_t n ) const {
146
147 if (n == 0) return;
148
149 // The size of one element in memory:
150 const size_t eltsz = m_proxy->GetIncrement();
151
152 // Get the location of the two elements in memory:
153 char* aptr = reinterpret_cast<char*>( a.getDataArray (auxid) );
154 char* bptr = &a == &b ? aptr : reinterpret_cast<char*>( b.getDataArray (auxid) );
155 aptr += eltsz * aindex;
156 bptr += eltsz * bindex;
157
158 TMethodCall* mc = m_assign.call();
159 if( mc ) {
160
161 // Create a temporary object in memory:
162 TClass* eltClass = m_proxy->GetValueClass();
163 void* tmp = eltClass->New();
164
165 for (size_t i = 0; i < n; ++i) {
166 // tmp = a
167 mc->ResetParam();
168 mc->SetParam( ( Long_t ) aptr );
169 mc->Execute( static_cast<void*>( tmp ) );
170 // a = b
171 mc->ResetParam();
172 mc->SetParam( ( Long_t ) bptr );
173 mc->Execute( static_cast<void*>( aptr ) );
174 // b = tmp
175 mc->ResetParam();
176 mc->SetParam( ( Long_t ) tmp );
177 mc->Execute( static_cast<void*>( bptr ) );
178 aptr += eltsz;
179 bptr += eltsz;
180 }
181
182 // Delete the temporary object:
183 eltClass->Destructor( tmp );
184
185 } else {
186
187 // Allocate some temporary memory for the swap:
188 std::vector< char > tmp( eltsz*n );
189 // tmp = a
190 memcpy( tmp.data(), aptr, eltsz*n );
191 // a = b
192 memcpy( aptr, bptr, eltsz*n );
193 // b = tmp
194 memcpy( bptr, tmp.data(), eltsz*n );
195 }
196
197 return;
198 }
199
201 size_t dst_index,
202 size_t n ) const {
203
204 if (n == 0) return;
205
206 // The size of one element in memory:
207 const size_t eltsz = m_proxy->GetIncrement();
208
209 // Get the memory address of the element:
210 char* dptr = reinterpret_cast< char* >( dst ) + eltsz * dst_index;
211
212 TMethodCall* mc = m_assign.call();
213 if( mc ) {
214 // Assign the default element's contents to this object:
215 for (size_t i = 0; i < n; ++i) {
216 mc->ResetParam();
217 mc->SetParam( ( Long_t ) m_defElt );
218 mc->Execute( static_cast<void*>( dptr ) );
219 dptr += eltsz;
220 }
221 } else {
222 // Set the memory to zero:
223 memset( dst, 0, eltsz*n );
224 }
225
226 return;
227 }
228
229
232 size_t dst_index,
233 size_t n ) const {
234
235 clear( dst.getDataArray (auxid), dst_index, n );
236 return;
237 }
238
240
241 return m_proxy->GetIncrement();
242 }
243
244 const std::type_info* TAuxVectorFactory::tiVec() const {
245
246 return m_class->GetTypeInfo();
247 }
248
249 const std::type_info* TAuxVectorFactory::tiAlloc() const {
250
251 return nullptr;
252 }
253
254 std::string TAuxVectorFactory::tiAllocName() const {
255
256 std::string name = SG::normalizedTypeinfoName (*m_class->GetTypeInfo());
258 std::string alloc_name;
259 if (cn.ntargs() >= 2) {
260 alloc_name = cn.targ(1).fullName();
261 }
262 else if (cn.ntargs() == 1) {
263 alloc_name = "std::allocator<" + cn.targ(0).fullName();
264 if (alloc_name[alloc_name.size()-1] == '>') alloc_name += " ";
265 alloc_name += ">";
266 }
267 return alloc_name;
268 }
269
270} // namespace xAOD
Manage lookup of vectors of auxiliary data.
#define XAOD_MESSAGE(MESSAGE)
Simple macro for printing error/verbose messages.
Recursively separate out template arguments in a C++ class name.
static Double_t a
Helper for getting a const version of a pointer.
Recursively separate out template arguments in a C++ class name.
std::string fullName() const
Return the full name of the expression.
const ClassName & targ(size_t i) const
Return one template argument.
size_t ntargs() const
Return number of template arguments.
Manage lookup of vectors of auxiliary data.
const void * getDataArray(SG::auxid_t auxid) const
Return a const pointer to the start of an aux data vector.
Abstract interface for manipulating vectors of arbitrary types.
void * m_defElt
Pointer to a default element object in memory.
void clear(void *dst, size_t dst_index, size_t n) const
Clear the payload of a given range inside a vector.
virtual const std::type_info * tiAlloc() const override
Return the type_info of the vector allocator.
virtual void copy(SG::auxid_t auxid, SG::AuxVectorData &dst, size_t dst_index, const SG::AuxVectorData &src, size_t src_index, size_t n) const override
Copy elements from one location to another.
::TClass * m_class
The type that this factory operates on.
virtual void copyForOutput(SG::auxid_t auxid, SG::AuxVectorData &dst, size_t dst_index, const SG::AuxVectorData &src, size_t src_index, size_t n) const override
Copy one element from one location to another.
virtual size_t getEltSize() const override
Size of the elements inside the vector type.
virtual ~TAuxVectorFactory()
Destructor.
virtual void swap(SG::auxid_t auxid, SG::AuxVectorData &a, size_t aindex, SG::AuxVectorData &b, size_t bindex, size_t n) const override
Swap the payload of two ranges of elements in memory.
virtual const std::type_info * tiVec() const override
Type info of the vector type handled by the factory object.
virtual std::unique_ptr< SG::IAuxTypeVector > create(SG::auxid_t auxid, size_t size, size_t capacity, bool isLinked) const override
Create a new vector in memory with the requested size and capacity.
TAuxVectorFactory(::TClass *cl)
Constructor, setting up the object based on a dictionary.
virtual std::unique_ptr< SG::IAuxTypeVector > createFromData(SG::auxid_t auxid, void *data, SG::IAuxTypeVector *linkedVector, bool isPacked, bool ownFlag, bool isLinked) const override
Create a vector object of this type from a data blob.
::TVirtualCollectionProxy * m_proxy
ROOT's description of the vector type.
virtual std::string tiAllocName() const override
Return the (demangled) name of the vector allocator.
const T * as_const_ptr(const T *p)
Helper for getting a const version of a pointer.
std::string normalizedTypeinfoName(const std::type_info &info)
Convert a type_info to a normalized string representation (matching the names used in the root dictio...
size_t auxid_t
Identifier for a particular aux data item.
Definition AuxTypes.h:27
ICaloAffectedTool is abstract interface for tools checking if 4 mom is in calo affected region.
Convert a type_info to a normalized string representation (matching the names used in the root dictio...