Go to the documentation of this file.00001 #ifndef DataFormats_Common_PtrVector_h
00002 #define DataFormats_Common_PtrVector_h
00003
00004
00005
00006
00007
00016
00017
00018
00019
00020
00021
00022 #include "boost/type_traits/is_base_of.hpp"
00023 #include <vector>
00024
00025
00026 #include "DataFormats/Common/interface/Ptr.h"
00027 #include "DataFormats/Common/interface/PtrVectorBase.h"
00028
00029
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;
00052
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 {
00066 return base_->fromItr(iter_+n);
00067 }
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;
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
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
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
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
00165 std::type_info const& typeInfo() const {return typeid(T);}
00166
00167
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
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
00198 template <typename T>
00199 inline
00200 void
00201 swap(PtrVector<T>& lhs, PtrVector<T>& rhs) {
00202 lhs.swap(rhs);
00203 }
00204 }
00205 #endif