ATLAS Offline Software
Loading...
Searching...
No Matches
AthLinks/ElementLinkVector.h
Go to the documentation of this file.
1// This file's extension implies that it's C, but it's really -*- C++ -*-.
2
3/*
4 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
5*/
6
7#ifndef ATHLINKS_ELEMENTLINKVECTOR_H
8#define ATHLINKS_ELEMENTLINKVECTOR_H
9
10#include <algorithm>
11#include <exception>
12#include <functional>
13#include <vector>
14#include <boost/iterator/transform_iterator.hpp>
15#include <RootMetaSelection.h>
16
17#include "AthLinks/ElementLinkVectorBase.h"
18#include "AthLinks/DataLink.h"
19#include "AthLinks/ElementLink.h"
22#include "GaudiKernel/MsgStream.h"
23
24
25// Forward declaration(s):
26namespace ROOT { namespace Meta { namespace Selection {
27 template< class STORABLE >
28 struct ElementLinkVector;
29}}}
30
31// forward declarations of our friends
32template <typename DOBJ>
33bool
35 const ElementLinkVector<DOBJ>& rhs);
36template <typename DOBJ>
37bool
39 const ElementLinkVector<DOBJ>& rhs);
40
61
62template <typename DOBJ>
64{
65private:
68
69
70public:
71 typedef typename std::vector< DataLink<DOBJ> > DataLinkVector;
73
78 {
79 // i.e. friend class ElemLinkRef;
81 ElemLink operator()(ElemLinkRef& shortRef) const {
82 return shortRef.elementLink();
83 }
84 const ElemLink operator()(const ElemLinkRef& shortRef) const {
85 return shortRef.elementLink();
86 }
87 };
88
89private:
91 typedef typename std::vector<ElemLinkRef> RefVector;
93
96
97public:
100 typedef typename ElemLink::ID_type ID_type;
101 typedef typename ElemLink::sgkey_t sgkey_t;
102
103
104 // We used to just use transform_iterator directly.
105 // However, postincrement for transform_iterator is implemented as a free
106 // function, which pyroot doesn't see. This causes python iteration
107 // over ElementLinkVector to fail.
108 template <class Iterator>
110 : public boost::transform_iterator<Short2LongRef, Iterator>
111 {
112 public:
113 typedef boost::transform_iterator<Short2LongRef, Iterator> Base;
114 using Base::Base;
115 ELVIterator (const Base& b) : Base (b) {}
116 using Base::operator++;
117 using Base::operator--;
118 ELVIterator operator++(int) { ELVIterator tmp=*this; ++(*this); return tmp; }
119 ELVIterator operator--(int) { ELVIterator tmp=*this; --(*this); return tmp; }
120 };
121
123
125 //FIXME typedef const ElemLink& const_reference;
127 typedef ELVIterator<typename RefVector::iterator> iterator;
128 typedef ELVIterator<typename RefVector::const_iterator> const_iterator;
129 //1.30 typedef typename boost::transform_iterator_generator<Short2LongRef, typename RefVector::iterator>::type iterator;
130 //1.30 typedef typename boost::transform_iterator_generator<Short2LongRef, typename RefVector::const_iterator>::type const_iterator;
131 typedef typename RefVector::size_type size_type;
132 typedef typename RefVector::difference_type difference_type;
134 typedef typename RefVector::allocator_type allocator_type;
136 typedef const ElemLink* const_pointer;
137 typedef ELVIterator<typename RefVector::reverse_iterator> reverse_iterator;
138 typedef ELVIterator<typename RefVector::const_reverse_iterator> const_reverse_iterator;
139 //1.30 typedef typename boost::transform_iterator_generator<Short2LongRef, typename RefVector::reverse_iterator>::type reverse_iterator;
140 //1.30 typedef typename boost::transform_iterator_generator<Short2LongRef, typename RefVector::const_reverse_iterator>::type const_reverse_iterator;
142
143
146
147
151
153 return m_shortRefs[index].elementIndex();
154 }
155
157 return m_shortRefs[index].dataID();
158 }
159
161
163
164 const DataLinkVector& hostDObjs() const { return m_hostDObjs; }
165 typename DataLinkVector::iterator beginHostDObjs() {
166 return m_hostDObjs.begin();
167 }
168 typename DataLinkVector::iterator endHostDObjs() {
169 return m_hostDObjs.end();
170 }
171 typename DataLinkVector::const_iterator beginHostDObjs() const {
172 return m_hostDObjs.begin();
173 }
174 typename DataLinkVector::const_iterator endHostDObjs() const {
175 return m_hostDObjs.end();
176 }
177
178 typename DataLinkVector::const_iterator findHostDObj(const ElemLink& link) const;
180 typename DataLinkVector::iterator findHostDObj(const ElemLink& link);
181
182 // Set the vector of host data objects from @a dobjs.
183 // @a dobjs is destroyed.
184 // This is an error if the vector is not empty.
186
188
189
191
193
196 {
197 if (n > 0)
198 addHostDObj(link);
199 }
200
201 ElementLinkVector(int n, const ElemLink& link = ElemLink()) :
203 {
204 if (n > 0)
205 addHostDObj(link);
206 }
207
208 ElementLinkVector(long n, const ElemLink& link = ElemLink()) :
210 {
211 if (n > 0)
212 addHostDObj(link);
213 }
214
217
221
223 ElementLinkVectorBase( std::move(vec) ),
224 m_shortRefs(std::move(vec.m_shortRefs)),
225 m_hostDObjs(std::move(vec.m_hostDObjs)) { }
226
228 {
229 if (this != &vec) {
230 m_persKeys = vec.m_persKeys;
231 m_persIndices = vec.m_persIndices;
232 m_shortRefs = vec.m_shortRefs;
233 m_hostDObjs = vec.m_hostDObjs;
234 }
235 return *this;
236 }
237
239 {
240 if (this != &vec) {
241 m_persKeys = std::move(vec.m_persKeys);
242 m_persIndices = std::move(vec.m_persIndices);
243 m_shortRefs = std::move(vec.m_shortRefs);
244 m_hostDObjs = std::move(vec.m_hostDObjs);
245 }
246 return *this;
247 }
248
249 template <class InputIterator>
250 void assign(InputIterator first, InputIterator last) {
251 clear();
252 insert(begin(), first, last);
253 }
254 void assign(size_type n, const ElemLink& link) {
255 clear();
256 insert(begin(), n, link);
257 }
258
260
261 // Also return list of shortrefs.
262 bool toPersistent(std::vector<typename DataLinkVector::size_type>& shortrefs);
263
264 // Just the DataLink part of toPersistent().
267 void doRemap();
269
271
272
273 iterator begin() { return iterator(m_shortRefs.begin(), Short2LongRef()); }
275 return const_iterator(m_shortRefs.begin(), Short2LongRef());
276 }
277 iterator end() { return iterator(m_shortRefs.end(), Short2LongRef()); }
279 return const_iterator(m_shortRefs.end(), Short2LongRef());
280 }
281 reverse_iterator rbegin() { return reverse_iterator(m_shortRefs.begin(), Short2LongRef()); }
283 return const_reverse_iterator(m_shortRefs.begin(), Short2LongRef());
284 }
285 reverse_iterator rend() { return reverse_iterator(m_shortRefs.end(), Short2LongRef()); }
287 return const_reverse_iterator(m_shortRefs.end(), Short2LongRef());
288 }
289
290
292
293 size_type size() const { return m_shortRefs.size(); }
294 size_type max_size() const { return m_shortRefs.max_size(); }
295 void resize(size_type sz, const ElemLink& link = ElemLink());
296 size_type capacity() const { return m_shortRefs.capacity(); }
297 bool empty() const { return 0 == size(); }
298 void reserve(size_type n) { return m_shortRefs.reserve(n); }
300
302
303 // reference operator[](size_type n);
305 operator[](size_type n) const { return m_shortRefs[n].elementLink(); }
306 // reference at(size_type n);
308 at(size_type n) const { return m_shortRefs.at(n).elementLink(); }
309 // reference front();
310 const_reference front() const{ return m_shortRefs.front().elementLink(); }
311 // reference back();
312 const_reference back() const{ return m_shortRefs.back().elementLink(); }
314
316
317 void push_back(const ElemLink& link) {
318 addHostDObj(link);
319 m_shortRefs.push_back(ElemLinkRef(link));
320 }
321 void pop_back() { //FIXME CHECK
323 m_shortRefs.pop_back();
324 }
325
326 // Add an element by indices.
327 // (Mostly for use from persistency.)
328 void push_back (typename DataLinkVector::size_type nameIndex,
330
331 iterator insert(iterator position, const ElemLink& link);
332 void insert(iterator position, size_type n, const ElemLink& link);
333
336
338 m_hostDObjs.swap(vec.m_hostDObjs);
339 m_shortRefs.swap(vec.m_shortRefs);
340 }
341
342 void clear() {
343 m_hostDObjs.clear();
344 m_shortRefs.clear();
345 }
346
347
348private:
350 void toTransient( uint64_t& dummy );
351 void toTransient( uint32_t& dummy );
353 template< typename INDEX_TYPE >
354 void toTransient( INDEX_TYPE& dummy );
355
358#ifdef __ELVDEBUG
359 link
360#endif
361 ) {
362#ifdef __ELVDEBUG
363 std::cout << "DUMMY removeHostDObj called for link "
364 << link.dataID() << "/" << link.index() << std::endl;
365#endif
366 //FIXME this is a dummy until we find how to remove an host w/o
367 //FIXME screwing up the otherElemLinkRefs
368 //FIXME m_hostDObjs.erase(findHostDObj(link));
369 }
370
372 void addHostDObj(const ElemLink& link);
373
375 typename RefVector::const_iterator
377 typename RefVector::const_iterator ret(m_shortRefs.begin());
378 advance(ret, distance(begin(), longIter));
379#ifdef __ELVDEBUG
380 std::cout << "shortIterFromLong(const version) called for "
381 << longIter->dataID() << "/" << longIter->index()
382 << " advance by " << distance(begin(), longIter)
383 << " result is " << ret->dataID() << "/" << ret->index() << std::endl;
384#endif
385 return ret;
386 }
387
389 typename RefVector::iterator
391 typename RefVector::iterator ret(m_shortRefs.begin());
392 advance(ret, distance(begin(), longIter));
393#ifdef __ELVDEBUG
394 std::cout << "shortIterFromLong called for "
395 << longIter->dataID() << "/" << longIter->index()
396 << " advance by " << distance(begin(), longIter)
397 << " result is " << ret->dataID() << "/" << ret->index() << std::endl;
398#endif
399 return ret;
400 }
401
403
404 template <class InputIterator>
405 ElementLinkVector(InputIterator first, InputIterator last);
406 template <class InputIterator>
407 void insert(iterator position, InputIterator first, InputIterator last);
409
411 friend bool operator == <>(const ElemLinkVec&, const ElemLinkVec&);
413 friend bool operator < <>(const ElemLinkVec&, const ElemLinkVec&);
414
416 typedef typename
418
419}; // class ElementLinkVector
420
421template <typename DOBJ>
424
425/*
426 * The following piece of code makes the Reflex dictionary think of
427 * "ElementLinkVector< T, DataProxyStorage< T >,
428 * SG::GenerateIndexingPolicy< T >::type >"
429 * simply as "ElementLinkVector< T >". This is vital for tricking
430 * ROOT into reading this object's payload back into a different
431 * ElementLink implementation in vanilla ROOT.
432 */
433namespace ROOT { namespace Meta { namespace Selection {
434
435template< class STORABLE >
436struct ElementLinkVector : public SelectNoInstance
437{
440 ROOT::Meta::Selection::MemberAttributes< kTransient > m_shortRefs;
441 ROOT::Meta::Selection::MemberAttributes< kTransient > m_hostDObjs;
442};
443
444}}} // ROOT namespace
445
446// Hide the rest from the dictionary generator:
447#ifndef __GCCXML__
448
449#include "AthLinks/ElementLinkVector.icc"
450#include "AthLinks/tools/SGELVRef.icc" /* to avoid circular deps */
451
453
454template <typename DOBJ>
455bool
457 const ElementLinkVector<DOBJ>& rhs) {
458 return (lhs.m_shortRefs < rhs.m_shortRefs);
459}
460template <typename DOBJ>
461bool
463 const ElementLinkVector<DOBJ>& rhs) {
464 return rhs < lhs;
465}
466template <typename DOBJ>
467bool
469 const ElementLinkVector<DOBJ>& rhs) {
470 return (lhs.m_shortRefs == rhs.m_shortRefs);
471}
472template <typename DOBJ>
473bool
475 const ElementLinkVector<DOBJ>& rhs) {
476 return !operator==(lhs, rhs);
477}
478//FIXME ops <= , => etc
480
481namespace std {
482template <typename DOBJ>
483void
486#ifdef __ELVDEBUG
487 std::cout << "std::swap called for lhs " << std::hex << &lhs
488 << " rhs " << &rhs << std::dec << std::endl;
489#endif
490 lhs.swap(rhs);
491}
492}
493
494#endif // not __GCCXML__
495#endif /*ATHLINKS_ELEMENTLINKVECTOR_H*/
std::vector< size_t > vec
static Double_t sz
ElementLinkVectorBase(const std::vector< uint32_t > &keys=std::vector< uint32_t >(), const std::vector< uint32_t > &indices=std::vector< uint32_t >())
Default constructor.
boost::transform_iterator< Short2LongRef, Iterator > Base
ElementLinkVector implementation for standalone ROOT.
void insert(iterator position, InputIterator first, InputIterator last)
void push_back(typename DataLinkVector::size_type nameIndex, typename ElemLinkRef::index_type elementIndex)
const_iterator begin() const
const_iterator end() const
ElementLink< asso_container_type > ElemLink
ElementLinkVector(long n, const ElemLink &link=ElemLink())
void moveHostDObjs(DataLinkVector &dobjs)
bool toPersistent(std::vector< typename DataLinkVector::size_type > &shortrefs)
ELVIterator< typename RefVector::reverse_iterator > reverse_iterator
void insert(iterator position, size_type n, const ElemLink &link)
void toTransient(uint32_t &dummy)
iterator erase(iterator position)
const_reference operator[](size_type n) const
ElementLinkVector(size_type n, const ElemLink &link)
void addHostDObj(const ElemLink &link)
add host of link to list. No duplicates. O(N) in m_hostDObjs
ElementLinkVector(const ElemLinkVec &vec)
DataLinkVector::const_iterator findHostDObj(const ElemLink &link) const
find the host of an element. Returns endHostDObjs() if not found
void resize(size_type sz, const ElemLink &link=ElemLink())
ElementLinkVector(int n, const ElemLink &link=ElemLink())
ElementLinkVector & operator=(const ElemLinkVec &vec)
DataLinkVector::iterator endHostDObjs()
DataLinkVector::iterator findHostDObj(const ElemLink &link)
find the host of an element. Returns endHostDObjs() if not found
const_reference front() const
RefVector::iterator shortIterFromLong(iterator longIter)
get a short ref iterator from an iterator
DataLinkVector::const_iterator endHostDObjs() const
void push_back(const ElemLink &link)
const_reverse_iterator rend() const
iterator insert(iterator position, const ElemLink &link)
ElementLinkVector(InputIterator first, InputIterator last)
ElementLinkVector(ElemLinkVec &&vec) noexcept
const_reference at(size_type n) const
DataLinkVector::iterator beginHostDObjs()
ELVIterator< typename RefVector::iterator > iterator
index_type elementIndex(size_type index) const
host index of an element, given its ElementLinkVector index. O(1)
ElementConstPointer elementCPtr(size_type index) const
pointer to an element, given its ElementLinkVector index. O(1)
void assign(size_type n, const ElemLink &link)
const_reverse_iterator rbegin() const
std::vector< DataLink< asso_container_type > > DataLinkVector
friend bool operator==(const ElemLinkVec &, const ElemLinkVec &)
access m_shortRefs
ROOT::Meta::Selection::ElementLinkVector< asso_container_type >::self DictSel
RefVector::const_iterator shortIterFromLong(const_iterator longIter) const
get a short ref iterator from an iterator
DataLinkVector::const_iterator beginHostDObjs() const
void swap(ElemLinkVec &vec)
void toTransient(uint64_t &dummy)
Function setting up the object for forward indexing types.
const DataLinkVector & hostDObjs() const
SG::ELVRef< asso_container_type > ElemLinkRef
void toTransient(INDEX_TYPE &dummy)
Function taking care of all the other indexing types (no direct ROOT I/O).
bool toTransient()
Reset the object's internal cache.
ID_type elementDataID(size_type index) const
dataID (long ref) of an element, given its ElementLinkVector index. O(1)
ElementLinkVector< asso_container_type > ElemLinkVec
void removeHostObj(const ElemLink &)
remove host of link from list. O(N) in m_hostDObjs (which is small)
iterator erase(iterator first, iterator last)
ELVIterator< typename RefVector::const_iterator > const_iterator
ELVIterator< typename RefVector::const_reverse_iterator > const_reverse_iterator
const_reference back() const
void assign(InputIterator first, InputIterator last)
a short ref to an ElementLink into an ElementLinkVector.
Definition SGELVRef.h:29
const ElemLink & elementLink() const
get the corresponding ElementLink. O(1)
Definition SGELVRef.h:58
ElemLink::index_type index_type
Definition SGELVRef.h:36
singleton-like access to IMessageSvc via open function and helper
Selection rules: declare transient members.
Definition DataVector.h:581
Definition index.py:1
STL namespace.
void swap(ElementLinkVector< DOBJ > &lhs, ElementLinkVector< DOBJ > &rhs)
a functor turning an ElemLinkRef into an ElementLink
const ElemLink operator()(const ElemLinkRef &shortRef) const
ElemLink operator()(ElemLinkRef &shortRef) const
ROOT::Meta::Selection::MemberAttributes< kTransient > m_shortRefs
ROOT::Meta::Selection::MemberAttributes< kTransient > m_hostDObjs