00001 #ifndef DataFormats_Common_PtrVector_h
00002 #define DataFormats_Common_PtrVector_h
00003
00004
00005
00006
00007
00016
00017
00018
00019
00020
00021
00022
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
00029 #include "DataFormats/Common/interface/Ptr.h"
00030 #include "DataFormats/Common/interface/PtrVectorBase.h"
00031
00032
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;
00055
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 {
00069 return base_->fromItr(iter_+n);
00070 }
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;
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
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
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
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
00164 std::type_info const& typeInfo() const {return typeid(T);}
00165
00166
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
00174 template <typename T>
00175 inline
00176 void
00177 swap(PtrVector<T>& lhs, PtrVector<T>& rhs) {
00178 lhs.swap(rhs);
00179 }
00180 }
00181 #endif