File indexing completed on 2024-04-06 12:03:54
0001 #ifndef DataFormats_Common_RefVector_h
0002 #define DataFormats_Common_RefVector_h
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
0012 #include "DataFormats/Common/interface/EDProductfwd.h"
0013 #include "DataFormats/Common/interface/FillView.h"
0014 #include "DataFormats/Common/interface/Ref.h"
0015 #include "DataFormats/Common/interface/RefHolderBase.h"
0016 #include "DataFormats/Common/interface/RefTraits.h"
0017 #include "DataFormats/Common/interface/RefVectorBase.h"
0018 #include "DataFormats/Common/interface/RefVectorIterator.h"
0019 #include "DataFormats/Common/interface/RefVectorTraits.h"
0020 #include "DataFormats/Common/interface/traits.h"
0021 #include "DataFormats/Provenance/interface/ProductID.h"
0022
0023 #include <algorithm>
0024 #include <stdexcept>
0025 #include <vector>
0026
0027 namespace edm {
0028
0029 template <typename C,
0030 typename T = typename refhelper::ValueTrait<C>::value,
0031 typename F = typename refhelper::FindTrait<C, T>::value>
0032 class RefVector {
0033 public:
0034 typedef C collection_type;
0035 typedef T member_type;
0036 typedef F finder_type;
0037 typedef typename refhelper::RefVectorTrait<C, T, F>::iterator_type iterator;
0038 typedef iterator const_iterator;
0039 typedef typename refhelper::RefVectorTrait<C, T, F>::ref_type value_type;
0040 typedef value_type const const_reference;
0041 typedef const_reference reference;
0042
0043
0044 typedef typename value_type::key_type key_type;
0045 typedef std::vector<key_type> KeyVec;
0046
0047
0048 typedef typename KeyVec::size_type size_type;
0049 typedef RefVectorBase<key_type> contents_type;
0050
0051
0052
0053 RefVector() : refVector_() {}
0054 ~RefVector() = default;
0055
0056 RefVector(RefVector const& rh) : refVector_(rh.refVector_) {}
0057 RefVector(RefVector&& rh) noexcept : refVector_(std::move(rh.refVector_)) {}
0058
0059 RefVector& operator=(RefVector const& rhs);
0060 RefVector& operator=(RefVector&& rhs) noexcept {
0061 refVector_ = std::move(rhs.refVector_);
0062 return *this;
0063 }
0064
0065 RefVector(ProductID const& iId) : refVector_(iId) {}
0066
0067 void push_back(value_type const& ref) { refVector_.pushBack(ref.refCore(), ref.key()); }
0068
0069
0070 value_type const operator[](size_type idx) const {
0071 RefCore const& core = refVector_.refCore();
0072 key_type const& key = refVector_.keys()[idx];
0073 void const* memberPointer = refVector_.cachedMemberPointer(idx);
0074 if (memberPointer) {
0075 RefCore newCore(core);
0076 newCore.setProductPtr(memberPointer);
0077 return value_type(newCore, key);
0078 }
0079 return value_type(core, key);
0080 }
0081
0082
0083 value_type const at(size_type idx) const {
0084 RefCore const& core = refVector_.refCore();
0085 key_type const& key = refVector_.keys().at(idx);
0086 void const* memberPointer = refVector_.cachedMemberPointer(idx);
0087 if (memberPointer) {
0088 RefCore newCore(core);
0089 newCore.setProductPtr(memberPointer);
0090 return value_type(newCore, key);
0091 }
0092 return value_type(core, key);
0093 }
0094
0095
0096 contents_type const& refVector() const { return refVector_; }
0097
0098
0099 bool empty() const { return refVector_.empty(); }
0100
0101
0102 size_type size() const { return refVector_.size(); }
0103
0104
0105 size_type capacity() const { return refVector_.capacity(); }
0106
0107
0108 void reserve(size_type n) { refVector_.reserve(n); }
0109
0110
0111 const_iterator begin() const;
0112
0113
0114 const_iterator end() const;
0115
0116
0117 ProductID id() const { return refVector_.refCore().id(); }
0118
0119
0120 EDProductGetter const* productGetter() const { return refVector_.refCore().productGetter(); }
0121
0122
0123 bool isNull() const { return !id().isValid(); }
0124
0125
0126 bool isNonnull() const { return !isNull(); }
0127
0128
0129 bool operator!() const { return isNull(); }
0130
0131
0132
0133 bool isAvailable() const;
0134
0135
0136 bool isTransient() const { return refVector_.refCore().isTransient(); }
0137
0138
0139 iterator erase(iterator const& pos);
0140
0141
0142 void clear() { refVector_.clear(); }
0143
0144
0145 void swap(RefVector<C, T, F>& other) noexcept;
0146
0147
0148 bool hasProductCache() const { return refVector_.refCore().productPtr() != 0; }
0149
0150 void fillView(ProductID const& id, std::vector<void const*>& pointers, FillViewHelperVector& helpers) const;
0151
0152
0153 CMS_CLASS_VERSION(13)
0154
0155 private:
0156 contents_type refVector_;
0157 };
0158
0159 template <typename C, typename T, typename F>
0160 inline void RefVector<C, T, F>::swap(RefVector<C, T, F>& other) noexcept {
0161 refVector_.swap(other.refVector_);
0162 }
0163
0164 template <typename C, typename T, typename F>
0165 inline RefVector<C, T, F>& RefVector<C, T, F>::operator=(RefVector<C, T, F> const& rhs) {
0166 RefVector<C, T, F> temp(rhs);
0167 this->swap(temp);
0168 return *this;
0169 }
0170
0171 template <typename C, typename T, typename F>
0172 inline void swap(RefVector<C, T, F>& a, RefVector<C, T, F>& b) noexcept {
0173 a.swap(b);
0174 }
0175
0176 template <typename C, typename T, typename F>
0177 void RefVector<C, T, F>::fillView(ProductID const&,
0178 std::vector<void const*>& pointers,
0179 FillViewHelperVector& helpers) const {
0180 pointers.reserve(this->size());
0181 helpers.reserve(this->size());
0182
0183 size_type key = 0;
0184 for (const_iterator i = begin(), e = end(); i != e; ++i, ++key) {
0185 member_type const* address = i->isNull() ? nullptr : &**i;
0186 pointers.push_back(address);
0187 helpers.emplace_back(i->id(), i->key());
0188 }
0189 }
0190
0191 template <typename C, typename T, typename F>
0192 inline void fillView(RefVector<C, T, F> const& obj,
0193 ProductID const& id,
0194 std::vector<void const*>& pointers,
0195 FillViewHelperVector& helpers) {
0196 obj.fillView(id, pointers, helpers);
0197 }
0198
0199 template <typename C, typename T, typename F>
0200 struct has_fillView<RefVector<C, T, F> > {
0201 static bool const value = true;
0202 };
0203
0204 template <typename C, typename T, typename F>
0205 inline bool operator==(RefVector<C, T, F> const& lhs, RefVector<C, T, F> const& rhs) {
0206 return lhs.refVector() == rhs.refVector();
0207 }
0208
0209 template <typename C, typename T, typename F>
0210 inline bool operator!=(RefVector<C, T, F> const& lhs, RefVector<C, T, F> const& rhs) {
0211 return !(lhs == rhs);
0212 }
0213
0214 template <typename C, typename T, typename F>
0215 inline typename RefVector<C, T, F>::iterator RefVector<C, T, F>::erase(iterator const& pos) {
0216 typename contents_type::keys_type::size_type index = pos - begin();
0217 typename contents_type::keys_type::iterator newPos = refVector_.eraseAtIndex(index);
0218 typename contents_type::keys_type::size_type newIndex = newPos - refVector_.keys().begin();
0219 return iterator(this, newIndex);
0220 }
0221
0222 template <typename C, typename T, typename F>
0223 typename RefVector<C, T, F>::const_iterator RefVector<C, T, F>::begin() const {
0224 return iterator(this, 0);
0225 }
0226
0227 template <typename C, typename T, typename F>
0228 typename RefVector<C, T, F>::const_iterator RefVector<C, T, F>::end() const {
0229 return iterator(this, size());
0230 }
0231
0232 template <typename C, typename T, typename F>
0233 bool RefVector<C, T, F>::isAvailable() const {
0234 if (refVector_.refCore().isAvailable()) {
0235 return true;
0236 } else if (empty()) {
0237 return false;
0238 }
0239
0240
0241
0242
0243
0244
0245
0246
0247 for (size_type i = 0; i < size(); ++i) {
0248 if (!(*this)[i].isAvailable()) {
0249 return false;
0250 }
0251 }
0252 return true;
0253 }
0254
0255 template <typename C, typename T, typename F>
0256 std::ostream& operator<<(std::ostream& os, RefVector<C, T, F> const& r) {
0257 for (typename RefVector<C, T, F>::const_iterator i = r.begin(), e = r.end(); i != e; ++i) {
0258 os << *i << '\n';
0259 }
0260 return os;
0261 }
0262 }
0263
0264 #include "DataFormats/Common/interface/GetProduct.h"
0265 namespace edm {
0266 namespace detail {
0267
0268 template <typename C, typename T, typename F>
0269 struct GetProduct<RefVector<C, T, F> > {
0270 typedef T element_type;
0271 typedef typename RefVector<C, T, F>::const_iterator iter;
0272 static element_type const* address(iter const& i) { return &**i; }
0273 };
0274 }
0275 }
0276 #endif