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 <boost/iterator_adaptors.hpp>
16#include <RootMetaSelection.h>
17
18#include "AthLinks/ElementLinkVectorBase.h"
19#include "AthLinks/DataLink.h"
20#include "AthLinks/ElementLink.h"
23#include "GaudiKernel/MsgStream.h"
24
25
26// Forward declaration(s):
27namespace ROOT { namespace Meta { namespace Selection {
28 template< class STORABLE >
29 struct ElementLinkVector;
30}}}
31
32// forward declarations of our friends
33template <typename DOBJ>
34bool
36 const ElementLinkVector<DOBJ>& rhs);
37template <typename DOBJ>
38bool
40 const ElementLinkVector<DOBJ>& rhs);
41
62
63template <typename DOBJ>
65{
66private:
69
70
71public:
72 typedef typename std::vector< DataLink<DOBJ> > DataLinkVector;
74
79 {
80 // i.e. friend class ElemLinkRef;
82 ElemLink operator()(ElemLinkRef& shortRef) const {
83 return shortRef.elementLink();
84 }
85 const ElemLink operator()(const ElemLinkRef& shortRef) const {
86 return shortRef.elementLink();
87 }
88 };
89
90private:
92 typedef typename std::vector<ElemLinkRef> RefVector;
94
97
98public:
101 typedef typename ElemLink::ID_type ID_type;
102 typedef typename ElemLink::sgkey_t sgkey_t;
103
104
105 // We used to just use transform_iterator directly.
106 // However, postincrement for transform_iterator is implemented as a free
107 // function, which pyroot doesn't see. This causes python iteration
108 // over ElementLinkVector to fail.
109 template <class Iterator>
111 : public boost::transform_iterator<Short2LongRef, Iterator>
112 {
113 public:
114 typedef boost::transform_iterator<Short2LongRef, Iterator> Base;
115 using Base::Base;
116 ELVIterator (const Base& b) : Base (b) {}
117 using Base::operator++;
118 using Base::operator--;
119 ELVIterator operator++(int) { ELVIterator tmp=*this; ++(*this); return tmp; }
120 ELVIterator operator--(int) { ELVIterator tmp=*this; --(*this); return tmp; }
121 };
122
124
126 //FIXME typedef const ElemLink& const_reference;
128 typedef ELVIterator<typename RefVector::iterator> iterator;
129 typedef ELVIterator<typename RefVector::const_iterator> const_iterator;
130 //1.30 typedef typename boost::transform_iterator_generator<Short2LongRef, typename RefVector::iterator>::type iterator;
131 //1.30 typedef typename boost::transform_iterator_generator<Short2LongRef, typename RefVector::const_iterator>::type const_iterator;
132 typedef typename RefVector::size_type size_type;
133 typedef typename RefVector::difference_type difference_type;
135 typedef typename RefVector::allocator_type allocator_type;
137 typedef const ElemLink* const_pointer;
138 typedef ELVIterator<typename RefVector::reverse_iterator> reverse_iterator;
139 typedef ELVIterator<typename RefVector::const_reverse_iterator> const_reverse_iterator;
140 //1.30 typedef typename boost::transform_iterator_generator<Short2LongRef, typename RefVector::reverse_iterator>::type reverse_iterator;
141 //1.30 typedef typename boost::transform_iterator_generator<Short2LongRef, typename RefVector::const_reverse_iterator>::type const_reverse_iterator;
143
144
147
148
152
154 return m_shortRefs[index].elementIndex();
155 }
156
158 return m_shortRefs[index].dataID();
159 }
160
162
164
165 const DataLinkVector& hostDObjs() const { return m_hostDObjs; }
166 typename DataLinkVector::iterator beginHostDObjs() {
167 return m_hostDObjs.begin();
168 }
169 typename DataLinkVector::iterator endHostDObjs() {
170 return m_hostDObjs.end();
171 }
172 typename DataLinkVector::const_iterator beginHostDObjs() const {
173 return m_hostDObjs.begin();
174 }
175 typename DataLinkVector::const_iterator endHostDObjs() const {
176 return m_hostDObjs.end();
177 }
178
179 typename DataLinkVector::const_iterator findHostDObj(const ElemLink& link) const;
181 typename DataLinkVector::iterator findHostDObj(const ElemLink& link);
182
183 // Set the vector of host data objects from @a dobjs.
184 // @a dobjs is destroyed.
185 // This is an error if the vector is not empty.
187
189
190
192
194
197 {
198 if (n > 0)
199 addHostDObj(link);
200 }
201
202 ElementLinkVector(int n, const ElemLink& link = ElemLink()) :
204 {
205 if (n > 0)
206 addHostDObj(link);
207 }
208
209 ElementLinkVector(long n, const ElemLink& link = ElemLink()) :
211 {
212 if (n > 0)
213 addHostDObj(link);
214 }
215
218
222
224 ElementLinkVectorBase( std::move(vec) ),
225 m_shortRefs(std::move(vec.m_shortRefs)),
226 m_hostDObjs(std::move(vec.m_hostDObjs)) { }
227
229 {
230 if (this != &vec) {
231 m_persKeys = vec.m_persKeys;
232 m_persIndices = vec.m_persIndices;
233 m_shortRefs = vec.m_shortRefs;
234 m_hostDObjs = vec.m_hostDObjs;
235 }
236 return *this;
237 }
238
240 {
241 if (this != &vec) {
242 m_persKeys = std::move(vec.m_persKeys);
243 m_persIndices = std::move(vec.m_persIndices);
244 m_shortRefs = std::move(vec.m_shortRefs);
245 m_hostDObjs = std::move(vec.m_hostDObjs);
246 }
247 return *this;
248 }
249
250 template <class InputIterator>
251 void assign(InputIterator first, InputIterator last) {
252 clear();
253 insert(begin(), first, last);
254 }
255 void assign(size_type n, const ElemLink& link) {
256 clear();
257 insert(begin(), n, link);
258 }
259
261
262 // Also return list of shortrefs.
263 bool toPersistent(std::vector<typename DataLinkVector::size_type>& shortrefs);
264
265 // Just the DataLink part of toPersistent().
268 void doRemap();
270
272
273
274 iterator begin() { return iterator(m_shortRefs.begin(), Short2LongRef()); }
276 return const_iterator(m_shortRefs.begin(), Short2LongRef());
277 }
278 iterator end() { return iterator(m_shortRefs.end(), Short2LongRef()); }
280 return const_iterator(m_shortRefs.end(), Short2LongRef());
281 }
282 reverse_iterator rbegin() { return reverse_iterator(m_shortRefs.begin(), Short2LongRef()); }
284 return const_reverse_iterator(m_shortRefs.begin(), Short2LongRef());
285 }
286 reverse_iterator rend() { return reverse_iterator(m_shortRefs.end(), Short2LongRef()); }
288 return const_reverse_iterator(m_shortRefs.end(), Short2LongRef());
289 }
290
291
293
294 size_type size() const { return m_shortRefs.size(); }
295 size_type max_size() const { return m_shortRefs.max_size(); }
296 void resize(size_type sz, const ElemLink& link = ElemLink());
297 size_type capacity() const { return m_shortRefs.capacity(); }
298 bool empty() const { return 0 == size(); }
299 void reserve(size_type n) { return m_shortRefs.reserve(n); }
301
303
304 // reference operator[](size_type n);
306 operator[](size_type n) const { return m_shortRefs[n].elementLink(); }
307 // reference at(size_type n);
309 at(size_type n) const { return m_shortRefs.at(n).elementLink(); }
310 // reference front();
311 const_reference front() const{ return m_shortRefs.front().elementLink(); }
312 // reference back();
313 const_reference back() const{ return m_shortRefs.back().elementLink(); }
315
317
318 void push_back(const ElemLink& link) {
319 addHostDObj(link);
320 m_shortRefs.push_back(ElemLinkRef(link));
321 }
322 void pop_back() { //FIXME CHECK
324 m_shortRefs.pop_back();
325 }
326
327 // Add an element by indices.
328 // (Mostly for use from persistency.)
329 void push_back (typename DataLinkVector::size_type nameIndex,
331
332 iterator insert(iterator position, const ElemLink& link);
333 void insert(iterator position, size_type n, const ElemLink& link);
334
337
339 m_hostDObjs.swap(vec.m_hostDObjs);
340 m_shortRefs.swap(vec.m_shortRefs);
341 }
342
343 void clear() {
344 m_hostDObjs.clear();
345 m_shortRefs.clear();
346 }
347
348
349private:
351 void toTransient( uint64_t& dummy );
352 void toTransient( uint32_t& dummy );
354 template< typename INDEX_TYPE >
355 void toTransient( INDEX_TYPE& dummy );
356
359#ifdef __ELVDEBUG
360 link
361#endif
362 ) {
363#ifdef __ELVDEBUG
364 std::cout << "DUMMY removeHostDObj called for link "
365 << link.dataID() << "/" << link.index() << std::endl;
366#endif
367 //FIXME this is a dummy until we find how to remove an host w/o
368 //FIXME screwing up the otherElemLinkRefs
369 //FIXME m_hostDObjs.erase(findHostDObj(link));
370 }
371
373 void addHostDObj(const ElemLink& link);
374
376 typename RefVector::const_iterator
378 typename RefVector::const_iterator ret(m_shortRefs.begin());
379 advance(ret, distance(begin(), longIter));
380#ifdef __ELVDEBUG
381 std::cout << "shortIterFromLong(const version) called for "
382 << longIter->dataID() << "/" << longIter->index()
383 << " advance by " << distance(begin(), longIter)
384 << " result is " << ret->dataID() << "/" << ret->index() << std::endl;
385#endif
386 return ret;
387 }
388
390 typename RefVector::iterator
392 typename RefVector::iterator ret(m_shortRefs.begin());
393 advance(ret, distance(begin(), longIter));
394#ifdef __ELVDEBUG
395 std::cout << "shortIterFromLong called for "
396 << longIter->dataID() << "/" << longIter->index()
397 << " advance by " << distance(begin(), longIter)
398 << " result is " << ret->dataID() << "/" << ret->index() << std::endl;
399#endif
400 return ret;
401 }
402
404
405 template <class InputIterator>
406 ElementLinkVector(InputIterator first, InputIterator last);
407 template <class InputIterator>
408 void insert(iterator position, InputIterator first, InputIterator last);
410
412 friend bool operator == <>(const ElemLinkVec&, const ElemLinkVec&);
414 friend bool operator < <>(const ElemLinkVec&, const ElemLinkVec&);
415
417 typedef typename
419
420}; // class ElementLinkVector
421
422template <typename DOBJ>
425
426/*
427 * The following piece of code makes the Reflex dictionary think of
428 * "ElementLinkVector< T, DataProxyStorage< T >,
429 * SG::GenerateIndexingPolicy< T >::type >"
430 * simply as "ElementLinkVector< T >". This is vital for tricking
431 * ROOT into reading this object's payload back into a different
432 * ElementLink implementation in vanilla ROOT.
433 */
434namespace ROOT { namespace Meta { namespace Selection {
435
436template< class STORABLE >
437struct ElementLinkVector : public SelectNoInstance
438{
441 ROOT::Meta::Selection::MemberAttributes< kTransient > m_shortRefs;
442 ROOT::Meta::Selection::MemberAttributes< kTransient > m_hostDObjs;
443};
444
445}}} // ROOT namespace
446
447// Hide the rest from the dictionary generator:
448#ifndef __GCCXML__
449
450#include "AthLinks/ElementLinkVector.icc"
451#include "AthLinks/tools/SGELVRef.icc" /* to avoid circular deps */
452
454
455template <typename DOBJ>
456bool
458 const ElementLinkVector<DOBJ>& rhs) {
459 return (lhs.m_shortRefs < rhs.m_shortRefs);
460}
461template <typename DOBJ>
462bool
464 const ElementLinkVector<DOBJ>& rhs) {
465 return rhs < lhs;
466}
467template <typename DOBJ>
468bool
470 const ElementLinkVector<DOBJ>& rhs) {
471 return (lhs.m_shortRefs == rhs.m_shortRefs);
472}
473template <typename DOBJ>
474bool
476 const ElementLinkVector<DOBJ>& rhs) {
477 return !operator==(lhs, rhs);
478}
479//FIXME ops <= , => etc
481
482namespace std {
483template <typename DOBJ>
484void
487#ifdef __ELVDEBUG
488 std::cout << "std::swap called for lhs " << std::hex << &lhs
489 << " rhs " << &rhs << std::dec << std::endl;
490#endif
491 lhs.swap(rhs);
492}
493}
494
495#endif // not __GCCXML__
496#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:30
const ElemLink & elementLink() const
get the corresponding ElementLink. O(1)
Definition SGELVRef.h:59
ElemLink::index_type index_type
Definition SGELVRef.h:37
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