ATLAS Offline Software
Loading...
Searching...
No Matches
RootAuxVectorFactory.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
11
12
17#include "AthLinks/ElementLinkBase.h"
18#include "CxxUtils/ClassName.h"
20#include "TClass.h"
21#include "TVirtualCollectionProxy.h"
22#include "TROOT.h"
23#include <iostream>
24#include <stdexcept>
25
26
27namespace {
28
29
38TClass* lookupVectorType (TClass *cl)
39{
40 std::string tname = cl->GetName();
41 tname += "::vector_type";
42 TDataType* typ = gROOT->GetType (tname.c_str());
43 if (typ)
44 return TClass::GetClass (typ->GetFullTypeName());
45 return nullptr;
46}
47
48
49} // anonymous namespace
50
51
52namespace SG {
53
54
65 size_t size, size_t /*capacity*/,
66 bool isLinked)
68 m_factory (factory),
69 m_ownFlag (true)
70{
71 const TClass* vecClass = factory->vecClass();
72 m_proxy.reset (vecClass->GetCollectionProxy()->Generate());
73 m_obj = factory->objClass()->New ();
74 m_vec = reinterpret_cast<char*> (m_obj) + factory->offset();
75 m_proxy->PushProxy (m_vec);
76 this->resize (size);
77}
78
79
97 void* data,
98 bool isPacked,
99 bool ownFlag,
100 bool isLinked)
102 m_factory (factory),
103 m_ownFlag (ownFlag)
104{
105 if (isPacked) std::abort();
106 const TClass* vecClass = factory->vecClass();
107 m_proxy.reset (vecClass->GetCollectionProxy()->Generate());
108 m_obj = data;
109 m_vec = reinterpret_cast<char*> (m_obj) + factory->offset();
110 m_proxy->PushProxy (m_vec);
111}
112
113
119 : IAuxTypeVector (other),
120 m_factory (other.m_factory),
121 m_proxy (other.m_proxy->Generate()),
122 m_ownFlag (true)
123{
124 m_obj = m_factory->objClass()->New ();
125 m_vec = reinterpret_cast<char*> (m_obj) + m_factory->offset();
126 m_proxy->PushProxy (m_vec);
127 size_t sz = other.size();
128 this->resize (sz);
129
130 if (sz > 0) {
131 const RootUtils::Type& rootType = m_factory->rootType();
132 const void* otherPtr = other.toPtr();
133 rootType.copyRange (this->toPtr(), otherPtr, sz);
134 }
135}
136
137
144{
145 if (m_ownFlag)
146 m_factory->objClass()->Destructor (m_obj);
147}
148
149
153std::unique_ptr<SG::IAuxTypeVector> RootAuxVector::clone() const
154{
155 return std::make_unique<RootAuxVector> (*this);
156}
157
158
163{
164 if (m_proxy->Size() == 0)
165 return 0;
166 return m_proxy->At(0);
167}
168
169
173const void* RootAuxVector::toPtr () const
174{
175 if (m_proxy->Size() == 0)
176 return 0;
177 TVirtualCollectionProxy* proxy ATLAS_THREAD_SAFE = m_proxy.get();
178 return proxy->At(0);
179}
180
181
186{
187 return m_obj;
188}
189
190
195{
196 return m_proxy->Size();
197}
198
199
207{
208 const void* orig = this->getDataSpan().beg;
209 m_proxy->Allocate(sz, false);
210 this->storeDataSpan();
211 return this->getDataSpan().beg == orig;
212}
213
214
219void RootAuxVector::reserve (size_t /*sz*/)
220{
221}
222
223
250bool RootAuxVector::shift (size_t pos, ptrdiff_t offs)
251{
252 size_t eltsz = m_proxy->GetIncrement();
253
254 const RootUtils::Type& rootType = m_factory->rootType();
255
256 if (offs < 0) {
257 if (-offs > static_cast<ptrdiff_t>(pos)) offs = -pos;
258 char* beg = reinterpret_cast<char*>(m_proxy->At(0));
259 rootType.copyRange (beg + eltsz*(pos+offs),
260 beg + eltsz*pos,
261 m_proxy->Size() - pos);
262 m_proxy->Allocate (m_proxy->Size() + offs, false);
263 this->storeDataSpan();
264 return true;
265 }
266 else if (offs > 0) {
267 size_t oldsz = m_proxy->Size();
268 m_proxy->Allocate (oldsz + offs, false);
269 char* beg = reinterpret_cast<char*>(m_proxy->At(0));
270 if (pos < oldsz)
271 rootType.copyRange (beg + eltsz*(pos+offs),
272 beg + eltsz*pos,
273 oldsz - pos);
274 rootType.clearRange (beg + eltsz*pos, offs);
275 this->storeDataSpan();
276 return false;
277 }
278 return true;
279}
280
281
305 void* src, size_t src_pos, size_t src_n,
306 SG::IAuxStore& /*srcStore*/)
307{
308 size_t eltsz = m_proxy->GetIncrement();
309 const void* orig = this->getDataSpan().beg;
310 const RootUtils::Type& rootType = m_factory->rootType();
311
312 char* srcp = reinterpret_cast<char*> (src);
313 char* begp = srcp + src_pos*eltsz;
314
315 shift (pos, src_n);
316 // FIXME: want move, not copy.
317 // But i don't seem to be able to call move operations through cling,
318 // so just use copy for now.
319 rootType.copyRange (reinterpret_cast<char*>(this->toPtr()) + pos*eltsz,
320 begp, src_n);
321 this->storeDataSpan();
322 return this->getDataSpan().beg == orig;
323}
324
325
337const std::type_info* RootAuxVector::objType() const
338{
339 return m_factory->objClass()->GetTypeInfo();
340}
341
342
349{
350 void* ptr ATLAS_THREAD_SAFE = const_cast<void*>(this->toPtr());
351 return AuxDataSpanBase (ptr, m_proxy->Size());
352}
353
354
362
363
364//==================================================================
365
366
372 : m_objClass (objClass),
373 m_vecClass (objClass),
374 m_offset (0),
375 m_isEL (NONE)
376{
377 TVirtualCollectionProxy* proxy = m_vecClass->GetCollectionProxy();
378
379 if (!proxy) {
380 TClass* vecClass = lookupVectorType (objClass);
381 if (vecClass) {
382 m_vecClass = vecClass;
383 Int_t offs = objClass->GetBaseClassOffset (vecClass);
384 if (offs >= 0) {
385 m_offset = offs;
386 proxy = vecClass->GetCollectionProxy();
387 }
388 else {
389 ATHCONTAINERS_ERROR("RootAuxVectorFactory::RootAuxVectorFactory",
390 std::string("Can't find vector base class in ") +
391 objClass->GetName());
392 }
393 }
394 }
395
396 if (!proxy) {
397 std::string err = "Can't find collection proxy for ";
398 err += m_vecClass->GetName();
399 throw std::runtime_error (err.c_str());
400 }
401
402 if (m_vecClass->GetTypeInfo() == 0) {
403 ATHCONTAINERS_ERROR("RootAuxVectorFactory::RootAuxVectorFactory",
404 std::string("No type_info available for class ") +
405 m_vecClass->GetName() +
406 std::string(". There is probably a missing dictionary. We will likely crash further on."));
407 }
408
409 TClass* eltClass = proxy->GetValueClass();
410 if (eltClass) {
411 m_type.init (eltClass);
412
413 const std::type_info* ti = eltClass->GetTypeInfo();
414 if (ti) {
415
416 static const CxxUtils::ClassName pat1 ("ElementLink<$T>");
417 static const CxxUtils::ClassName pat2 ("std::vector<ElementLink<$T> >");
418
421 if (clname.match (pat1, matches)) {
423 if (eltClass->GetBaseClass ("ElementLinkBase") == nullptr) {
425 }
426 }
427 else if (clname.match (pat2, matches)) {
429
430 TVirtualCollectionProxy* proxy2 = eltClass->GetCollectionProxy();
431 if (proxy2) {
432 TClass* innerEltClass = proxy2->GetValueClass();
433 if (innerEltClass) {
434 if (innerEltClass->GetBaseClass ("ElementLinkBase") == nullptr) {
436 }
437 }
438 }
439 }
440 }
441 }
442 else
443 m_type.init (proxy->GetType());
444}
445
446
453
454
462std::unique_ptr<SG::IAuxTypeVector>
464 size_t size,
465 size_t capacity,
466 bool isLinked) const
467{
468 return std::make_unique<RootAuxVector> (this, auxid, size, capacity,
469 isLinked);
470}
471
472
493std::unique_ptr<SG::IAuxTypeVector>
495 void* data,
496 IAuxTypeVector* linkedVector,
497 bool isPacked,
498 bool ownFlag,
499 bool isLinked) const
500{
501 if (linkedVector) std::abort();
502 return std::make_unique<RootAuxVector> (this, auxid, data, isPacked, ownFlag,
503 isLinked);
504}
505
506
510 AuxVectorData& dst,
511 size_t dst_index,
512 const AuxVectorData& src,
513 size_t src_index,
514 size_t n) const
515{
516 if (n == 0) return nullptr;
517 size_t eltsz = m_type.getSize();
518 char* dstptr = reinterpret_cast<char*> (dst.getDataArray (auxid));
519 if (&src == &dst) {
520 // Source and destination containers are the same,
521 // so we don't need to bother with fetching the src pointer.
522 // copyRange properly handles overlapping regions.
523 m_type.copyRange (dstptr + eltsz*dst_index, dstptr + eltsz*src_index, n);
524 return dstptr + eltsz*dst_index;
525 }
526 else {
527 const char* srcptr = reinterpret_cast<const char*>(src.getDataArrayAllowMissing (auxid));
528 if (srcptr) {
529 m_type.copyRange (dstptr + eltsz*dst_index, srcptr + eltsz*src_index, n);
530 return dstptr + eltsz*dst_index;
531 }
532 else {
533 m_type.clearRange (dstptr + eltsz*dst_index, n);
534 return nullptr;
535 }
536 }
537}
538
539
552 AuxVectorData& dst,
553 size_t dst_index,
554 const AuxVectorData& src,
555 size_t src_index,
556 size_t n) const
557{
558 (void)copyImpl (auxid, dst, dst_index, src, src_index, n);
559}
560
561
575 AuxVectorData& dst, size_t dst_index,
576 const AuxVectorData& src, size_t src_index,
577 size_t n) const
578{
579 char* dstptr = copyImpl (auxid, dst, dst_index, src, src_index, n);
580
581 if (m_isEL == ELEMENT_LINK) {
582 size_t eltsz = m_type.getSize();
583 for (size_t i = 0; i < n; i++) {
584 reinterpret_cast<ElementLinkBase*>(dstptr + i*eltsz)->thin();
585 }
586 }
587 else if (m_isEL == ELEMENT_LINK_VECTOR) {
588 size_t eltsz = m_type.getSize();
589 for (size_t i = 0; i < n; i++) {
590 std::vector<ElementLinkBase>& v =
591 *reinterpret_cast<std::vector<ElementLinkBase>* > (dstptr +i*eltsz);
592 for (ElementLinkBase& el : v) {
593 el.thin();
594 }
595 }
596 }
597 else if (m_isEL == ELEMENT_LINK_NONPOINTER) {
598 ATHCONTAINERS_ERROR("RootAuxVectorFactory::copyForOutput",
599 std::string("Cannot apply thinning for ElementLink with non-pointer element: ") +
600 m_vecClass->GetName());
601 }
602}
603
604
618 AuxVectorData& a, size_t aindex,
619 AuxVectorData& b, size_t bindex,
620 size_t n) const
621{
622 if (n == 0) return;
623 void* aptr = a.getDataArray (auxid);
624 void* bptr = &a == &b ? aptr : b.getDataArray (auxid);
625 m_type.swapRange (aptr, aindex, bptr, bindex, n);
626}
627
628
637 AuxVectorData& dst, size_t dst_index,
638 size_t n) const
639{
640 if (n == 0) return;
641 m_type.clearRange (dst.getDataArray (auxid), dst_index, n);
642}
643
644
649{
650 return m_type.getSize();
651}
652
653
657const std::type_info* RootAuxVectorFactory::tiVec() const
658{
659 return m_objClass->GetTypeInfo();
660}
661
662
669{
670 return true;
671}
672
673
679const std::type_info* RootAuxVectorFactory::tiAlloc() const
680{
681 return nullptr;
682}
683
684
689{
690 std::string name = SG::normalizedTypeinfoName (*m_vecClass->GetTypeInfo());
691 CxxUtils::ClassName cn (name);
692 std::string alloc_name;
693 if (cn.ntargs() >= 2) {
694 alloc_name = cn.targ(1).fullName();
695 }
696 else if (cn.ntargs() == 1) {
697 alloc_name = "std::allocator<" + cn.targ(0).fullName();
698 if (alloc_name[alloc_name.size()-1] == '>') alloc_name += " ";
699 alloc_name += ">";
700 }
701 return alloc_name;
702}
703
704
705} // namespace SG
Manage lookup of vectors of auxiliary data.
Recursively separate out template arguments in a C++ class name.
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
static Double_t sz
static Double_t a
if(febId1==febId2)
Dynamic implementation of IAuxVectorFactory, relying on root's vector proxy.
Define macros for attributes used to control the static checker.
#define ATLAS_THREAD_SAFE
Recursively separate out template arguments in a C++ class name.
std::string fullName() const
Return the full name of the expression.
std::map< std::string, ClassName > match_t
Map used to hold variable assignments from matching.
bool match(const ClassName &pattern, match_t &matches) const
Match this expression against a pattern.
const ClassName & targ(size_t i) const
Return one template argument.
size_t ntargs() const
Return number of template arguments.
Base class for ElementLinks to vectors of pointers.
Wrapper for ROOT types.
Definition Type.h:40
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.
Interface for non-const operations on an auxiliary store.
Definition IAuxStore.h:48
Abstract interface for manipulating vectors of arbitrary types.
bool isLinked() const
Return true if this variable is linked from another one.
auxid_t auxid() const
Return the auxid of the variable this vector represents.
void storeDataSpan(void *beg, size_t size)
Update the stored span.
const AuxDataSpanBase & getDataSpan() const
Return a reference to a description of this vector's start+size.
IAuxTypeVector(auxid_t auxid, bool isLinked)
Constructor.
Dynamic implementation of IAuxVectorFactory, relying on root's vector proxy.
RootAuxVectorFactory(TClass *objClass)
Constructor.
size_t offset() const
Return the offset of the vector within the object.
virtual void copy(SG::auxid_t auxid, AuxVectorData &dst, size_t dst_index, const AuxVectorData &src, size_t src_index, size_t n) const override
Copy elements between vectors.
virtual bool isDynamic() const override
True if the vectors created by this factory work by dynamic emulation (via TVirtualCollectionProxy or...
virtual ~RootAuxVectorFactory() override
Destructor.
virtual void swap(SG::auxid_t auxid, AuxVectorData &a, size_t aindex, AuxVectorData &b, size_t bindex, size_t n) const override
Swap elements between vectors.
RootUtils::Type m_type
Wrapper for the ROOT type of the element.
char * copyImpl(SG::auxid_t auxid, AuxVectorData &dst, size_t dst_index, const AuxVectorData &src, size_t src_index, size_t n) const
Helper for copy; returns a pointer to the first destination object, or nullptr if the destination was...
virtual const std::type_info * tiVec() const override
Return the type_info of the overall object.
size_t m_offset
Offset of the STL vector within the overall object.
enum SG::RootAuxVectorFactory::@071257101107162132204103261125230107154016006205 m_isEL
Flag to tell whether we need to do thinning.
virtual const std::type_info * tiAlloc() const override
Return the type_info of the vector allocator.
virtual std::string tiAllocName() const override
Return the (demangled) name of the vector allocator.
TClass * m_objClass
The TClass for the overall object.
TClass * m_vecClass
The TClass for the std::vector.
virtual void copyForOutput(SG::auxid_t auxid, AuxVectorData &dst, size_t dst_index, const AuxVectorData &src, size_t src_index, size_t n) const override
Copy elements between vectors, possibly applying thinning.
virtual std::unique_ptr< SG::IAuxTypeVector > createFromData(SG::auxid_t auxid, void *data, IAuxTypeVector *linkedVector, bool isPacked, bool ownFlag, bool isLinked) const override
Create a vector object of this type from a data blob.
virtual std::unique_ptr< SG::IAuxTypeVector > create(SG::auxid_t auxid, size_t size, size_t capacity, bool isLinked) const override
Create a vector object of this type.
virtual size_t getEltSize() const override
Return the size of an element of this vector type.
virtual void clear(SG::auxid_t auxid, AuxVectorData &dst, size_t dst_index, size_t n) const override
Clear a range of elements within a vector.
const RootAuxVectorFactory * m_factory
Pointer back to the factory class for this type.
void * m_vec
Pointer to the vector object itself.
virtual void * toPtr() override
Return a pointer to the start of the vector's data.
std::unique_ptr< TVirtualCollectionProxy > m_proxy
The collection proxy for the vector.
bool m_ownFlag
Should be delete the vector object?
RootAuxVector(const RootAuxVectorFactory *factory, SG::auxid_t auxid, size_t size, size_t capacity, bool isLinked)
Constructor.
virtual AuxDataSpanBase getDataSpanImpl() const override final
Return a span object describing the current vector.
virtual std::unique_ptr< SG::IAuxTypeVector > clone() const override
Make a copy of this vector.
virtual void * toVector() override
Return a pointer to the overall object.
virtual bool insertMove(size_t pos, void *src, size_t src_pos, size_t src_n, SG::IAuxStore &srcStore) override
Insert elements into the vector via move semantics.
void storeDataSpan()
Update the stored span.
virtual ~RootAuxVector() override
Destructor.
void * m_obj
Pointer to the overall object itself.
virtual bool resize(size_t sz) override
Change the size of the vector.
virtual bool shift(size_t pos, ptrdiff_t offs) override
Shift the elements of the vector.
virtual const std::type_info * objType() const override
Return the type of the complete object to be saved.
virtual void reserve(size_t sz) override
Change the capacity of the vector.
virtual size_t size() const override
Return the size of the vector.
Helper for emitting error messages.
#define ATHCONTAINERS_ERROR(ctx, msg)
Definition error.h:54
Forward declaration.
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
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
TClass * lookupVectorType(TClass &cl)
Internal function used by xAOD::TAuxStore and xAOD::RAuxStore.
Convert a type_info to a normalized string representation (matching the names used in the root dictio...
Minimal span-like object describing the range of an auxiliary variable.
Definition AuxDataSpan.h:40
void * beg
Pointer to the start of the variable's vector.
Definition AuxDataSpan.h:54