File indexing completed on 2024-04-06 12:03:53
0001 #ifndef DataFormats_Common_PtrVector_h
0002 #define DataFormats_Common_PtrVector_h
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
0023 #include "DataFormats/Common/interface/Ptr.h"
0024 #include "DataFormats/Common/interface/PtrVectorBase.h"
0025 #include "DataFormats/Common/interface/FillViewHelperVector.h"
0026
0027
0028 #include <type_traits>
0029 #include <typeinfo>
0030 #include <vector>
0031
0032
0033 namespace edm {
0034 class ProductID;
0035 template <typename T>
0036 class PtrVector;
0037
0038 template <typename T>
0039 class PtrHolder {
0040 public:
0041 PtrHolder(Ptr<T> const& iPtr) : ptr_(iPtr) {}
0042
0043 Ptr<T> const& operator*() const { return ptr_; }
0044 Ptr<T> const* operator->() const { return &ptr_; }
0045
0046 private:
0047 Ptr<T> ptr_;
0048 };
0049
0050 template <typename T>
0051 class PtrVectorItr {
0052 public:
0053 using iterator_category = std::random_access_iterator_tag;
0054 using value_type = Ptr<T>;
0055 using pointer = Ptr<T>*;
0056 using reference = Ptr<T> const;
0057
0058 using iterator = PtrVectorItr<T>;
0059 using difference_type = std::ptrdiff_t;
0060
0061 PtrVectorItr(std::vector<void const*>::const_iterator const& iItr, PtrVector<T> const* iBase)
0062 : iter_(iItr), base_(iBase) {}
0063
0064 Ptr<T> const operator*() const { return base_->fromItr(iter_); }
0065
0066 Ptr<T> const operator[](difference_type n) const {
0067 return base_->fromItr(iter_ + n);
0068 }
0069
0070 PtrHolder<T> operator->() const { return PtrHolder<T>(this->operator*()); }
0071
0072 iterator& operator++() {
0073 ++iter_;
0074 return *this;
0075 }
0076 iterator& operator--() {
0077 --iter_;
0078 return *this;
0079 }
0080 iterator& operator+=(difference_type n) {
0081 iter_ += n;
0082 return *this;
0083 }
0084 iterator& operator-=(difference_type n) {
0085 iter_ -= n;
0086 return *this;
0087 }
0088
0089 iterator operator++(int) {
0090 iterator it(*this);
0091 ++iter_;
0092 return it;
0093 }
0094 iterator operator--(int) {
0095 iterator it(*this);
0096 --iter_;
0097 return it;
0098 }
0099 iterator operator+(difference_type n) const {
0100 iterator it(*this);
0101 it.iter_ += n;
0102 return it;
0103 }
0104 iterator operator-(difference_type n) const {
0105 iterator it(*this);
0106 it.iter_ -= n;
0107 return it;
0108 }
0109
0110 difference_type operator-(iterator const& rhs) const { return this->iter_ - rhs.iter_; }
0111
0112 bool operator==(iterator const& rhs) const { return this->iter_ == rhs.iter_; }
0113 bool operator!=(iterator const& rhs) const { return this->iter_ != rhs.iter_; }
0114 bool operator<(iterator const& rhs) const { return this->iter_ < rhs.iter_; }
0115 bool operator>(iterator const& rhs) const { return this->iter_ > rhs.iter_; }
0116 bool operator<=(iterator const& rhs) const { return this->iter_ <= rhs.iter_; }
0117 bool operator>=(iterator const& rhs) const { return this->iter_ >= rhs.iter_; }
0118
0119 private:
0120 std::vector<void const*>::const_iterator iter_;
0121 PtrVector<T> const* base_;
0122 };
0123
0124 template <typename T>
0125 class PtrVector : public PtrVectorBase {
0126 public:
0127 using const_iterator = PtrVectorItr<T>;
0128 using iterator = PtrVectorItr<T>;
0129 using value_type = Ptr<T>;
0130 using member_type = T;
0131 using collection_type = void;
0132
0133 friend class PtrVectorItr<T>;
0134 PtrVector() : PtrVectorBase() {}
0135 explicit PtrVector(ProductID const& iId) : PtrVectorBase(iId) {}
0136 PtrVector(PtrVector<T> const& iOther) : PtrVectorBase(iOther) {}
0137
0138 template <typename U>
0139 PtrVector(PtrVector<U> const& iOther) : PtrVectorBase(iOther) {
0140 static_assert(std::is_base_of<T, U>::value, "PtrVector being copied is not of compatible type");
0141 }
0142
0143
0144
0145 Ptr<T> operator[](unsigned long const iIndex) const { return this->makePtr<Ptr<T> >(iIndex); }
0146
0147 const_iterator begin() const { return const_iterator(this->void_begin(), this); }
0148
0149 const_iterator end() const { return const_iterator(this->void_end(), this); }
0150
0151
0152 void push_back(Ptr<T> const& iPtr) {
0153 this->push_back_base(
0154 iPtr.refCore(), iPtr.key(), iPtr.hasProductCache() ? iPtr.operator->() : static_cast<void const*>(nullptr));
0155 }
0156
0157 template <typename U>
0158 void push_back(Ptr<U> const& iPtr) {
0159
0160 static_assert(std::is_base_of<T, U>::value,
0161 "Ptr used in push_back can not be converted to type used by PtrVector.");
0162 this->push_back_base(
0163 iPtr.refCore(), iPtr.key(), iPtr.hasProductCache() ? iPtr.operator->() : static_cast<void const*>(nullptr));
0164 }
0165
0166 void swap(PtrVector& other) { this->PtrVectorBase::swap(other); }
0167
0168 PtrVector& operator=(PtrVector const& rhs) {
0169 PtrVector temp(rhs);
0170 this->swap(temp);
0171 return *this;
0172 }
0173
0174 void fillView(std::vector<void const*>& pointers, FillViewHelperVector& helpers) const;
0175
0176
0177 CMS_CLASS_VERSION(8)
0178
0179 private:
0180
0181 std::type_info const& typeInfo() const override { return typeid(T); }
0182
0183
0184 Ptr<T> fromItr(std::vector<void const*>::const_iterator const& iItr) const { return this->makePtr<Ptr<T> >(iItr); }
0185 };
0186
0187 template <typename T>
0188 void PtrVector<T>::fillView(std::vector<void const*>& pointers, FillViewHelperVector& helpers) const {
0189 pointers.reserve(this->size());
0190 for (const_iterator i = begin(), e = end(); i != e; ++i) {
0191 Ptr<T> ref = *i;
0192 T const* address = ref.isNull() ? nullptr : &*ref;
0193 pointers.push_back(address);
0194 helpers.push_back(FillViewHelperVector::value_type(ref.id(), ref.key()));
0195 }
0196 }
0197
0198 template <typename T>
0199 inline void fillView(PtrVector<T> const& obj,
0200 ProductID const&,
0201 std::vector<void const*>& pointers,
0202 FillViewHelperVector& helpers) {
0203 obj.fillView(pointers, helpers);
0204 }
0205
0206 template <typename T>
0207 struct has_fillView<PtrVector<T> > {
0208 static bool const value = true;
0209 };
0210
0211
0212 template <typename T>
0213 inline void swap(PtrVector<T>& lhs, PtrVector<T>& rhs) {
0214 lhs.swap(rhs);
0215 }
0216 }
0217 #endif