CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_3/src/DataFormats/Common/interface/PtrVector.h

Go to the documentation of this file.
00001 #ifndef DataFormats_Common_PtrVector_h
00002 #define DataFormats_Common_PtrVector_h
00003 // -*- C++ -*-
00004 //
00005 // Package:     Common
00006 // Class  :     PtrVector
00007 //
00016 //
00017 // Original Author:  Chris Jones
00018 //         Created:  Wed Oct 24 15:26:50 EDT 2007
00019 //
00020 
00021 // user include files
00022 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
00023 #include "DataFormats/Common/interface/Ptr.h"
00024 #include "DataFormats/Common/interface/PtrVectorBase.h"
00025 
00026 // system include files
00027 #include "boost/type_traits/is_base_of.hpp"
00028 #include <typeinfo>
00029 #include <vector>
00030 
00031 // forward declarations
00032 namespace edm {
00033   template <typename T> class PtrVector;
00034 
00035   template <typename T>
00036   class PtrHolder {
00037   public:
00038     PtrHolder(Ptr<T> const& iPtr) : ptr_(iPtr) {}
00039 
00040     Ptr<T> const& operator*() const {
00041       return ptr_;
00042     }
00043     Ptr<T> const* operator->() const {
00044       return &ptr_;
00045     }
00046   private:
00047     Ptr<T> ptr_;
00048   };
00049 
00050   template <typename T>
00051   class PtrVectorItr : public std::iterator <std::random_access_iterator_tag, Ptr<T> > {
00052   public:
00053     typedef Ptr<T> const reference; // otherwise boost::range does not work
00054                                     // const, because this is a const_iterator
00055     typedef PtrVectorItr<T> iterator;
00056     typedef typename std::iterator <std::random_access_iterator_tag, Ptr<T> >::difference_type difference_type;
00057 
00058     PtrVectorItr(std::vector<void const*>::const_iterator const& iItr,
00059                  PtrVector<T> const* iBase):
00060     iter_(iItr),
00061     base_(iBase) {}
00062 
00063     Ptr<T> const operator*() const {
00064       return base_->fromItr(iter_);
00065     }
00066 
00067     Ptr<T> const operator[](difference_type n) const {  // Otherwise the
00068       return base_->fromItr(iter_+n);        // boost::range
00069     }                                        // doesn't have []
00070 
00071 
00072     PtrHolder<T> operator->() const {
00073       return PtrHolder<T>( this->operator*() );
00074     }
00075 
00076     iterator & operator++() {++iter_; return *this;}
00077     iterator & operator--() {--iter_; return *this;}
00078     iterator & operator+=(difference_type n) {iter_ += n; return *this;}
00079     iterator & operator-=(difference_type n) {iter_ -= n; return *this;}
00080 
00081     iterator operator++(int) {iterator it(*this); ++iter_; return it;}
00082     iterator operator--(int) {iterator it(*this); --iter_; return it;}
00083     iterator operator+(difference_type n) const {iterator it(*this); it.iter_+=n; return it;}
00084     iterator operator-(difference_type n) const {iterator it(*this); it.iter_-=n; return it;}
00085 
00086     difference_type operator-(iterator const& rhs) const {return this->iter_ - rhs.iter_;}
00087 
00088     bool operator==(iterator const& rhs) const {return this->iter_ == rhs.iter_;}
00089     bool operator!=(iterator const& rhs) const {return this->iter_ != rhs.iter_;}
00090     bool operator<(iterator const& rhs) const {return this->iter_ < rhs.iter_;}
00091     bool operator>(iterator const& rhs) const {return this->iter_ > rhs.iter_;}
00092     bool operator<=(iterator const& rhs) const {return this->iter_ <= rhs.iter_;}
00093     bool operator>=(iterator const& rhs) const {return this->iter_ >= rhs.iter_;}
00094 
00095   private:
00096     std::vector<void const*>::const_iterator iter_;
00097     PtrVector<T> const* base_;
00098   };
00099 
00100   template <typename T>
00101   class PtrVector : public PtrVectorBase {
00102 
00103   public:
00104 
00105     typedef PtrVectorItr<T> const_iterator;
00106     typedef PtrVectorItr<T> iterator; // make boost::sub_range happy (std allows this)
00107     typedef Ptr<T> value_type;
00108     typedef void collection_type;
00109 
00110     friend class PtrVectorItr<T>;
00111     PtrVector() : PtrVectorBase() {}
00112     explicit PtrVector(ProductID const& iId) : PtrVectorBase(iId) {}
00113     PtrVector(PtrVector<T> const& iOther): PtrVectorBase(iOther) {}
00114 
00115     template <typename U>
00116     PtrVector(PtrVector<U> const& iOther): PtrVectorBase(iOther) {
00117       BOOST_STATIC_ASSERT( (boost::is_base_of<T, U>::value) );
00118     }
00119 
00120     // ---------- const member functions ---------------------
00121 
00122     Ptr<T> operator[](unsigned long const iIndex ) const {
00123       return this->makePtr<Ptr<T> >(iIndex);
00124     }
00125 
00126     const_iterator begin() const {
00127       return const_iterator(this->void_begin(),
00128                             this);
00129     }
00130 
00131     const_iterator end() const {
00132       return const_iterator(this->void_end(),
00133                             this);
00134     }
00135     // ---------- member functions ---------------------------
00136 
00137     void push_back(Ptr<T> const& iPtr) {
00138       this->push_back_base(iPtr.refCore(),
00139                            iPtr.key(),
00140                            iPtr.hasProductCache() ? iPtr.operator->() : static_cast<void const*>(0));
00141     }
00142 
00143     template<typename U>
00144     void push_back(Ptr<U> const& iPtr) {
00145       //check that types are assignable
00146       BOOST_STATIC_ASSERT( (boost::is_base_of<T, U>::value) );
00147       this->push_back_base(iPtr.refCore(),
00148                            iPtr.key(),
00149                            iPtr.hasProductCache() ? iPtr.operator->() : static_cast<void const*>(0));
00150     }
00151 
00152     void swap(PtrVector& other) {
00153       this->PtrVectorBase::swap(other);
00154     }
00155 
00156     PtrVector& operator=(PtrVector const& rhs) {
00157       PtrVector temp(rhs);
00158       this->swap(temp);
00159       return *this;
00160     }
00161 
00162     void fillView(std::vector<void const*>& pointers) const;
00163 
00164     //Used by ROOT storage
00165     CMS_CLASS_VERSION(8)
00166 
00167   private:
00168 
00169     //PtrVector const& operator=(PtrVector const&); // stop default
00170     std::type_info const& typeInfo() const {return typeid(T);}
00171 
00172     // ---------- member data --------------------------------
00173     Ptr<T> fromItr(std::vector<void const*>::const_iterator const& iItr) const {
00174       return this->makePtr<Ptr<T> >(iItr);
00175     }
00176 
00177   };
00178 
00179   template <typename T>
00180   void
00181   PtrVector<T>::fillView(std::vector<void const*>& pointers) const {
00182     pointers.reserve(this->size());
00183     for (const_iterator i = begin(), e = end(); i != e; ++i) {
00184       Ptr<T> ref = *i;
00185       T const* address = ref.isNull() ? 0 : &*ref;
00186       pointers.push_back(address);
00187     }
00188   }
00189 
00190   // NOTE: the following implementation has unusual signature!
00191   template <typename T>
00192   inline void fillView(PtrVector<T> const& obj,
00193                        std::vector<void const*>& pointers) {
00194     obj.fillView(pointers);
00195   }
00196 
00197   template <typename T>
00198   struct has_fillView<PtrVector<T> > {
00199     static bool const value = true;
00200   };
00201 
00202   // Free swap function
00203   template <typename T>
00204   inline
00205   void
00206   swap(PtrVector<T>& lhs, PtrVector<T>& rhs) {
00207     lhs.swap(rhs);
00208   }
00209 }
00210 #endif