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 "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
00023 #include "DataFormats/Common/interface/Ptr.h"
00024 #include "DataFormats/Common/interface/PtrVectorBase.h"
00025
00026
00027 #include "boost/type_traits/is_base_of.hpp"
00028 #include <typeinfo>
00029 #include <vector>
00030
00031
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;
00054
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 {
00068 return base_->fromItr(iter_+n);
00069 }
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;
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
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
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
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
00165 CMS_CLASS_VERSION(8)
00166
00167 private:
00168
00169
00170 std::type_info const& typeInfo() const {return typeid(T);}
00171
00172
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
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
00203 template <typename T>
00204 inline
00205 void
00206 swap(PtrVector<T>& lhs, PtrVector<T>& rhs) {
00207 lhs.swap(rhs);
00208 }
00209 }
00210 #endif