BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
Event/GeneratorObject/include/DataModel/ElementLinkVector.h
Go to the documentation of this file.
1#ifndef DATAMODEL_ELEMENTLINKVECTOR_H
2#define DATAMODEL_ELEMENTLINKVECTOR_H
3
4#ifndef DATAMODEL_DATALINK_H
5# include "DataModel/DataLink.h"
6#endif
7
8#ifndef DATAMODEL_ELEMENTLINK_H
9# include "DataModel/ElementLink.h"
10#endif
11
12#ifndef _CPP_ALGORITHM
13# include <algorithm>
14#endif
15#ifndef __EXCEPTION__
16# include <exception>
17#endif
18#ifndef _CPP_FUNCTIONAL
19# include <functional>
20#endif
21#ifndef _CPP_VECTOR
22# include <vector>
23#endif
24#ifndef BOOST_ITERATOR_ADAPTOR_DWA053000_HPP_
25# include <boost/iterator_adaptors.hpp>
26#endif
27
28/** @class ElementLinkVector
29 * @brief a vector of "compact" element links. It turns the host data object
30 * key into an index. The memory size of a compact link is three
31 * words/link, and only 2 words/link needs to be persistified.
32 * It also mantains a vector of hosts used to generate the "short ref"
33 *
34 * @param DOBJ host object type (e,g. vector<Elem>, NOT Elem),
35 * All host data objects must have the same type.
36 * @param StoragePolicy DOBJ management policy (defaults to DataProxyStorage)
37 * @param IndexingPolicy policy to find the element in the host DOBJ \n
38 * IndexingPolicy is generated automatically for STL sequences
39 * (e.g. vector, DataList etc). For other types of containers
40 * (e.g. maps), the container author must define the container type
41 * using the macros in tools/DeclareIndexingPolicies.h \n
42 * Advanced developers may have to define an ad-hoc indexing policy
43 * (e.g. GenParticleIndexing in GeneratorObjects/McEventIndexingPolicy.h)
44 *
45 * @author ATLAS Collaboration
46 * $Id: ElementLinkVector.h,v 1.3 2003/10/20 08:18:58 srini Exp $
47 **/
48
49template <typename DOBJ, class StoragePolicy = DataProxyStorage<DOBJ>,
50 class IndexingPolicy = typename SG::GenerateIndexingPolicy<DOBJ>::type>
52private:
53 typedef typename std::vector<DataLink<DOBJ, StoragePolicy>> DataLinkVector;
56
57 /** @class ElemLinkRef
58 * @brief a short ref to an ElementLink into an ElementLinkVector
59 */
60 class ElemLinkRef : public IndexingPolicy {
61 public:
63 typedef typename ElemLinkVec::ElemLink ElemLink;
64 typedef typename ElemLink::ElementPointer ElementPointer;
66 typedef typename ElemLink::index_type index_type;
67 typedef typename ElemLink::ID_type ID_type;
68
69 /// STL required
70 ElemLinkRef( const ElemLinkRef& rhs );
71 /// STL required
72 ElemLinkRef& operator=( const ElemLinkRef& rhs );
73 /// standard constructor
74 /// @throws invalid_argument when link not found in ElemLinkVector
75 ElemLinkRef( const ElemLinkVec& linkVect, const ElemLink& link = ElemLink() );
76 /// index into the host
77 using IndexingPolicy::index;
78 /// dataID of the host
79 ID_type dataID() const;
80 /// element pointer in ElementLink
81 ElementConstPointer cptr() const { return m_ptr; }
82 /// index of an element dobj in its ElementLinkVector host dobjs list
83 typename DataLinkVector::size_type shortRef() const { return m_shortRef; }
84
85 /// get the corresponding ElementLink. O(1)
86 ElemLink elementLink() const { return ElemLink( dataID(), index(), m_ptr ); }
87
88 /// \name comparison ops (STL required)
89 //@{
90 bool operator==( const ElemLinkRef& rhs ) const {
91 return ( ( index() == rhs.index() ) && ( dataID() == rhs.dataID() ) );
92 }
93 bool operator<( const ElemLinkRef& rhs ) const {
94 return ( ( index() < rhs.index() ) ||
95 ( ( index() == rhs.index() ) && ( dataID() < rhs.dataID() ) ) );
96 }
97 //@}
98 private:
99 ElemLinkVec & m_linkVect; ///! our owner
100 ElementPointer m_ptr; ///! the element pointer
101 typename DataLinkVector::size_type m_shortRef; ///! index of the host dobj
102 };
103
104 /** @class Short2LongRef
105 * @brief a functor turning an ElemLinkRef into an ElementLink
106 */
107 struct Short2LongRef : public std::unary_function<ElemLinkRef, ElemLink> {
108 ElemLink operator()( const ElemLinkRef& shortRef ) const { return shortRef.elementLink(); }
109 };
110
111 /// the element links stored as ElemLinkRefs for compactness
112 typedef typename std::vector<ElemLinkRef> RefVector;
113 RefVector m_shortRefs;
114
115 /// the dobjs hosting our elements. They are all of type DOBJ
116 DataLinkVector m_hostDObjs;
117
118public:
121 typedef typename ElemLink::ID_type ID_type;
122
123 ///\name vector typedefs: it behaves like a vector<ElemLink>
124 //@{
125 typedef ElemLink& reference;
126 // FIXME typedef const ElemLink& const_reference;
127 typedef ElemLink const_reference;
128 typedef typename boost::transform_iterator_generator<
129 Short2LongRef, typename RefVector::iterator>::type iterator;
130 typedef typename boost::transform_iterator_generator<
131 Short2LongRef, typename RefVector::const_iterator>::type const_iterator;
132 typedef typename RefVector::size_type size_type;
133 typedef typename RefVector::difference_type difference_type;
134 typedef ElemLink value_type;
135 typedef typename RefVector::allocator_type allocator_type;
136 typedef ElemLink* pointer;
137 typedef const ElemLink* const_pointer;
138 typedef typename boost::transform_iterator_generator<
139 Short2LongRef, typename RefVector::reverse_iterator>::type reverse_iterator;
140 typedef typename boost::transform_iterator_generator<
141 Short2LongRef, typename RefVector::const_reverse_iterator>::type const_reverse_iterator;
142 //@}
143
144 /// \name recommended (fast) access to contents of ElemLinks
145 /// by-pass the expensive creation of ElemLinks
146 //@{
147 /// pointer to an element, given its ElementLinkVector index. O(1)
149 return m_shortRefs[index].cptr();
150 }
151 /// host index of an element, given its ElementLinkVector index. O(1)
152 index_type elementIndex( size_type index ) const { return m_shortRefs[index].index(); }
153 /// dataID (long ref) of an element, given its ElementLinkVector index. O(1)
154 ID_type elementDataID( size_type index ) const { return m_shortRefs[index].dataID(); }
155
156 /// index of an element dobj in its ElementLinkVector host dobjs list . O(1)
157 typename DataLinkVector::size_type elementShortRef( size_type index ) const {
158 return m_shortRefs[index].shortRef();
159 }
160 //@}
161
162 /// \name iterators to DataLinkVector of host dobjs. Use e.g. for persistency
163 //@{
164 typename DataLinkVector::iterator beginHostDObjs() { return m_hostDObjs.begin(); }
165 typename DataLinkVector::iterator endHostDObjs() { return m_hostDObjs.end(); }
166 typename DataLinkVector::const_iterator beginHostDObjs() const {
167 return m_hostDObjs.begin();
168 }
169 typename DataLinkVector::const_iterator endHostDObjs() const { return m_hostDObjs.end(); }
170 /// find the host of an element. Returns endHostDObjs() if not found
171 typename DataLinkVector::const_iterator findHostDObj( const ElemLink& link ) const;
172 /// find the host of an element. Returns endHostDObjs() if not found
173 typename DataLinkVector::iterator findHostDObj( const ElemLink& link );
174
175 //@}
176
177 /// \name vector structors (no Allocators)
178 //@{
180
181 ElementLinkVector( size_type n, const ElemLink& link = ElemLink() )
182 : m_shortRefs( n, ElemLinkRef( *this, link ) ) {
183 addHostDObj( link );
184 }
185
186 ElementLinkVector( int n, const ElemLink& link = ElemLink() )
187 : m_shortRefs( n, ElemLinkRef( *this, link ) ) {
188 addHostDObj( link );
189 }
190
191 ElementLinkVector( long n, const ElemLink& link = ElemLink() )
192 : m_shortRefs( n, ElemLinkRef( *this, link ) ) {
193 addHostDObj( link );
194 }
195
196 explicit ElementLinkVector( size_type n ) : m_shortRefs( n, ElemLinkRef( *this ) ) {}
197
198 ElementLinkVector( const ElemLinkVec& vec )
199 : m_shortRefs( vec.m_shortRefs ), m_hostDObjs( vec.m_hostDObjs ) {}
200
201 template <class InputIterator> void assign( InputIterator first, InputIterator last ) {
202 clear();
203 insert( begin(), first, last );
204 }
205 void assign( size_type n, const ElemLink& link ) {
206 clear();
207 insert( begin(), n, link );
208 }
209 //@}
210
211 /// \name vector iterators
212 //@{
213
214 iterator begin() { return iterator( m_shortRefs.begin(), Short2LongRef() ); }
216 return const_iterator( m_shortRefs.begin(), Short2LongRef() );
217 }
218 iterator end() { return iterator( m_shortRefs.end(), Short2LongRef() ); }
219 const_iterator end() const { return const_iterator( m_shortRefs.end(), Short2LongRef() ); }
221 return reverse_iterator( m_shortRefs.begin(), Short2LongRef() );
222 }
224 return const_reverse_iterator( m_shortRefs.begin(), Short2LongRef() );
225 }
226 reverse_iterator rend() { return reverse_iterator( m_shortRefs.end(), Short2LongRef() ); }
228 return const_reverse_iterator( m_shortRefs.end(), Short2LongRef() );
229 }
230 //@}
231
232 /// \name vector capacity
233 //@{
234 size_type size() const { return m_shortRefs.size(); }
235 size_type max_size() const { return m_shortRefs.max_size(); }
236 void resize( size_type sz, ElemLink& link );
237 size_type capacity() const { return m_shortRefs.capacity(); }
238 bool empty() const { return 0 == size(); }
239 void reserve( size_type n ) { return m_shortRefs.reserve( n ); }
240 //@}
241
242 /// \name vector element accessors. NB only CONST accessors
243 //@{
244 // reference operator[](size_type n);
245 const_reference operator[]( size_type n ) const { return m_shortRefs[n].elementLink(); }
246 // reference at(size_type n);
247 const_reference at( size_type n ) const { return m_shortRefs.at( n ).elementLink(); }
248 // reference front();
249 const_reference front() const { return m_shortRefs.front().elementLink(); }
250 // reference back();
251 const_reference back() const { return m_shortRefs.back().elementLink(); }
252 //@}
253
254 /// \name vector Modifiers
255 //@{
256 void push_back( const ElemLink& link ) {
257 addHostObj( link );
258 m_shortRefs.push_back( ElemLinkRef( *this, link ) );
259 }
260 void pop_back() { // FIXME CHECK
261 removeHostObj( back() );
262 m_shortRefs.pop_back();
263 }
264
265 iterator insert( iterator position, const ElemLink& link );
266 void insert( iterator position, size_type n, const ElemLink& link );
267
270
271 void swap( ElemLinkVec& vec ) {
272 m_hostDObjs.swap( vec.m_hostDObjs );
273 m_shortRefs.swap( vec.m_shortRefs );
274 }
275
276 void clear() {
277 m_hostDObjs.clear();
278 m_shortRefs.clear();
279 }
280 //@}
281
282private:
283 /// remove host of link from list. O(N) in m_hostDObjs (which is small)
284 void removeHostObj( const ElemLink&
285#ifdef __ELVDEBUG
286 link
287#endif
288 ) {
289#ifdef __ELVDEBUG
290 std::cout << "DUMMY removeHostDObj called for link " << link.dataID() << "/"
291 << link.index() << std::endl;
292#endif
293 // FIXME this is a dummy until we find how to remove an host w/o
294 // FIXME screwing up the otherElemLinkRefs
295 // FIXME m_hostDObjs.erase(findHostDObj(link));
296 }
297
298 /// add host of link to list. No duplicates. O(N) in m_hostDObjs
299 void addHostObj( const ElemLink& link ) {
300 if ( endHostDObjs() == findHostDObj( link ) )
301 {
302 m_hostDObjs.push_back( DataLink<DOBJ, StoragePolicy>( link.dataID() ) );
303#ifdef __ELVDEBUG
304 std::cout << "addHostDObj added link " << link.dataID() << "/" << link.index()
305 << std::endl;
306#endif
307 }
308 }
309 /// get a short ref iterator from an iterator
310 typename RefVector::const_iterator shortIterFromLong( const_iterator longIter ) const {
311 typename RefVector::const_iterator ret( m_shortRefs.begin() );
312 advance( ret, distance( begin(), longIter ) );
313#ifdef __ELVDEBUG
314 std::cout << "shortIterFromLong(const version) called for " << longIter->dataID() << "/"
315 << longIter->index() << " advance by " << distance( begin(), longIter )
316 << " result is " << ret->dataID() << "/" << ret->index() << std::endl;
317#endif
318 return ret;
319 }
320
321 /// get a short ref iterator from an iterator
322 typename RefVector::iterator shortIterFromLong( iterator longIter ) {
323 typename RefVector::iterator ret( m_shortRefs.begin() );
324 advance( ret, distance( begin(), longIter ) );
325#ifdef __ELVDEBUG
326 std::cout << "shortIterFromLong called for " << longIter->dataID() << "/"
327 << longIter->index() << " advance by " << distance( begin(), longIter )
328 << " result is " << ret->dataID() << "/" << ret->index() << std::endl;
329#endif
330 return ret;
331 }
332
333 /// \name FIXME don't know how to implement
334 //@{
335 template <class InputIterator> ElementLinkVector( InputIterator first, InputIterator last );
336 template <class InputIterator>
337 void insert( iterator position, InputIterator first, InputIterator last );
338 //@}
339
340 /// access m_shortRefs
341 friend bool operator== <>( const ElemLinkVec&, const ElemLinkVec& );
342 /// access m_shortRefs
343 friend bool operator< <>( const ElemLinkVec&, const ElemLinkVec& );
344};
345
346#ifndef STOREGATE_ELEMENTLINKVECTOR_HH
347# include "DataModel/ElementLinkVector.icc"
348#endif
349
350/// \name vector comparison operators
351//@{
352template <typename DOBJ, class StoragePolicy, class IndexingPolicy>
355 return ( lhs.m_shortRefs < rhs.m_shortRefs );
356}
357template <typename DOBJ, class StoragePolicy, class IndexingPolicy>
362template <typename DOBJ, class StoragePolicy, class IndexingPolicy>
365 return ( lhs.m_shortRefs == rhs.m_shortRefs );
366}
367template <typename DOBJ, class StoragePolicy, class IndexingPolicy>
372// FIXME ops <= , => etc
373//@}
374
375/// specialized swap algorithm
376template <typename DOBJ, class StoragePolicy, class IndexingPolicy>
379#ifdef __ELVDEBUG
380 std::cout << "std::swap called for lhs " << std::hex << &lhs << " rhs " << &rhs << std::dec
381 << std::endl;
382#endif
383 lhs.swap( rhs );
384}
385#endif /*ELEMENTLINKVECTOR_H*/
dble_vec_t vec[12]
const Int_t n
bool operator>(const ElementLinkVector< DOBJ, StoragePolicy, IndexingPolicy > &lhs, const ElementLinkVector< DOBJ, StoragePolicy, IndexingPolicy > &rhs)
bool operator==(const ElementLinkVector< DOBJ, StoragePolicy, IndexingPolicy > &lhs, const ElementLinkVector< DOBJ, StoragePolicy, IndexingPolicy > &rhs)
bool operator!=(const ElementLinkVector< DOBJ, StoragePolicy, IndexingPolicy > &lhs, const ElementLinkVector< DOBJ, StoragePolicy, IndexingPolicy > &rhs)
bool operator<(const ElementLinkVector< DOBJ, StoragePolicy, IndexingPolicy > &lhs, const ElementLinkVector< DOBJ, StoragePolicy, IndexingPolicy > &rhs)
a vector of "compact" element links. It turns the host data object key into an index....
iterator erase(iterator position)
boost::transform_iterator_generator< Short2LongRef, typenameRefVector::const_iterator >::type const_iterator
iterator insert(iterator position, const ElemLink &link)
DataLinkVector::const_iterator findHostDObj(const ElemLink &link) const
find the host of an element. Returns endHostDObjs() if not found
boost::transform_iterator_generator< Short2LongRef, typenameRefVector::reverse_iterator >::type reverse_iterator
boost::transform_iterator_generator< Short2LongRef, typenameRefVector::iterator >::type iterator
void insert(iterator position, size_type n, const ElemLink &link)
ElementLinkVector(int n, const ElemLink &link=ElemLink())
DataLinkVector::iterator findHostDObj(const ElemLink &link)
find the host of an element. Returns endHostDObjs() if not found
ID_type elementDataID(size_type index) const
dataID (long ref) of an element, given its ElementLinkVector index. O(1)
ElementLinkVector(long n, const ElemLink &link=ElemLink())
friend bool operator<(const ElemLinkVec &, const ElemLinkVec &)
access m_shortRefs
DataLinkVector::size_type elementShortRef(size_type index) const
index of an element dobj in its ElementLinkVector host dobjs list . O(1)
boost::transform_iterator_generator< Short2LongRef, typenameRefVector::const_reverse_iterator >::type const_reverse_iterator
iterator erase(iterator first, iterator last)
void assign(InputIterator first, InputIterator last)
friend bool operator==(const ElemLinkVec &, const ElemLinkVec &)
access m_shortRefs
ElementLinkVector(size_type n, const ElemLink &link=ElemLink())
void resize(size_type sz, ElemLink &link)
DataLinkVector::const_iterator beginHostDObjs() const
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)