CMS 3D CMS Logo

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