CMS 3D CMS Logo

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