CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/DataFormats/Common/interface/OwnVector.h

Go to the documentation of this file.
00001 #ifndef DataFormats_Common_OwnVector_h
00002 #define DataFormats_Common_OwnVector_h
00003 
00004 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
00005 #include "DataFormats/Common/interface/ClonePolicy.h"
00006 #include "DataFormats/Common/interface/fillPtrVector.h"
00007 #include "DataFormats/Common/interface/Ref.h"
00008 #include "DataFormats/Common/interface/setPtr.h"
00009 #include "DataFormats/Common/interface/traits.h"
00010 
00011 #if defined CMS_USE_DEBUGGING_ALLOCATOR
00012 #include "DataFormats/Common/interface/debugging_allocator.h"
00013 #endif
00014 #include "FWCore/Utilities/interface/EDMException.h"
00015 
00016 #include <algorithm>
00017 #include <functional>
00018 #include <typeinfo>
00019 #include <vector>
00020 #include "FWCore/Utilities/interface/GCC11Compatibility.h"
00021 
00022 namespace edm {
00023   class ProductID;
00024   template <typename T, typename P = ClonePolicy<T> >
00025   class OwnVector {
00026   private:
00027 #if defined(CMS_USE_DEBUGGING_ALLOCATOR)
00028     typedef std::vector<T*, debugging_allocator<T> > base;
00029 #else
00030     typedef std::vector<T*> base;
00031 #endif
00032 
00033   public:
00034     typedef typename base::size_type size_type;
00035     typedef T value_type;
00036     typedef T* pointer;
00037     typedef T& reference;
00038     typedef T const& const_reference;
00039     typedef P policy_type;
00040 
00041     class iterator;
00042     class const_iterator {
00043     public:
00044       typedef T value_type;
00045       typedef T* pointer;
00046       typedef T const& reference;
00047       typedef ptrdiff_t difference_type;
00048       typedef typename base::const_iterator::iterator_category iterator_category;
00049       const_iterator(typename base::const_iterator const& it) : i(it) { }
00050       const_iterator(iterator const& it) : i(it.i) { }
00051       const_iterator() {}
00052       const_iterator& operator++() { ++i; return *this; }
00053       const_iterator operator++(int) { const_iterator ci = *this; ++i; return ci; }
00054       const_iterator& operator--() { --i; return *this; }
00055       const_iterator operator--(int) { const_iterator ci = *this; --i; return ci; }
00056       difference_type operator-(const_iterator const& o) const { return i - o.i; }
00057       const_iterator operator+(difference_type n) const { return const_iterator(i + n); }
00058       const_iterator operator-(difference_type n) const { return const_iterator(i - n); }
00059       bool operator<(const_iterator const& o) const { return i < o.i; }
00060       bool operator==(const_iterator const& ci) const { return i == ci.i; }
00061       bool operator!=(const_iterator const& ci) const { return i != ci.i; }
00062       T const& operator *() const { return **i; }
00063       //    operator T const*() const { return & **i; }
00064       T const* operator->() const { return & (operator*()); }
00065       const_iterator & operator +=(difference_type d) { i += d; return *this; }
00066       const_iterator & operator -=(difference_type d) { i -= d; return *this; }
00067       reference operator[](difference_type d) const { return *const_iterator(i+d); } // for boost::iterator_range []
00068     private:
00069       typename base::const_iterator i;
00070     };
00071     class iterator {
00072     public:
00073       typedef T value_type;
00074       typedef T * pointer;
00075       typedef T & reference;
00076       typedef ptrdiff_t difference_type;
00077       typedef typename base::iterator::iterator_category iterator_category;
00078       iterator(typename base::iterator const& it) : i(it) { }
00079       iterator() {}
00080       iterator& operator++() { ++i; return *this; }
00081       iterator operator++(int) { iterator ci = *this; ++i; return ci; }
00082       iterator& operator--() { --i; return *this; }
00083       iterator operator--(int) { iterator ci = *this; --i; return ci; }
00084       difference_type operator-(iterator const& o) const { return i - o.i; }
00085       iterator operator+(difference_type n) const { return iterator(i + n); }
00086       iterator operator-(difference_type n) const { return iterator(i - n); }
00087       bool operator<(iterator const& o) const { return i < o.i; }
00088       bool operator==(iterator const& ci) const { return i == ci.i; }
00089       bool operator!=(iterator const& ci) const { return i != ci.i; }
00090       T & operator *() const { return **i; }
00091       //    operator T *() const { return & **i; }
00092       //T *& get() { return *i; }
00093       T * operator->() const { return & (operator*()); }
00094       iterator & operator +=(difference_type d) { i += d; return *this; }
00095       iterator & operator -=(difference_type d) { i -= d; return *this; }
00096       reference operator[](difference_type d) const { return *iterator(i+d); } // for boost::iterator_range []
00097     private:
00098       typename base::iterator i;
00099       friend class const_iterator;
00100       friend class OwnVector<T, P>;
00101    };
00102 
00103 
00104     OwnVector();
00105     OwnVector(size_type);
00106     OwnVector(OwnVector const&);
00107 #if defined(__GXX_EXPERIMENTAL_CXX0X__)
00108     OwnVector(OwnVector&&) noexcept;
00109 #endif
00110 
00111     ~OwnVector() noexcept;
00112 
00113     iterator begin();
00114     iterator end();
00115     const_iterator begin() const;
00116     const_iterator end() const;
00117     size_type size() const;
00118     bool empty() const;
00119     reference operator[](size_type);
00120     const_reference operator[](size_type) const;
00121 
00122     OwnVector<T, P>& operator=(OwnVector<T, P> const&);
00123 #if defined(__GXX_EXPERIMENTAL_CXX0X__)
00124     OwnVector<T, P>& operator=(OwnVector<T, P>&&) noexcept;
00125 #endif
00126 
00127 
00128     void reserve(size_t);
00129     template <typename D> void push_back(D*& d);
00130     template <typename D> void push_back(D* const& d);
00131     template <typename D> void push_back(std::auto_ptr<D> d);
00132     void push_back(T const& valueToCopy);
00133     bool is_back_safe() const;
00134     void pop_back();
00135     reference back();
00136     const_reference back() const;
00137     reference front();
00138     const_reference front() const;
00139     base const& data() const;
00140     void clear();
00141     iterator erase(iterator pos);
00142     iterator erase(iterator first, iterator last);
00143     template<typename S>
00144     void sort(S s);
00145     void sort();
00146 
00147     void swap(OwnVector<T, P>& other) noexcept;
00148 
00149     void fillView(ProductID const& id,
00150                   std::vector<void const*>& pointers,
00151                   helper_vector& helpers) const;
00152 
00153     void setPtr(std::type_info const& toType,
00154                 unsigned long index,
00155                 void const*& ptr) const;
00156 
00157     void fillPtrVector(std::type_info const& toType,
00158                        std::vector<unsigned long> const& indices,
00159                        std::vector<void const*>& ptrs) const;
00160 
00161 
00162     //Used by ROOT storage
00163     CMS_CLASS_VERSION(11)
00164 
00165   private:
00166     void destroy() noexcept;
00167     template<typename O>
00168     struct Ordering {
00169       Ordering(O const& c) : comp(c) { }
00170       bool operator()(T const* t1, T const* t2) const {
00171         return comp(*t1, *t2);
00172       }
00173     private:
00174       O comp;
00175     };
00176     template<typename O>
00177     static Ordering<O> ordering(O const& comp) {
00178       return Ordering<O>(comp);
00179     }
00180     base data_;
00181   };
00182 
00183   template<typename T, typename P>
00184   inline OwnVector<T, P>::OwnVector() : data_() {
00185   }
00186 
00187   template<typename T, typename P>
00188   inline OwnVector<T, P>::OwnVector(size_type n) : data_(n) {
00189   }
00190 
00191   template<typename T, typename P>
00192   inline OwnVector<T, P>::OwnVector(OwnVector<T, P> const& o) : data_(o.size()) {
00193     size_type current = 0;
00194     for (const_iterator i = o.begin(), e = o.end(); i != e; ++i,++current)
00195       data_[current] = policy_type::clone(*i);
00196   }
00197 
00198 #if defined(__GXX_EXPERIMENTAL_CXX0X__)
00199   template<typename T, typename P>
00200   inline OwnVector<T, P>::OwnVector(OwnVector<T, P>&& o)  noexcept{
00201     data_.swap(o.data_);
00202   }
00203 #endif
00204 
00205   template<typename T, typename P>
00206   inline OwnVector<T, P>::~OwnVector() noexcept {
00207     destroy();
00208   }
00209 
00210   template<typename T, typename P>
00211   inline OwnVector<T, P>& OwnVector<T, P>::operator=(OwnVector<T, P> const& o) {
00212     OwnVector<T,P> temp(o);
00213     swap(temp);
00214     return *this;
00215   }
00216 
00217 #if defined(__GXX_EXPERIMENTAL_CXX0X__)
00218   template<typename T, typename P>
00219   inline OwnVector<T, P>& OwnVector<T, P>::operator=(OwnVector<T, P>&& o) noexcept {
00220     data_.swap(o.data_);
00221     return *this;
00222   }
00223 #endif
00224 
00225 
00226   template<typename T, typename P>
00227   inline typename OwnVector<T, P>::iterator OwnVector<T, P>::begin() {
00228     return iterator(data_.begin());
00229   }
00230 
00231   template<typename T, typename P>
00232   inline typename OwnVector<T, P>::iterator OwnVector<T, P>::end() {
00233     return iterator(data_.end());
00234   }
00235 
00236   template<typename T, typename P>
00237   inline typename OwnVector<T, P>::const_iterator OwnVector<T, P>::begin() const {
00238     return const_iterator(data_.begin());
00239   }
00240 
00241   template<typename T, typename P>
00242   inline typename OwnVector<T, P>::const_iterator OwnVector<T, P>::end() const {
00243     return const_iterator(data_.end());
00244   }
00245 
00246   template<typename T, typename P>
00247   inline typename OwnVector<T, P>::size_type OwnVector<T, P>::size() const {
00248     return data_.size();
00249   }
00250 
00251   template<typename T, typename P>
00252   inline bool OwnVector<T, P>::empty() const {
00253     return data_.empty();
00254   }
00255 
00256   template<typename T, typename P>
00257   inline typename OwnVector<T, P>::reference OwnVector<T, P>::operator[](size_type n) {
00258     return *data_[n];
00259   }
00260 
00261   template<typename T, typename P>
00262   inline typename OwnVector<T, P>::const_reference OwnVector<T, P>::operator[](size_type n) const {
00263     return *data_[n];
00264   }
00265 
00266   template<typename T, typename P>
00267   inline void OwnVector<T, P>::reserve(size_t n) {
00268     data_.reserve(n);
00269   }
00270 
00271   template<typename T, typename P>
00272   template<typename D>
00273   inline void OwnVector<T, P>::push_back(D*& d) {
00274     // C++ does not yet support rvalue references, so d should only be
00275     // able to bind to an lvalue.
00276     // This should be called only for lvalues.
00277     data_.push_back(d);
00278     d = 0;
00279   }
00280 
00281   template<typename T, typename P>
00282   template<typename D>
00283   inline void OwnVector<T, P>::push_back(D* const& d) {
00284 
00285     // C++ allows d to be bound to an lvalue or rvalue. But the other
00286     // signature should be a better match for an lvalue (because it
00287     // does not require an lvalue->rvalue conversion). Thus this
00288     // signature should only be chosen for rvalues.
00289     data_.push_back(d);
00290   }
00291 
00292 
00293   template<typename T, typename P>
00294   template<typename D>
00295   inline void OwnVector<T, P>::push_back(std::auto_ptr<D> d) {
00296     data_.push_back(d.release());
00297   }
00298 
00299 
00300   template<typename T, typename P>
00301   inline void OwnVector<T, P>::push_back(T const& d) {
00302     data_.push_back(policy_type::clone(d));
00303   }
00304 
00305 
00306   template<typename T, typename P>
00307   inline void OwnVector<T, P>::pop_back() {
00308     // We have to delete the pointed-to thing, before we squeeze it
00309     // out of the vector...
00310     delete data_.back();
00311     data_.pop_back();
00312   }
00313 
00314   template <typename T, typename P>
00315   inline bool OwnVector<T, P>::is_back_safe() const {
00316     return data_.back() != 0;
00317   }
00318 
00319   template<typename T, typename P>
00320   inline typename OwnVector<T, P>::reference OwnVector<T, P>::back() {
00321     T* result = data_.back();
00322     if (result == 0) {
00323       Exception::throwThis(errors::NullPointerError,
00324         "In OwnVector::back() we have intercepted an attempt to dereference a null pointer\n"
00325         "Since OwnVector is allowed to contain null pointers, you much assure that the\n"
00326         "pointer at the end of the collection is not null before calling back()\n"
00327         "if you wish to avoid this exception.\n"
00328         "Consider using OwnVector::is_back_safe()\n");
00329     }
00330     return *data_.back();
00331   }
00332 
00333   template<typename T, typename P>
00334   inline typename OwnVector<T, P>::const_reference OwnVector<T, P>::back() const {
00335     T* result = data_.back();
00336     if (result == 0) {
00337       Exception::throwThis(errors::NullPointerError,
00338         "In OwnVector::back() we have intercepted an attempt to dereference a null pointer\n"
00339         "Since OwnVector is allowed to contain null pointers, you much assure that the\n"
00340         "pointer at the end of the collection is not null before calling back()\n"
00341         "if you wish to avoid this exception.\n"
00342         "Consider using OwnVector::is_back_safe()\n");
00343     }
00344     return *data_.back();
00345   }
00346 
00347   template<typename T, typename P>
00348   inline typename OwnVector<T, P>::reference OwnVector<T, P>::front() {
00349     return *data_.front();
00350   }
00351 
00352   template<typename T, typename P>
00353   inline typename OwnVector<T, P>::const_reference OwnVector<T, P>::front() const {
00354     return *data_.front();
00355   }
00356 
00357   template<typename T, typename P>
00358   inline void OwnVector<T, P>::destroy() noexcept {
00359     typename base::const_iterator b = data_.begin(), e = data_.end();
00360     for(typename base::const_iterator i = b; i != e; ++ i)
00361       delete * i;
00362   }
00363 
00364   template<typename T, typename P>
00365   inline typename OwnVector<T, P>::base const& OwnVector<T, P>::data() const {
00366     return data_;
00367   }
00368 
00369   template<typename T, typename P>
00370   inline void OwnVector<T, P>::clear() {
00371     destroy();
00372     data_.clear();
00373   }
00374 
00375   template<typename T, typename P>
00376   typename OwnVector<T, P>::iterator OwnVector<T, P>::erase(iterator pos) {
00377     delete * pos.i;
00378     return iterator(data_.erase(pos.i));
00379   }
00380 
00381   template<typename T, typename P>
00382   typename OwnVector<T, P>::iterator OwnVector<T, P>::erase(iterator first, iterator last) {
00383     typename base::iterator b = first.i, e = last.i;
00384     for(typename base::iterator i = b; i != e; ++ i)
00385       delete * i;
00386     return iterator(data_.erase(b, e));
00387   }
00388 
00389   template<typename T, typename P> template<typename S>
00390   void OwnVector<T, P>::sort(S comp) {
00391     std::sort(data_.begin(), data_.end(), ordering(comp));
00392   }
00393 
00394   template<typename T, typename P>
00395   void OwnVector<T, P>::sort() {
00396     std::sort(data_.begin(), data_.end(), ordering(std::less<value_type>()));
00397   }
00398 
00399   template<typename T, typename P>
00400   inline void OwnVector<T, P>::swap(OwnVector<T, P>& other) noexcept {
00401     data_.swap(other.data_);
00402   }
00403 
00404   template<typename T, typename P>
00405   void OwnVector<T, P>::fillView(ProductID const& id,
00406                                  std::vector<void const*>& pointers,
00407                                  helper_vector& helpers) const {
00408     typedef Ref<OwnVector>      ref_type ;
00409     typedef reftobase::RefHolder<ref_type> holder_type;
00410 
00411     size_type numElements = this->size();
00412     pointers.reserve(numElements);
00413     helpers.reserve(numElements);
00414     size_type key = 0;
00415     for(typename base::const_iterator i=data_.begin(), e=data_.end(); i!=e; ++i, ++key) {
00416 
00417       if (*i == 0) {
00418         Exception::throwThis(errors::NullPointerError,
00419           "In OwnVector::fillView() we have intercepted an attempt to put a null pointer\n"
00420           "into a View and that is not allowed.  It is probably an error that the null\n"
00421           "pointer was in the OwnVector in the first place.\n");
00422       }
00423       else {
00424         pointers.push_back(*i);
00425         holder_type h(ref_type(id, *i, key,this));
00426         helpers.push_back(&h);
00427       }
00428     }
00429   }
00430 
00431   template<typename T, typename P>
00432   inline void swap(OwnVector<T, P>& a, OwnVector<T, P>& b) noexcept {
00433     a.swap(b);
00434   }
00435 
00436   //----------------------------------------------------------------------
00437   //
00438   // Free function template to support creation of Views.
00439 
00440   template <typename T, typename P>
00441   inline
00442   void
00443   fillView(OwnVector<T,P> const& obj,
00444            ProductID const& id,
00445            std::vector<void const*>& pointers,
00446            helper_vector& helpers) {
00447     obj.fillView(id, pointers, helpers);
00448   }
00449 
00450 
00451   template <typename T, typename P>
00452   struct has_fillView<edm::OwnVector<T, P> > {
00453     static bool const value = true;
00454   };
00455 
00456 
00457   // Free function templates to support the use of edm::Ptr.
00458 
00459   template <typename T, typename P>
00460   inline
00461   void
00462   OwnVector<T,P>::setPtr(std::type_info const& toType,
00463                                    unsigned long index,
00464                                    void const*& ptr) const {
00465     detail::reallySetPtr<OwnVector<T,P> >(*this, toType, index, ptr);
00466   }
00467 
00468   template <typename T, typename P>
00469   inline
00470   void
00471   setPtr(OwnVector<T,P> const& obj,
00472          std::type_info const& toType,
00473          unsigned long index,
00474          void const*& ptr) {
00475     obj.setPtr(toType, index, ptr);
00476   }
00477 
00478   template <typename T, typename P>
00479   inline
00480   void
00481     OwnVector<T,P>::fillPtrVector(std::type_info const& toType,
00482                                   std::vector<unsigned long> const& indices,
00483                                   std::vector<void const*>& ptrs) const {
00484     detail::reallyfillPtrVector(*this, toType, indices, ptrs);
00485   }
00486 
00487 
00488   template <typename T, typename P>
00489   inline
00490   void
00491   fillPtrVector(OwnVector<T,P> const& obj,
00492                 std::type_info const& toType,
00493                 std::vector<unsigned long> const& indices,
00494                 std::vector<void const*>& ptrs) {
00495     obj.fillPtrVector(toType, indices, ptrs);
00496   }
00497 
00498 
00499   template <typename T, typename P>
00500    struct has_setPtr<edm::OwnVector<T,P> > {
00501      static bool const value = true;
00502    };
00503 
00504 
00505 }
00506 
00507 
00508 #endif