CMS 3D CMS Logo

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 // $Id: PtrVector.h,v 1.4 2009/02/12 19:45:29 wmtan Exp $
00020 //
00021 
00022 // system include files
00023 #include "boost/iterator.hpp"
00024 #include "boost/static_assert.hpp"
00025 #include "boost/type_traits/is_base_of.hpp"
00026 #include <vector>
00027 
00028 // user include files
00029 #include "DataFormats/Common/interface/Ptr.h"
00030 #include "DataFormats/Common/interface/PtrVectorBase.h"
00031 
00032 // forward declarations
00033 namespace edm {
00034   template <typename T> class PtrVector;
00035   
00036   template <typename T>
00037   class PtrHolder {
00038   public:
00039     PtrHolder(Ptr<T> const& iPtr) :ptr_(iPtr) {}
00040     
00041     Ptr<T> const& operator*() const {
00042       return ptr_;
00043     }
00044     Ptr<T> const* operator->() const {
00045       return &ptr_;
00046     }
00047   private:
00048     Ptr<T> ptr_;
00049   };
00050   
00051   template <typename T>
00052   class PtrVectorItr : public std::iterator <std::random_access_iterator_tag, Ptr<T> > {
00053   public:
00054     typedef Ptr<T> const reference; // otherwise boost::range does not work
00055                                     // const, because this is a const_iterator
00056     typedef PtrVectorItr<T> iterator;
00057     typedef typename std::iterator <std::random_access_iterator_tag, Ptr<T> >::difference_type difference_type;
00058     
00059     PtrVectorItr(std::vector<void const*>::const_iterator const& iItr,
00060                  PtrVector<T> const* iBase):
00061     iter_(iItr),
00062     base_(iBase) {}
00063     
00064     Ptr<T> const operator*() const {
00065       return base_->fromItr(iter_);
00066     }
00067 
00068     Ptr<T> const operator[](difference_type n) const {  // Otherwise the
00069       return base_->fromItr(iter_+n);        // boost::range 
00070     }                                        // doesn't have []
00071 
00072     
00073     PtrHolder<T> operator->() const {
00074       return PtrHolder<T>( this->operator*() );
00075     }
00076     
00077     iterator & operator++() {++iter_; return *this;}
00078     iterator & operator--() {--iter_; return *this;}
00079     iterator & operator+=(difference_type n) {iter_ += n; return *this;}
00080     iterator & operator-=(difference_type n) {iter_ -= n; return *this;}
00081     
00082     iterator operator++(int) {iterator it(*this); ++iter_; return it;}
00083     iterator operator--(int) {iterator it(*this); --iter_; return it;}
00084     iterator operator+(difference_type n) const {iterator it(*this); it.iter_+=n; return it;}
00085     iterator operator-(difference_type n) const {iterator it(*this); it.iter_-=n; return it;}
00086     
00087     difference_type operator-(iterator const& rhs) const {return this->iter_ - rhs.iter_;}
00088     
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     bool operator>=(iterator const& rhs) const {return this->iter_ >= rhs.iter_;}
00095     
00096   private:
00097     std::vector<void const*>::const_iterator iter_;
00098     PtrVector<T> const* base_;
00099   };
00100   
00101   template <typename T>
00102   class PtrVector : public PtrVectorBase {
00103     
00104   public:
00105     
00106     typedef PtrVectorItr<T> const_iterator;
00107     typedef PtrVectorItr<T> iterator; // make boost::sub_range happy (std allows this)
00108     typedef Ptr<T> value_type;
00109     
00110     friend class PtrVectorItr<T>;
00111     PtrVector() {}
00112     PtrVector(PtrVector<T> const& iOther): PtrVectorBase(iOther) {}
00113     
00114     template <typename U>
00115     PtrVector(PtrVector<U> const& iOther): PtrVectorBase(iOther) {
00116       BOOST_STATIC_ASSERT( (boost::is_base_of<T, U>::value) );
00117     }
00118     
00119     // ---------- const member functions ---------------------
00120     
00121     Ptr<T> operator[](unsigned long const iIndex ) const {
00122       return this->makePtr<Ptr<T> >(iIndex);
00123     }
00124     
00125     const_iterator begin() const {
00126       return const_iterator(this->void_begin(),
00127                             this);
00128     }
00129     
00130     const_iterator end() const {
00131       return const_iterator(this->void_end(),
00132                             this);
00133     }
00134     // ---------- member functions ---------------------------
00135     
00136     void push_back(Ptr<T> const& iPtr) {
00137       this->push_back_base(iPtr.refCore(),
00138                            iPtr.key(),
00139                            iPtr.hasCache() ? iPtr.operator->() : static_cast<void const*>(0));
00140     }
00141 
00142     template<typename U>
00143     void push_back(Ptr<U> const& iPtr) {
00144       //check that types are assignable
00145       BOOST_STATIC_ASSERT( (boost::is_base_of<T, U>::value) );
00146       this->push_back_base(iPtr.refCore(),
00147                            iPtr.key(),
00148                            iPtr.hasCache() ? iPtr.operator->() : static_cast<void const*>(0));
00149     }
00150 
00151     void swap(PtrVector& other) {
00152       this->PtrVectorBase::swap(other);
00153     }
00154     
00155     PtrVector& operator=(PtrVector const& rhs) {
00156       PtrVector temp(rhs);
00157       this->swap(temp);
00158       return *this;
00159     }
00160 
00161   private:
00162     
00163     //PtrVector const& operator=(PtrVector const&); // stop default
00164     std::type_info const& typeInfo() const {return typeid(T);}
00165 
00166     // ---------- member data --------------------------------
00167     Ptr<T> fromItr(std::vector<void const*>::const_iterator const& iItr) const {
00168       return this->makePtr<Ptr<T> >(iItr);
00169     }
00170     
00171   };
00172   
00173   // Free swap function
00174   template <typename T>
00175   inline
00176   void
00177   swap(PtrVector<T>& lhs, PtrVector<T>& rhs) {
00178     lhs.swap(rhs);
00179   }
00180 }
00181 #endif

Generated on Tue Jun 9 17:29:37 2009 for CMSSW by  doxygen 1.5.4