LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
PtrVector.h
Go to the documentation of this file.
1 #ifndef canvas_Persistency_Common_PtrVector_h
2 #define canvas_Persistency_Common_PtrVector_h
3 
4 // ======================================================================
5 //
6 // PtrVector: a container which returns art::Ptr<>'s referring to items
7 // in one container in the art::Event
8 //
9 // ======================================================================
10 
13 #include "cetlib/container_algorithms.h"
14 
15 #include <initializer_list>
16 #include <iterator>
17 #include <vector>
18 
19 namespace art {
20  template <typename T>
21  class PtrVector;
22 
23  template <typename T>
24  void swap(PtrVector<T>&, PtrVector<T>&);
25 
26  template <typename Comp>
27  class ComparePtrs {
28  public:
29  ComparePtrs(Comp const comp) : comp_{comp} {}
30  template <typename T>
31  bool
32  operator()(Ptr<T> const& a, Ptr<T> const& b)
33  {
34  return comp_(*a, *b);
35  }
36 
37  private:
38  Comp comp_;
39  };
40 }
41 
42 template <typename T>
43 class art::PtrVector : public PtrVectorBase {
44 private:
45  using data_t = std::vector<Ptr<T>>;
46 
47 public:
48  using value_type = typename data_t::value_type;
49  using allocator_type = typename data_t::allocator_type;
50  using reference = typename data_t::reference;
51  using const_reference = typename data_t::const_reference;
52  using pointer = typename data_t::pointer;
53  using const_pointer = typename data_t::const_pointer;
54  using iterator = typename data_t::iterator;
56  using reverse_iterator = typename data_t::reverse_iterator;
57  using const_reverse_iterator = typename data_t::const_reverse_iterator;
58  using difference_type = typename data_t::difference_type;
59  using size_type = typename data_t::size_type;
60 
61  PtrVector();
62  template <typename U>
64 
65  template <typename U>
66  PtrVector(std::initializer_list<Ptr<U>> il);
67  template <typename U>
68  PtrVector<T>& operator=(std::initializer_list<Ptr<U>> il);
69 
70  template <typename U>
71  PtrVector<T>& operator=(PtrVector<U> const& other) &;
72 
73  // Iterators.
74  iterator begin();
75  const_iterator begin() const;
76  iterator end();
77  const_iterator end() const;
78  reverse_iterator rbegin();
79  const_reverse_iterator rbegin() const;
80  reverse_iterator rend();
81  const_reverse_iterator rend() const;
82 
83  const_iterator cbegin() const;
84  const_iterator cend() const;
85  const_reverse_iterator crbegin() const;
86  const_reverse_iterator crend() const;
87 
88  // Capacity.
89  size_type size() const;
90  size_type max_size() const;
91  void resize(size_type n);
92  size_type capacity() const;
93  bool empty() const;
94  void reserve(size_type n);
95  void shrink_to_fit();
96 
97  // Element access.
98  Ptr<T> const& operator[](unsigned long const idx) const;
99  reference at(size_type n);
100  const_reference at(size_type n) const;
101  reference front();
102  const_reference front() const;
103  reference back();
104  const_reference back() const;
105  // No data() functions by design.
106 
107  // Modifiers.
108  template <typename U>
109  void assign(size_type n, Ptr<U> const& p);
110  template <class InputIterator>
111  void assign(InputIterator first, InputIterator last);
112  template <typename U>
113  void assign(std::initializer_list<Ptr<U>> il);
114  template <typename U>
115  void push_back(Ptr<U> const& p);
116  template <typename... Args>
117  void emplace_back(Args&&... args);
118  void pop_back();
119  template <typename U>
120  iterator insert(iterator position, Ptr<U> const& p);
121  template <typename U>
122  void insert(iterator position, size_type n, Ptr<U> const& p);
123  template <typename InputIterator>
124  iterator insert(const_iterator position,
125  InputIterator first,
126  InputIterator last);
127  iterator erase(iterator position);
128  iterator erase(iterator first, iterator last);
129  void swap(PtrVector& other);
130  void swap(key_type k1, key_type k2);
131  void clear();
132  // No emplace() due to problems associated with checking for
133  // compatible ProductID.
134 
135  bool operator==(PtrVector const& other) const;
136  void sort();
137  template <class Comp>
138  void sort(Comp comp);
139  static short
141  {
142  return 11;
143  }
144 
145 private:
146  void fill_offsets(indices_t& indices) override;
147  void fill_from_offsets(indices_t const& indices) const override;
148  void zeroTransients() override;
149 
150  // Need to explicitly zero this from custom streamer for base class.
151  mutable data_t ptrs_{};
152 };
153 
154 #include <algorithm>
155 #include <functional>
156 #include <iterator>
157 #include <type_traits>
158 
159 // Constructors.
160 template <typename T>
161 inline art::PtrVector<T>::PtrVector() = default;
162 
163 template <typename T>
164 template <typename U>
166  : PtrVectorBase{other}
167 {
168  // Ensure that types are compatible.
169  static_assert(std::is_base_of_v<T, U> || std::is_base_of_v<U, T>,
170  "PtrVector: incompatible types");
171  ptrs_.reserve(other.size());
172  cet::copy_all(other, std::back_inserter(ptrs_));
173 }
174 
175 template <typename T>
176 template <typename U>
177 inline art::PtrVector<T>::PtrVector(std::initializer_list<Ptr<U>> const il)
178 {
179  static_assert(std::is_same_v<T, U> || std::is_base_of_v<T, U> ||
180  std::is_base_of_v<U, T>,
181  "PtrVector: incompatible types");
182  ptrs_.reserve(il.size());
183  for (auto&& p : il) {
184  updateCore(p.refCore());
185  ptrs_.push_back(std::move(p));
186  }
187 }
188 
189 template <typename T>
190 template <typename U>
191 inline art::PtrVector<T>&
192 art::PtrVector<T>::operator=(std::initializer_list<Ptr<U>> const il)
193 {
194  static_assert(std::is_same_v<T, U> || std::is_base_of_v<T, U> ||
195  std::is_base_of_v<U, T>,
196  "PtrVector: incompatible types");
197  assign(il);
198  return *this;
199 }
200 
201 template <typename T>
202 template <typename U>
203 inline art::PtrVector<T>&
205 {
206  static_assert(std::is_base_of_v<T, U> || std::is_base_of_v<U, T>,
207  "PtrVector: incompatible types");
208  PtrVectorBase::operator=(other);
209  ptrs_.clear();
210  cet::copy_all(other, std::back_inserter(ptrs_));
211  return *this;
212 }
213 
214 // Iterators.
215 template <typename T>
216 inline auto
218 {
219  return ptrs_.begin();
220 }
221 
222 template <typename T>
223 inline auto
225 {
226  return ptrs_.begin();
227 }
228 
229 template <typename T>
230 inline auto
232 {
233  return ptrs_.end();
234 }
235 
236 template <typename T>
237 inline auto
239 {
240  return ptrs_.end();
241 }
242 
243 template <typename T>
244 inline auto
246 {
247  return ptrs_.rbegin();
248 }
249 
250 template <typename T>
251 inline auto
253 {
254  return ptrs_.rbegin();
255 }
256 
257 template <typename T>
258 inline auto
260 {
261  return ptrs_.rend();
262 }
263 
264 template <typename T>
265 inline auto
267 {
268  return ptrs_.rend();
269 }
270 
271 template <typename T>
272 inline auto
274 {
275  return ptrs_.cbegin();
276 }
277 
278 template <typename T>
279 inline auto
281 {
282  return ptrs_.cend();
283 }
284 
285 template <typename T>
286 inline auto
288 {
289  return ptrs_.crbegin();
290 }
291 
292 template <typename T>
293 inline auto
295 {
296  return ptrs_.crend();
297 }
298 
299 // Capacity.
300 template <typename T>
301 inline auto
303 {
304  return ptrs_.size();
305 }
306 
307 template <typename T>
308 inline auto
310 {
311  return ptrs_.max_size();
312 }
313 
314 template <typename T>
315 inline void
317 {
318  ptrs_.resize(n);
319 }
320 
321 template <typename T>
322 inline auto
324 {
325  return ptrs_.capacity();
326 }
327 
328 template <typename T>
329 inline bool
331 {
332  return ptrs_.empty();
333 }
334 
335 template <typename T>
336 inline void
338 {
339  ptrs_.reserve(n);
340 }
341 
342 template <typename T>
343 inline void
345 {
346  ptrs_.shrink_to_fit();
347 }
348 
349 // Element access.
350 template <typename T>
351 inline art::Ptr<T> const&
352 art::PtrVector<T>::operator[](unsigned long const idx) const
353 {
354  return *(begin() + idx);
355 }
356 
357 template <typename T>
358 inline auto
360 {
361  return ptrs_.at(n);
362 }
363 
364 template <typename T>
365 inline auto
367 {
368  return ptrs_.at(n);
369 }
370 
371 template <typename T>
372 inline auto
374 {
375  return ptrs_.front();
376 }
377 
378 template <typename T>
379 inline auto
381 {
382  return ptrs_.front();
383 }
384 
385 template <typename T>
386 inline auto
388 {
389  return ptrs_.back();
390 }
391 
392 template <typename T>
393 inline auto
395 {
396  return ptrs_.back();
397 }
398 
399 // Modifiers.
400 template <typename T>
401 template <typename U>
402 inline void
404 {
405  static_assert(std::is_same_v<T, U> || std::is_base_of_v<T, U> ||
406  std::is_base_of_v<U, T>,
407  "PtrVector: incompatible types");
409  updateCore(p.refCore());
410  ptrs_.assign(n, p);
411 }
412 
413 template <typename T>
414 template <typename InputIterator>
415 inline void
416 art::PtrVector<T>::assign(InputIterator const first, InputIterator const last)
417 {
419  std::for_each(
420  first, last, [this](Ptr<T> const& p) { updateCore(p.refCore()); });
421  ptrs_.assign(first, last);
422 }
423 
424 template <typename T>
425 template <typename U>
426 inline void
427 art::PtrVector<T>::assign(std::initializer_list<Ptr<U>> const il)
428 {
429  assign(il.begin(), il.end());
430 }
431 
432 template <typename T>
433 template <typename U>
434 inline void
436 {
437  // Ensure that types are compatible.
438  static_assert(std::is_same_v<T, U> || std::is_base_of_v<T, U> ||
439  std::is_base_of_v<U, T>,
440  "PtrVector: incompatible types");
441  updateCore(p.refCore());
442  ptrs_.push_back(p);
443 }
444 
445 template <typename T>
446 template <typename... Args>
447 inline void
449 {
450  Ptr<T> p(std::forward<Args>(args)...);
451  updateCore(p.refCore());
452  ptrs_.push_back(std::move(p));
453 }
454 
455 template <typename T>
456 inline void
458 {
459  ptrs_.pop_back();
460 }
461 
462 template <typename T>
463 template <typename U>
464 inline typename art::PtrVector<T>::iterator
465 art::PtrVector<T>::insert(iterator const position, Ptr<U> const& p)
466 {
467  // Ensure that types are compatible.
468  static_assert(std::is_same_v<T, U> || std::is_base_of_v<T, U> ||
469  std::is_base_of_v<U, T>,
470  "PtrVector: incompatible types");
471  updateCore(p.refCore());
472  return ptrs_.insert(position, p);
473 }
474 
475 template <typename T>
476 template <typename U>
477 inline void
479  size_type const n,
480  Ptr<U> const& p)
481 {
482  // Ensure that types are compatible.
483  static_assert(std::is_same_v<T, U> || std::is_base_of_v<T, U> ||
484  std::is_base_of_v<U, T>,
485  "PtrVector: incompatible types");
486  updateCore(p.refCore());
487  ptrs_.insert(position, n, p);
488 }
489 
490 template <typename T>
491 template <typename InputIterator>
492 inline auto
494  InputIterator first,
495  InputIterator last) -> iterator
496 {
497  std::for_each(
498  first, last, [this](Ptr<T> const& p) { updateCore(p.refCore()); });
499  return ptrs_.insert(position, first, last);
500 }
501 
502 template <typename T>
503 inline auto
505 {
506  return ptrs_.erase(position);
507 }
508 
509 template <typename T>
510 inline auto
512 {
513  return ptrs_.erase(first, last);
514 }
515 
516 template <typename T>
517 inline void
519 {
520  ptrs_.swap(other.ptrs_);
521  PtrVectorBase::swap(other);
522 }
523 
524 template <typename T>
525 inline void
527 {
528  std::swap(ptrs_[k1], ptrs_[k2]);
529 }
530 
531 template <typename T>
532 inline void
534 {
535  ptrs_.clear();
537 }
538 
539 template <typename T>
540 inline bool
542 {
543  return ptrs_ == other.ptrs_ && PtrVectorBase::operator==(other);
544 }
545 
546 template <typename T>
547 inline void
549 {
550  sort(std::less<T>{});
551 }
552 
553 template <typename T>
554 template <class Comp>
555 inline void
556 art::PtrVector<T>::sort(Comp const comp)
557 {
558  cet::sort_all(ptrs_, ComparePtrs{comp});
559 }
560 
561 template <typename T>
562 void
564 {
565  // Precondition: indices is expected to be empty.
566  assert(indices.empty());
567  indices.reserve(ptrs_.size());
568  for (auto const& i : ptrs_) {
569  indices.push_back(i.key());
570  }
571 }
572 
573 template <typename T>
574 void
576 {
577  // Precondition: ptrs_ is expected to be empty.
578  assert(ptrs_.empty());
579  ptrs_.reserve(indices.size());
580  for (auto i : indices) {
581  ptrs_.emplace_back(id(), i, productGetter());
582  }
583 }
584 
585 template <typename T>
586 inline void
588 {
589  data_t tmp;
590  ptrs_.swap(tmp);
591 }
592 
593 template <typename T>
594 inline void
596 {
597  lhs.swap(rhs);
598 }
599 
600 #endif /* canvas_Persistency_Common_PtrVector_h */
601 
602 // Local Variables:
603 // mode: c++
604 // End:
void swap(PtrVectorBase &)
typename data_t::allocator_type allocator_type
Definition: PtrVector.h:49
intermediate_table::iterator iterator
void reserve(size_type n)
Definition: PtrVector.h:337
bool operator==(Provenance const &a, Provenance const &b) noexcept
Definition: Provenance.cc:141
void swap(PtrVector< T > &, PtrVector< T > &)
Definition: PtrVector.h:595
typename data_t::iterator iterator
Definition: PtrVector.h:54
size_type max_size() const
Definition: PtrVector.h:309
decltype(auto) constexpr cend(T &&obj)
ADL-aware version of std::cend.
Definition: StdUtils.h:93
typename data_t::difference_type difference_type
Definition: PtrVector.h:58
void shrink_to_fit()
Definition: PtrVector.h:344
PtrVector< T > & operator=(std::initializer_list< Ptr< U >> il)
typename data_t::const_reference const_reference
Definition: PtrVector.h:51
void swap(PtrVector &other)
Definition: PtrVector.h:518
iterator begin()
Definition: PtrVector.h:217
typename data_t::value_type value_type
Definition: PtrVector.h:48
unsigned long key_type
Definition: PtrVectorBase.h:21
void fill_offsets(indices_t &indices) override
Definition: PtrVector.h:563
bool operator==(PtrVectorBase const &) const noexcept
iterator erase(iterator position)
Definition: PtrVector.h:504
typename data_t::reverse_iterator reverse_iterator
Definition: PtrVector.h:56
const_reverse_iterator crbegin() const
Definition: PtrVector.h:287
void emplace_back(Args &&...args)
Definition: PtrVector.h:448
intermediate_table::const_iterator const_iterator
Float_t tmp
Definition: plot.C:35
reverse_iterator rbegin()
Definition: PtrVector.h:245
std::vector< Ptr< recob::EndPoint2D >> data_t
Definition: PtrVector.h:45
size_type capacity() const
Definition: PtrVector.h:323
static short Class_Version()
Definition: PtrVector.h:140
const_reverse_iterator crend() const
Definition: PtrVector.h:294
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:101
bool operator()(Ptr< T > const &a, Ptr< T > const &b)
Definition: PtrVector.h:32
std::vector< key_type > indices_t
Definition: PtrVectorBase.h:22
reference back()
Definition: PtrVector.h:387
ComparePtrs(Comp const comp)
Definition: PtrVector.h:29
void fill_from_offsets(indices_t const &indices) const override
Definition: PtrVector.h:575
typename data_t::const_iterator const_iterator
Definition: PtrVector.h:55
void push_back(Ptr< U > const &p)
Definition: PtrVector.h:435
void swap(Handle< T > &a, Handle< T > &b)
typename data_t::const_reverse_iterator const_reverse_iterator
Definition: PtrVector.h:57
constexpr std::array< std::size_t, geo::vect::dimension< Vector >)> indices()
Returns a sequence of indices valid for a vector of the specified type.
iterator end()
Definition: PtrVector.h:231
typename data_t::pointer pointer
Definition: PtrVector.h:52
void resize(size_type n)
Definition: PtrVector.h:316
reference at(size_type n)
Definition: PtrVector.h:359
const_iterator cbegin() const
Definition: PtrVector.h:273
bool empty() const
Definition: PtrVector.h:330
EDProductGetter const * productGetter() const noexcept
Definition: PtrVectorBase.h:86
size_type size() const
Definition: PtrVector.h:302
reference front()
Definition: PtrVector.h:373
iterator insert(iterator position, Ptr< U > const &p)
typename data_t::reference reference
Definition: PtrVector.h:50
const_iterator cend() const
Definition: PtrVector.h:280
void pop_back()
Definition: PtrVector.h:457
decltype(auto) constexpr cbegin(T &&obj)
ADL-aware version of std::cbegin.
Definition: StdUtils.h:85
Definition: MVAAlg.h:12
reverse_iterator rend()
Definition: PtrVector.h:259
data_t ptrs_
Definition: PtrVector.h:151
typename data_t::const_pointer const_pointer
Definition: PtrVector.h:53
Char_t n[5]
void assign(size_type n, Ptr< U > const &p)
Definition: PtrVector.h:403
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
typename data_t::size_type size_type
Definition: PtrVector.h:59
void updateCore(RefCore const &core)
indices_t::size_type size_type
Definition: PtrVectorBase.h:23
Ptr< T > const & operator[](unsigned long const idx) const
Definition: PtrVector.h:352
bool operator==(PtrVector const &other) const
Definition: PtrVector.h:541
void clear()
Definition: PtrVector.h:533
Definition: fwd.h:26
vec_iX clear()
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
Definition: StdUtils.h:109
void zeroTransients() override
Definition: PtrVector.h:587
RefCore const & refCore() const noexcept
Definition: Ptr.h:197