CMS 3D CMS Logo

RefVector.h
Go to the documentation of this file.
1 #ifndef DataFormats_Common_RefVector_h
2 #define DataFormats_Common_RefVector_h
3 
4 /*----------------------------------------------------------------------
5 
6 RefVector: A template for a vector of interproduct references.
7  Each vector element is a reference to a member of the same product.
8 
9 ----------------------------------------------------------------------*/
10 
22 
23 #include <algorithm>
24 #include <stdexcept>
25 #include <vector>
26 
27 namespace edm {
28 
29  template<typename C,
30  typename T = typename refhelper::ValueTrait<C>::value,
31  typename F = typename refhelper::FindTrait<C, T>::value>
32  class RefVector {
33  public:
34  typedef C collection_type;
35  typedef T member_type;
36  typedef F finder_type;
38  typedef iterator const_iterator;
40  typedef value_type const const_reference; // better this than the default 'const value_type &'
41  typedef const_reference reference; // as operator[] returns 'const R' and not 'R &'
42 
43  // key_type is the type of the key into the collection
44  typedef typename value_type::key_type key_type;
45  typedef std::vector<key_type> KeyVec;
46 
47  // size_type is the type of the index into the RefVector
48  typedef typename KeyVec::size_type size_type;
50 
54  ~RefVector() = default;
55 
58 
59  RefVector& operator=(RefVector const& rhs);
61  refVector_ = std::move(rhs.refVector_);
62  return *this;
63  }
64 
65 
66 
67  RefVector(ProductID const& iId) : refVector_(iId) {}
69  void push_back(value_type const& ref) {
70  refVector_.pushBack(ref.refCore(), ref.key());
71  }
72 
73 
75  value_type const operator[](size_type idx) const {
76  RefCore const& core = refVector_.refCore();
77  key_type const& key = refVector_.keys()[idx];
78  void const* memberPointer = refVector_.cachedMemberPointer(idx);
79  if(memberPointer) {
80  RefCore newCore(core);
81  newCore.setProductPtr(memberPointer);
82  return value_type(newCore, key);
83  }
84  return value_type(core, key);
85  }
86 
88  value_type const at(size_type idx) const {
89  RefCore const& core = refVector_.refCore();
90  key_type const& key = refVector_.keys().at(idx);
91  void const* memberPointer = refVector_.cachedMemberPointer(idx);
92  if(memberPointer) {
93  RefCore newCore(core);
94  newCore.setProductPtr(memberPointer);
95  return value_type(newCore, key);
96  }
97  return value_type(core, key);
98  }
99 
101  contents_type const& refVector() const {return refVector_;}
102 
104  bool empty() const {return refVector_.empty();}
105 
107  size_type size() const {return refVector_.size();}
108 
110  size_type capacity() const {return refVector_.capacity();}
111 
113  void reserve(size_type n) {refVector_.reserve(n);}
114 
116  const_iterator begin() const;
117 
119  const_iterator end() const;
120 
122  ProductID id() const {return refVector_.refCore().id();}
123 
126 
128  bool isNull() const {return !id().isValid();}
129 
131  bool isNonnull() const {return !isNull();}
132 
134  bool operator!() const {return isNull();}
135 
138  bool isAvailable() const;
139 
141  bool isTransient() const {return refVector_.refCore().isTransient();}
142 
144  iterator erase(iterator const& pos);
145 
147  void clear() {refVector_.clear();}
148 
151 
153  bool hasProductCache() const {return refVector_.refCore().productPtr() != 0;}
154 
155  void fillView(ProductID const& id,
156  std::vector<void const*>& pointers,
158 
159  //Needed for ROOT storage
161 
162  private:
163 
164  contents_type refVector_;
165  };
166 
167  template<typename C, typename T, typename F>
168  inline
169  void
170  RefVector<C, T, F>::swap(RefVector<C, T, F> & other) noexcept {
171  refVector_.swap(other.refVector_);
172  }
173 
174  template<typename C, typename T, typename F>
175  inline
179  this->swap(temp);
180  return *this;
181  }
182 
183  template<typename C, typename T, typename F>
184  inline
185  void
187  a.swap(b);
188  }
189 
190  template<typename C, typename T, typename F>
191  void
193  std::vector<void const*>& pointers,
194  FillViewHelperVector& helpers) const {
195 
196  pointers.reserve(this->size());
197  helpers.reserve(this->size());
198 
199  size_type key = 0;
200  for(const_iterator i=begin(), e=end(); i!=e; ++i, ++key) {
201  member_type const* address = i->isNull() ? 0 : &**i;
202  pointers.push_back(address);
203  helpers.emplace_back(i->id(),i->key());
204  }
205  }
206 
207  template<typename C, typename T, typename F>
208  inline
209  void
211  ProductID const& id,
212  std::vector<void const*>& pointers,
213  FillViewHelperVector& helpers) {
214  obj.fillView(id, pointers, helpers);
215  }
216 
217  template<typename C, typename T, typename F>
218  struct has_fillView<RefVector<C,T,F> > {
219  static bool const value = true;
220  };
221 
222  template<typename C, typename T, typename F>
223  inline
224  bool
226  return lhs.refVector() == rhs.refVector();
227  }
228 
229  template<typename C, typename T, typename F>
230  inline
231  bool
233  return !(lhs == rhs);
234  }
235 
236  template<typename C, typename T, typename F>
237  inline
239  RefVector<C, T, F>::erase(iterator const& pos) {
241  typename contents_type::keys_type::iterator newPos =
242  refVector_.eraseAtIndex(index);
243  typename contents_type::keys_type::size_type newIndex = newPos - refVector_.keys().begin();
244  return iterator(this, newIndex);
245  }
246 
247  template<typename C, typename T, typename F>
249  return iterator(this, 0);
250  }
251 
252  template<typename C, typename T, typename F>
254  return iterator(this, size());
255  }
256 
257  template<typename C, typename T, typename F>
258  bool
260  if(refVector_.refCore().isAvailable()) {
261  return true;
262  } else if(empty()) {
263  return false;
264  }
265 
266  // The following is the simplest implementation, but
267  // this is woefully inefficient and could be optimized
268  // to run much faster with some nontrivial effort. There
269  // is only 1 place in the code base where this function
270  // is used at all and I'm not sure whether it will ever
271  // be used with thinned collections, so for the moment I
272  // am not spending the time to optimize this.
273  for(size_type i = 0; i < size(); ++i) {
274  if(!(*this)[i].isAvailable()) {
275  return false;
276  }
277  }
278  return true;
279  }
280 
281  template<typename C, typename T, typename F>
282  std::ostream&
283  operator<<(std::ostream& os, RefVector<C,T,F> const& r) {
285  i = r.begin(),
286  e = r.end();
287  i != e;
288  ++i) {
289  os << *i << '\n';
290  }
291  return os;
292  }
293 }
294 
296 namespace edm {
297  namespace detail {
298 
299  template<typename C, typename T, typename F>
300  struct GetProduct<RefVector<C, T, F> > {
301  typedef T element_type;
303  static element_type const* address(iter const& i) {
304  return &**i;
305  }
306  };
307  }
308 }
309 #endif
std::remove_cv< typename std::remove_reference< argument_type >::type >::type key_type
Definition: Ref.h:169
void const * cachedMemberPointer(size_type idx) const
Definition: RefVectorBase.h:67
bool isNonnull() const
Checks for non-null.
Definition: RefVector.h:131
size_type size() const
Size of vector.
Definition: RefVectorBase.h:78
void setProductPtr(void const *prodPtr) const
Definition: RefCore.h:58
~RefVector()=default
value_type const const_reference
Definition: RefVector.h:40
value_type::key_type key_type
Definition: RefVector.h:44
size_type capacity() const
Capacity of the RefVector.
Definition: RefVector.h:110
Definition: __init__.py:1
void swap(RefVectorBase< KEY > &other) noexcept
swap two vectors
#define noexcept
RefCore const & refCore() const
Definition: Ref.h:280
const_reference reference
Definition: RefVector.h:41
key_type key() const
Accessor for product key.
Definition: Ref.h:265
void clear()
clear the vector
contents_type refVector_
Definition: RefVector.h:164
#define CMS_CLASS_VERSION(_version_)
Definition: classes.h:31
const_iterator end() const
Termination of iteration.
Definition: RefVector.h:253
bool empty() const
Is the RefVector empty.
Definition: RefVector.h:104
uint16_t size_type
const_iterator begin() const
Initialize an iterator over the RefVector.
Definition: RefVector.h:248
KeyVec::size_type size_type
Definition: RefVector.h:48
RefCore const & refCore() const
Accessor for product ID and product getter.
Definition: RefVectorBase.h:65
bool isNull() const
Checks for null.
Definition: RefVector.h:128
void fillView(ProductID const &id, std::vector< void const * > &pointers, FillViewHelperVector &helpers) const
Definition: RefVector.h:192
bool operator==(debugging_allocator< X > const &, debugging_allocator< Y > const &) noexcept
bool empty() const
Is vector empty?
Definition: RefVectorBase.h:75
ProductID id() const
Accessor for product ID.
Definition: RefVector.h:122
RefVector(ProductID const &iId)
Definition: RefVector.h:67
std::vector< key_type > KeyVec
Definition: RefVector.h:45
bool isTransient() const
Checks if product collection is tansient (i.e. non persistable)
Definition: RefVector.h:141
void const * productPtr() const
Definition: RefCore.h:52
bool isAvailable() const
Definition: RefCore.cc:169
refhelper::RefVectorTrait< C, T, F >::iterator_type iterator
Definition: RefVector.h:37
keys_type::size_type size_type
Definition: RefVectorBase.h:34
void swap(RefVector< C, T, F > &other)
Swap two vectors.
Definition: RefVector.h:170
def template(fileName, svg, replaceme="REPLACEME")
Definition: svgfig.py:520
RefVector(RefVector const &rh)
Definition: RefVector.h:56
Definition: value.py:1
void reserve(size_type n)
Reserve space for RefVector.
Definition: RefVector.h:113
EDProductGetter const * productGetter() const
Accessor for product getter.
Definition: RefVector.h:125
bool operator!=(debugging_allocator< X > const &, debugging_allocator< Y > const &) noexcept
iterator const_iterator
Definition: RefVector.h:38
RefVectorBase< key_type > contents_type
Definition: RefVector.h:49
void pushBack(RefCore const &product, KEY const &key)
Definition: RefVectorBase.h:80
RefVector & operator=(RefVector &&rhs)
Definition: RefVector.h:60
void clear()
Clear the vector.
Definition: RefVector.h:147
bool hasProductCache() const
Checks if product is in memory.
Definition: RefVector.h:153
RefVector< C, T, F >::const_iterator iter
Definition: RefVector.h:302
double b
Definition: hdecay.h:120
EDProductGetter const * productGetter() const
Definition: RefCore.h:84
ProductID id() const
Definition: RefCore.h:49
value_type const operator[](size_type idx) const
Retrieve an element of the RefVector.
Definition: RefVector.h:75
bool isTransient() const
Definition: RefCore.h:106
value_type const at(size_type idx) const
Retrieve an element of the RefVector.
Definition: RefVector.h:88
HLT enums.
bool isAvailable() const
Definition: RefVector.h:259
double a
Definition: hdecay.h:121
static element_type const * address(iter const &i)
Definition: RefVector.h:303
keys_type const & keys() const
Accessor for vector of keys and pointers.
Definition: RefVectorBase.h:72
void push_back(value_type const &ref)
Add a Ref<C, T> to the RefVector.
Definition: RefVector.h:69
size_type size() const
Size of the RefVector.
Definition: RefVector.h:107
FindUsingAdvance< C, T > value
Definition: RefTraits.h:41
keys_type::iterator eraseAtIndex(size_type index)
erase an element from the vector
void reserve(size_type n)
Reserve space for vector.
refhelper::RefVectorTrait< C, T, F >::ref_type value_type
Definition: RefVector.h:39
RefVector & operator=(RefVector const &rhs)
bool isValid() const
Definition: ProductID.h:35
contents_type const & refVector() const
Accessor for all data.
Definition: RefVector.h:101
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:281
long double T
size_type capacity() const
Capacity of vector.
Definition: RefVectorBase.h:98
std::vector< std::pair< edm::ProductID, unsigned long > > FillViewHelperVector
bool operator!() const
Checks for null.
Definition: RefVector.h:134
edm::RefVector< Container > RefVector
def move(src, dest)
Definition: eostools.py:510
RefVector(RefVector &&rh)
Definition: RefVector.h:57
iterator erase(iterator const &pos)
Erase an element from the vector.
Definition: RefVector.h:239