File indexing completed on 2024-04-06 12:03:52
0001 #ifndef DataFormats_Common_OwnVector_h
0002 #define DataFormats_Common_OwnVector_h
0003
0004 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
0005 #include "DataFormats/Common/interface/ClonePolicy.h"
0006 #include "DataFormats/Common/interface/fillPtrVector.h"
0007 #include "DataFormats/Common/interface/Ref.h"
0008 #include "DataFormats/Common/interface/setPtr.h"
0009 #include "DataFormats/Common/interface/traits.h"
0010
0011 #if defined CMS_USE_DEBUGGING_ALLOCATOR
0012 #include "DataFormats/Common/interface/debugging_allocator.h"
0013 #endif
0014 #include "FWCore/Utilities/interface/EDMException.h"
0015
0016 #include <algorithm>
0017 #include <functional>
0018 #include <typeinfo>
0019 #include <vector>
0020
0021 namespace edm {
0022 class ProductID;
0023 template <typename T, typename P = ClonePolicy<T> >
0024 class OwnVector {
0025 public:
0026 #if defined(CMS_USE_DEBUGGING_ALLOCATOR)
0027 typedef std::vector<T*, debugging_allocator<T> > base;
0028 #else
0029 typedef std::vector<T*> base;
0030 #endif
0031
0032 public:
0033 typedef typename base::size_type size_type;
0034 typedef T value_type;
0035 typedef T* pointer;
0036 typedef T& reference;
0037 typedef T const& const_reference;
0038 typedef P policy_type;
0039
0040 class iterator;
0041 class const_iterator {
0042 public:
0043 typedef T value_type;
0044 typedef T* pointer;
0045 typedef T const& reference;
0046 typedef ptrdiff_t difference_type;
0047 typedef typename base::const_iterator::iterator_category iterator_category;
0048 const_iterator(iterator const& it) : i(it.i) {}
0049 const_iterator() {}
0050 const_iterator& operator++() {
0051 ++i;
0052 return *this;
0053 }
0054 const_iterator operator++(int) {
0055 const_iterator ci = *this;
0056 ++i;
0057 return ci;
0058 }
0059 const_iterator& operator--() {
0060 --i;
0061 return *this;
0062 }
0063 const_iterator operator--(int) {
0064 const_iterator ci = *this;
0065 --i;
0066 return ci;
0067 }
0068 difference_type operator-(const_iterator const& o) const { return i - o.i; }
0069 const_iterator operator+(difference_type n) const { return const_iterator(i + n); }
0070 const_iterator operator-(difference_type n) const { return const_iterator(i - n); }
0071 bool operator<(const_iterator const& o) const { return i < o.i; }
0072 bool operator==(const_iterator const& ci) const { return i == ci.i; }
0073 bool operator!=(const_iterator const& ci) const { return i != ci.i; }
0074 T const& operator*() const { return **i; }
0075
0076 T const* operator->() const { return &(operator*()); }
0077 const_iterator& operator+=(difference_type d) {
0078 i += d;
0079 return *this;
0080 }
0081 const_iterator& operator-=(difference_type d) {
0082 i -= d;
0083 return *this;
0084 }
0085 reference operator[](difference_type d) const { return *const_iterator(i + d); }
0086 private:
0087 const_iterator(typename base::const_iterator const& it) : i(it) {}
0088 typename base::const_iterator base_iter() const { return i; }
0089 typename base::const_iterator i;
0090 friend class OwnVector<T, P>;
0091 };
0092 class iterator {
0093 public:
0094 typedef T value_type;
0095 typedef T* pointer;
0096 typedef T& reference;
0097 typedef ptrdiff_t difference_type;
0098 typedef typename base::iterator::iterator_category iterator_category;
0099 iterator() {}
0100 iterator& operator++() {
0101 ++i;
0102 return *this;
0103 }
0104 iterator operator++(int) {
0105 iterator ci = *this;
0106 ++i;
0107 return ci;
0108 }
0109 iterator& operator--() {
0110 --i;
0111 return *this;
0112 }
0113 iterator operator--(int) {
0114 iterator ci = *this;
0115 --i;
0116 return ci;
0117 }
0118 difference_type operator-(iterator const& o) const { return i - o.i; }
0119 iterator operator+(difference_type n) const { return iterator(i + n); }
0120 iterator operator-(difference_type n) const { return iterator(i - n); }
0121 bool operator<(iterator const& o) const { return i < o.i; }
0122 bool operator==(iterator const& ci) const { return i == ci.i; }
0123 bool operator!=(iterator const& ci) const { return i != ci.i; }
0124 T& operator*() const { return **i; }
0125
0126
0127 T* operator->() const { return &(operator*()); }
0128 iterator& operator+=(difference_type d) {
0129 i += d;
0130 return *this;
0131 }
0132 iterator& operator-=(difference_type d) {
0133 i -= d;
0134 return *this;
0135 }
0136 reference operator[](difference_type d) const { return *iterator(i + d); }
0137 private:
0138 iterator(typename base::iterator const& it) : i(it) {}
0139 typename base::iterator i;
0140 friend class const_iterator;
0141 friend class OwnVector<T, P>;
0142 };
0143
0144 OwnVector();
0145 OwnVector(size_type);
0146 OwnVector(OwnVector const&);
0147 #if defined(__GXX_EXPERIMENTAL_CXX0X__)
0148 OwnVector(OwnVector&&) noexcept;
0149 #endif
0150
0151 ~OwnVector() noexcept;
0152
0153 iterator begin();
0154 iterator end();
0155 const_iterator begin() const;
0156 const_iterator end() const;
0157 size_type size() const;
0158 bool empty() const;
0159 reference operator[](size_type);
0160 const_reference operator[](size_type) const;
0161
0162 OwnVector<T, P>& operator=(OwnVector<T, P> const&);
0163 #if defined(__GXX_EXPERIMENTAL_CXX0X__)
0164 OwnVector<T, P>& operator=(OwnVector<T, P>&&) noexcept;
0165 #endif
0166
0167 void shrink_to_fit() { data_.shrink_to_fit(); }
0168
0169 void reserve(size_t);
0170 template <typename D>
0171 void push_back(D*& d);
0172 template <typename D>
0173 void push_back(D* const& d);
0174 template <typename D>
0175 void push_back(std::unique_ptr<D> d);
0176 void push_back(T const& valueToCopy);
0177
0178 template <typename D>
0179 void set(size_t i, D*& d);
0180 template <typename D>
0181 void set(size_t i, D* const& d);
0182 template <typename D>
0183 void set(size_t i, std::unique_ptr<D> d);
0184 void set(size_t i, T const& valueToCopy);
0185
0186 template <typename D>
0187 void insert(const_iterator i, D*& d);
0188 template <typename D>
0189 void insert(const_iterator i, D* const& d);
0190 template <typename D>
0191 void insert(const_iterator i, std::unique_ptr<D> d);
0192 void insert(const_iterator i, T const& valueToCopy);
0193
0194 bool is_back_safe() const;
0195 void pop_back();
0196 reference back();
0197 const_reference back() const;
0198 reference front();
0199 const_reference front() const;
0200 base const& data() const;
0201 void clear();
0202 iterator erase(iterator pos);
0203 iterator erase(iterator first, iterator last);
0204 void reverse() { std::reverse(data_.begin(), data_.end()); }
0205 template <typename S>
0206 void sort(S s);
0207 void sort();
0208
0209 void swap(OwnVector<T, P>& other) noexcept;
0210
0211 void fillView(ProductID const& id, std::vector<void const*>& pointers, FillViewHelperVector& helpers) const;
0212
0213 void setPtr(std::type_info const& toType, unsigned long index, void const*& ptr) const;
0214
0215 void fillPtrVector(std::type_info const& toType,
0216 std::vector<unsigned long> const& indices,
0217 std::vector<void const*>& ptrs) const;
0218
0219
0220 CMS_CLASS_VERSION(11)
0221
0222 private:
0223 void destroy() noexcept;
0224 template <typename O>
0225 struct Ordering {
0226 Ordering(O const& c) : comp(c) {}
0227 bool operator()(T const* t1, T const* t2) const { return comp(*t1, *t2); }
0228
0229 private:
0230 O comp;
0231 };
0232 template <typename O>
0233 static Ordering<O> ordering(O const& comp) {
0234 return Ordering<O>(comp);
0235 }
0236 base data_;
0237 };
0238
0239 template <typename T, typename P>
0240 inline OwnVector<T, P>::OwnVector() : data_() {}
0241
0242 template <typename T, typename P>
0243 inline OwnVector<T, P>::OwnVector(size_type n) : data_(n) {}
0244
0245 template <typename T, typename P>
0246 inline OwnVector<T, P>::OwnVector(OwnVector<T, P> const& o) : data_(o.size()) {
0247 size_type current = 0;
0248 for (const_iterator i = o.begin(), e = o.end(); i != e; ++i, ++current)
0249 data_[current] = policy_type::clone(*i);
0250 }
0251
0252 #if defined(__GXX_EXPERIMENTAL_CXX0X__)
0253 template <typename T, typename P>
0254 inline OwnVector<T, P>::OwnVector(OwnVector<T, P>&& o) noexcept {
0255 data_.swap(o.data_);
0256 }
0257 #endif
0258
0259 template <typename T, typename P>
0260 inline OwnVector<T, P>::~OwnVector() noexcept {
0261 destroy();
0262 }
0263
0264 template <typename T, typename P>
0265 inline OwnVector<T, P>& OwnVector<T, P>::operator=(OwnVector<T, P> const& o) {
0266 OwnVector<T, P> temp(o);
0267 swap(temp);
0268 return *this;
0269 }
0270
0271 #if defined(__GXX_EXPERIMENTAL_CXX0X__)
0272 template <typename T, typename P>
0273 inline OwnVector<T, P>& OwnVector<T, P>::operator=(OwnVector<T, P>&& o) noexcept {
0274 data_.swap(o.data_);
0275 return *this;
0276 }
0277 #endif
0278
0279 template <typename T, typename P>
0280 inline typename OwnVector<T, P>::iterator OwnVector<T, P>::begin() {
0281 return iterator(data_.begin());
0282 }
0283
0284 template <typename T, typename P>
0285 inline typename OwnVector<T, P>::iterator OwnVector<T, P>::end() {
0286 return iterator(data_.end());
0287 }
0288
0289 template <typename T, typename P>
0290 inline typename OwnVector<T, P>::const_iterator OwnVector<T, P>::begin() const {
0291 return const_iterator(data_.begin());
0292 }
0293
0294 template <typename T, typename P>
0295 inline typename OwnVector<T, P>::const_iterator OwnVector<T, P>::end() const {
0296 return const_iterator(data_.end());
0297 }
0298
0299 template <typename T, typename P>
0300 inline typename OwnVector<T, P>::size_type OwnVector<T, P>::size() const {
0301 return data_.size();
0302 }
0303
0304 template <typename T, typename P>
0305 inline bool OwnVector<T, P>::empty() const {
0306 return data_.empty();
0307 }
0308
0309 template <typename T, typename P>
0310 inline typename OwnVector<T, P>::reference OwnVector<T, P>::operator[](size_type n) {
0311 return *data_[n];
0312 }
0313
0314 template <typename T, typename P>
0315 inline typename OwnVector<T, P>::const_reference OwnVector<T, P>::operator[](size_type n) const {
0316 return *data_[n];
0317 }
0318
0319 template <typename T, typename P>
0320 inline void OwnVector<T, P>::reserve(size_t n) {
0321 data_.reserve(n);
0322 }
0323
0324 template <typename T, typename P>
0325 template <typename D>
0326 inline void OwnVector<T, P>::push_back(D*& d) {
0327
0328
0329
0330 data_.push_back(d);
0331 d = nullptr;
0332 }
0333
0334 template <typename T, typename P>
0335 template <typename D>
0336 inline void OwnVector<T, P>::push_back(D* const& d) {
0337
0338
0339
0340
0341 data_.push_back(d);
0342 }
0343
0344 template <typename T, typename P>
0345 template <typename D>
0346 inline void OwnVector<T, P>::push_back(std::unique_ptr<D> d) {
0347 data_.push_back(d.release());
0348 }
0349
0350 template <typename T, typename P>
0351 inline void OwnVector<T, P>::push_back(T const& d) {
0352 data_.push_back(policy_type::clone(d));
0353 }
0354
0355 template <typename T, typename P>
0356 template <typename D>
0357 inline void OwnVector<T, P>::set(size_t i, D*& d) {
0358
0359 if (d == data_[i])
0360 return;
0361 delete data_[i];
0362 data_[i] = d;
0363 d = nullptr;
0364 }
0365
0366 template <typename T, typename P>
0367 template <typename D>
0368 inline void OwnVector<T, P>::set(size_t i, D* const& d) {
0369
0370 if (d == data_[i])
0371 return;
0372 delete data_[i];
0373 data_[i] = d;
0374 }
0375
0376 template <typename T, typename P>
0377 template <typename D>
0378 inline void OwnVector<T, P>::set(size_t i, std::unique_ptr<D> d) {
0379 if (d.get() == data_[i])
0380 return;
0381 delete data_[i];
0382 data_[i] = d.release();
0383 }
0384
0385 template <typename T, typename P>
0386 inline void OwnVector<T, P>::set(size_t i, T const& d) {
0387 if (&d == data_[i])
0388 return;
0389 delete data_[i];
0390 data_[i] = policy_type::clone(d);
0391 }
0392
0393 template <typename T, typename P>
0394 template <typename D>
0395 inline void OwnVector<T, P>::insert(const_iterator it, D*& d) {
0396 data_.insert(it.base_iter(), d);
0397 d = nullptr;
0398 }
0399
0400 template <typename T, typename P>
0401 template <typename D>
0402 inline void OwnVector<T, P>::insert(const_iterator it, D* const& d) {
0403 data_.insert(it.base_iter(), d);
0404 }
0405
0406 template <typename T, typename P>
0407 template <typename D>
0408 inline void OwnVector<T, P>::insert(const_iterator it, std::unique_ptr<D> d) {
0409 data_.insert(it.base_iter(), d.release());
0410 }
0411
0412 template <typename T, typename P>
0413 inline void OwnVector<T, P>::insert(const_iterator it, T const& d) {
0414 data_.insert(it.base_iter(), policy_type::clone(d));
0415 }
0416
0417 template <typename T, typename P>
0418 inline void OwnVector<T, P>::pop_back() {
0419
0420
0421 delete data_.back();
0422 data_.pop_back();
0423 }
0424
0425 template <typename T, typename P>
0426 inline bool OwnVector<T, P>::is_back_safe() const {
0427 return data_.back() != 0;
0428 }
0429
0430 template <typename T, typename P>
0431 inline typename OwnVector<T, P>::reference OwnVector<T, P>::back() {
0432 T* result = data_.back();
0433 if (result == nullptr) {
0434 Exception::throwThis(errors::NullPointerError,
0435 "In OwnVector::back() we have intercepted an attempt to dereference a null pointer\n"
0436 "Since OwnVector is allowed to contain null pointers, you much assure that the\n"
0437 "pointer at the end of the collection is not null before calling back()\n"
0438 "if you wish to avoid this exception.\n"
0439 "Consider using OwnVector::is_back_safe()\n");
0440 }
0441 return *data_.back();
0442 }
0443
0444 template <typename T, typename P>
0445 inline typename OwnVector<T, P>::const_reference OwnVector<T, P>::back() const {
0446 T* result = data_.back();
0447 if (result == 0) {
0448 Exception::throwThis(errors::NullPointerError,
0449 "In OwnVector::back() we have intercepted an attempt to dereference a null pointer\n"
0450 "Since OwnVector is allowed to contain null pointers, you much assure that the\n"
0451 "pointer at the end of the collection is not null before calling back()\n"
0452 "if you wish to avoid this exception.\n"
0453 "Consider using OwnVector::is_back_safe()\n");
0454 }
0455 return *data_.back();
0456 }
0457
0458 template <typename T, typename P>
0459 inline typename OwnVector<T, P>::reference OwnVector<T, P>::front() {
0460 return *data_.front();
0461 }
0462
0463 template <typename T, typename P>
0464 inline typename OwnVector<T, P>::const_reference OwnVector<T, P>::front() const {
0465 return *data_.front();
0466 }
0467
0468 template <typename T, typename P>
0469 inline void OwnVector<T, P>::destroy() noexcept {
0470 typename base::const_iterator b = data_.begin(), e = data_.end();
0471 for (typename base::const_iterator i = b; i != e; ++i)
0472 delete *i;
0473 }
0474
0475 template <typename T, typename P>
0476 inline typename OwnVector<T, P>::base const& OwnVector<T, P>::data() const {
0477 return data_;
0478 }
0479
0480 template <typename T, typename P>
0481 inline void OwnVector<T, P>::clear() {
0482 destroy();
0483 data_.clear();
0484 }
0485
0486 template <typename T, typename P>
0487 typename OwnVector<T, P>::iterator OwnVector<T, P>::erase(iterator pos) {
0488 delete *pos.i;
0489 return iterator(data_.erase(pos.i));
0490 }
0491
0492 template <typename T, typename P>
0493 typename OwnVector<T, P>::iterator OwnVector<T, P>::erase(iterator first, iterator last) {
0494 typename base::iterator b = first.i, e = last.i;
0495 for (typename base::iterator i = b; i != e; ++i)
0496 delete *i;
0497 return iterator(data_.erase(b, e));
0498 }
0499
0500 template <typename T, typename P>
0501 template <typename S>
0502 void OwnVector<T, P>::sort(S comp) {
0503 std::sort(data_.begin(), data_.end(), ordering(comp));
0504 }
0505
0506 template <typename T, typename P>
0507 void OwnVector<T, P>::sort() {
0508 std::sort(data_.begin(), data_.end(), ordering(std::less<value_type>()));
0509 }
0510
0511 template <typename T, typename P>
0512 inline void OwnVector<T, P>::swap(OwnVector<T, P>& other) noexcept {
0513 data_.swap(other.data_);
0514 }
0515
0516 #if defined(__GXX_EXPERIMENTAL_CXX0X__)
0517 template <typename T, typename P>
0518 void OwnVector<T, P>::fillView(ProductID const& id,
0519 std::vector<void const*>& pointers,
0520 FillViewHelperVector& helpers) const {
0521 size_type numElements = this->size();
0522 pointers.reserve(numElements);
0523 helpers.reserve(numElements);
0524 size_type key = 0;
0525 for (typename base::const_iterator i = data_.begin(), e = data_.end(); i != e; ++i, ++key) {
0526 if (*i == nullptr) {
0527 Exception::throwThis(errors::NullPointerError,
0528 "In OwnVector::fillView() we have intercepted an attempt to put a null pointer\n"
0529 "into a View and that is not allowed. It is probably an error that the null\n"
0530 "pointer was in the OwnVector in the first place.\n");
0531 } else {
0532 pointers.push_back(*i);
0533 helpers.emplace_back(id, key);
0534 }
0535 }
0536 }
0537 #endif
0538
0539 template <typename T, typename P>
0540 inline void swap(OwnVector<T, P>& a, OwnVector<T, P>& b) noexcept {
0541 a.swap(b);
0542 }
0543
0544
0545
0546
0547
0548 template <typename T, typename P>
0549 inline void fillView(OwnVector<T, P> const& obj,
0550 ProductID const& id,
0551 std::vector<void const*>& pointers,
0552 FillViewHelperVector& helpers) {
0553 obj.fillView(id, pointers, helpers);
0554 }
0555
0556 template <typename T, typename P>
0557 struct has_fillView<edm::OwnVector<T, P> > {
0558 static bool const value = true;
0559 };
0560
0561
0562
0563 template <typename T, typename P>
0564 inline void OwnVector<T, P>::setPtr(std::type_info const& toType, unsigned long index, void const*& ptr) const {
0565 detail::reallySetPtr<OwnVector<T, P> >(*this, toType, index, ptr);
0566 }
0567
0568 template <typename T, typename P>
0569 inline void setPtr(OwnVector<T, P> const& obj, std::type_info const& toType, unsigned long index, void const*& ptr) {
0570 obj.setPtr(toType, index, ptr);
0571 }
0572
0573 template <typename T, typename P>
0574 inline void OwnVector<T, P>::fillPtrVector(std::type_info const& toType,
0575 std::vector<unsigned long> const& indices,
0576 std::vector<void const*>& ptrs) const {
0577 detail::reallyfillPtrVector(*this, toType, indices, ptrs);
0578 }
0579
0580 template <typename T, typename P>
0581 inline void fillPtrVector(OwnVector<T, P> const& obj,
0582 std::type_info const& toType,
0583 std::vector<unsigned long> const& indices,
0584 std::vector<void const*>& ptrs) {
0585 obj.fillPtrVector(toType, indices, ptrs);
0586 }
0587
0588 template <typename T, typename P>
0589 struct has_setPtr<edm::OwnVector<T, P> > {
0590 static bool const value = true;
0591 };
0592
0593 }
0594
0595 #endif