Back to home page

Project CMSSW displayed by LXR

 
 

    


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       //    operator T const*() const { return & **i; }
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); }  // for boost::iterator_range []
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       //    operator T *() const { return & **i; }
0126       //T *& get() { return *i; }
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); }  // for boost::iterator_range []
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     //Used by ROOT storage
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     // C++ does not yet support rvalue references, so d should only be
0328     // able to bind to an lvalue.
0329     // This should be called only for lvalues.
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     // C++ allows d to be bound to an lvalue or rvalue. But the other
0338     // signature should be a better match for an lvalue (because it
0339     // does not require an lvalue->rvalue conversion). Thus this
0340     // signature should only be chosen for rvalues.
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     // see push_back for documentation
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     // see push_back for documentation
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     // We have to delete the pointed-to thing, before we squeeze it
0420     // out of the vector...
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   // Free function template to support creation of Views.
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   // Free function templates to support the use of edm::Ptr.
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 }  // namespace edm
0594 
0595 #endif