File indexing completed on 2024-04-06 12:03:54
0001 #ifndef DataFormats_Common_RefToBaseVector_h
0002 #define DataFormats_Common_RefToBaseVector_h
0003
0004
0005
0006
0007
0008 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
0009 #include "DataFormats/Common/interface/FillViewHelperVector.h"
0010 #include "DataFormats/Provenance/interface/ProductID.h"
0011 #include <algorithm>
0012 #include <memory>
0013 #include <utility>
0014 #include <vector>
0015
0016 namespace edm {
0017 template <typename T>
0018 class RefToBase;
0019 template <typename T>
0020 class View;
0021 template <typename C>
0022 class Handle;
0023 class EDProductGetter;
0024 namespace reftobase {
0025 template <typename T>
0026 class BaseVectorHolder;
0027 class RefVectorHolderBase;
0028 }
0029
0030 template <class T>
0031 class RefToBaseVector {
0032 public:
0033 typedef RefToBase<T> value_type;
0034 typedef T member_type;
0035 typedef reftobase::BaseVectorHolder<T> holder_type;
0036 typedef typename holder_type::size_type size_type;
0037 typedef typename holder_type::const_iterator const_iterator;
0038
0039 RefToBaseVector();
0040 RefToBaseVector(RefToBaseVector const&);
0041 template <class REFV>
0042 explicit RefToBaseVector(REFV const&);
0043 template <typename C>
0044 explicit RefToBaseVector(Handle<C> const&);
0045 RefToBaseVector(std::shared_ptr<reftobase::RefVectorHolderBase> p);
0046 RefToBaseVector& operator=(RefToBaseVector const& iRHS);
0047 void swap(RefToBaseVector& other);
0048
0049 ~RefToBaseVector();
0050
0051
0052 void clear();
0053
0054 value_type at(size_type idx) const;
0055 value_type operator[](size_type idx) const;
0056 bool isValid() const { return holder_ != nullptr; }
0057 bool isInvalid() const { return holder_ == nullptr; }
0058 bool empty() const;
0059 size_type size() const;
0060
0061 ProductID id() const;
0062 EDProductGetter const* productGetter() const;
0063 const_iterator begin() const;
0064 const_iterator end() const;
0065
0066 void push_back(const RefToBase<T>&);
0067
0068 void fillView(std::vector<void const*>& pointers, FillViewHelperVector& helpers) const;
0069 std::unique_ptr<reftobase::RefVectorHolderBase> vectorHolder() const;
0070
0071
0072
0073 bool isAvailable() const { return holder_->isAvailable(); }
0074
0075
0076 CMS_CLASS_VERSION(10)
0077
0078 private:
0079 holder_type* holder_;
0080 };
0081 }
0082
0083 #include "DataFormats/Common/interface/RefToBase.h"
0084 #include "DataFormats/Common/interface/VectorHolder.h"
0085 #include "DataFormats/Common/interface/IndirectVectorHolder.h"
0086 #include "DataFormats/Common/interface/RefVectorHolder.h"
0087 #include "FWCore/Utilities/interface/EDMException.h"
0088 #include "DataFormats/Common/interface/traits.h"
0089
0090 namespace edm {
0091 template <class T>
0092 inline void swap(RefToBaseVector<T>& a, RefToBaseVector<T>& b) {
0093 a.swap(b);
0094 }
0095
0096 template <class T>
0097 inline bool operator==(RefToBaseVector<T> const& a, RefToBaseVector<T> const& b) {
0098 if (a.isInvalid() && b.isInvalid())
0099 return true;
0100 if (a.isInvalid() || b.isInvalid())
0101 return false;
0102 return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin());
0103 }
0104
0105
0106
0107
0108
0109 template <class T>
0110 inline RefToBaseVector<T>::RefToBaseVector() : holder_(nullptr) {}
0111
0112 template <class T>
0113 template <class REFV>
0114 inline RefToBaseVector<T>::RefToBaseVector(const REFV& iRef) : holder_(new reftobase::VectorHolder<T, REFV>(iRef)) {}
0115
0116 template <class T>
0117 inline RefToBaseVector<T>::RefToBaseVector(const RefToBaseVector<T>& iOther)
0118 : holder_(iOther.holder_ ? iOther.holder_->clone() : nullptr) {}
0119
0120 template <class T>
0121 inline RefToBaseVector<T>::RefToBaseVector(std::shared_ptr<reftobase::RefVectorHolderBase> p)
0122 : holder_(new reftobase::IndirectVectorHolder<T>(p)) {}
0123
0124 template <class T>
0125 inline RefToBaseVector<T>& RefToBaseVector<T>::operator=(const RefToBaseVector& iRHS) {
0126 RefToBaseVector temp(iRHS);
0127 this->swap(temp);
0128 return *this;
0129 }
0130
0131 template <class T>
0132 inline void RefToBaseVector<T>::swap(RefToBaseVector& other) {
0133 std::swap(holder_, other.holder_);
0134 }
0135
0136 template <class T>
0137 inline RefToBaseVector<T>::~RefToBaseVector() {
0138 delete holder_;
0139 }
0140
0141 template <class T>
0142 inline typename RefToBaseVector<T>::value_type RefToBaseVector<T>::at(size_type idx) const {
0143 if (holder_ == nullptr)
0144 Exception::throwThis(
0145 errors::InvalidReference, "Trying to dereference null RefToBaseVector<T> in method: at(", idx, ")\n");
0146 return holder_->at(idx);
0147 }
0148
0149 template <class T>
0150 inline typename RefToBaseVector<T>::value_type RefToBaseVector<T>::operator[](size_type idx) const {
0151 return at(idx);
0152 }
0153
0154 template <class T>
0155 inline bool RefToBaseVector<T>::empty() const {
0156 return holder_ ? holder_->empty() : true;
0157 }
0158
0159 template <class T>
0160 inline typename RefToBaseVector<T>::size_type RefToBaseVector<T>::size() const {
0161 return holder_ ? holder_->size() : 0;
0162 }
0163
0164 template <class T>
0165 inline void RefToBaseVector<T>::clear() {
0166 if (holder_ != nullptr)
0167 holder_->clear();
0168 }
0169
0170 template <class T>
0171 inline ProductID RefToBaseVector<T>::id() const {
0172 return holder_ ? holder_->id() : ProductID();
0173 }
0174
0175 template <class T>
0176 inline EDProductGetter const* RefToBaseVector<T>::productGetter() const {
0177 return holder_ ? holder_->productGetter() : nullptr;
0178 }
0179
0180 template <class T>
0181 inline typename RefToBaseVector<T>::const_iterator RefToBaseVector<T>::begin() const {
0182 return holder_ ? holder_->begin() : const_iterator();
0183 }
0184
0185 template <class T>
0186 inline typename RefToBaseVector<T>::const_iterator RefToBaseVector<T>::end() const {
0187 return holder_ ? holder_->end() : const_iterator();
0188 }
0189
0190 template <typename T>
0191 void RefToBaseVector<T>::fillView(std::vector<void const*>& pointers, FillViewHelperVector& helpers) const {
0192 pointers.reserve(this->size());
0193 helpers.reserve(this->size());
0194 for (const_iterator i = begin(), e = end(); i != e; ++i) {
0195 RefToBase<T> ref = *i;
0196 member_type const* address = ref.isNull() ? nullptr : &*ref;
0197 pointers.push_back(address);
0198 helpers.push_back(FillViewHelperVector::value_type(ref.id(), ref.key()));
0199 }
0200 }
0201
0202
0203 template <typename T>
0204 inline void fillView(RefToBaseVector<T> const& obj,
0205 ProductID const&,
0206 std::vector<void const*>& pointers,
0207 FillViewHelperVector& helpers) {
0208 obj.fillView(pointers, helpers);
0209 }
0210
0211 template <typename T>
0212 struct has_fillView<RefToBaseVector<T> > {
0213 static bool const value = true;
0214 };
0215
0216 template <typename T>
0217 void RefToBaseVector<T>::push_back(const RefToBase<T>& r) {
0218 if (holder_ == nullptr) {
0219 std::unique_ptr<reftobase::BaseVectorHolder<T> > p = r.holder_->makeVectorHolder();
0220 holder_ = p.release();
0221 }
0222 holder_->push_back(r.holder_);
0223 }
0224
0225 template <typename T>
0226 std::unique_ptr<reftobase::RefVectorHolderBase> RefToBaseVector<T>::vectorHolder() const {
0227 return holder_ ? holder_->vectorHolder() : std::unique_ptr<reftobase::RefVectorHolderBase>();
0228 }
0229 }
0230
0231 #include "DataFormats/Common/interface/RefVector.h"
0232 #include "DataFormats/Common/interface/Handle.h"
0233
0234 namespace edm {
0235
0236 template <typename T>
0237 template <typename C>
0238 RefToBaseVector<T>::RefToBaseVector(const Handle<C>& h)
0239 : holder_(new reftobase::VectorHolder<
0240 T,
0241 RefVector<C, typename refhelper::ValueTrait<C>::value, typename refhelper::FindTrait<C, T>::value> >(
0242 h.id())) {}
0243
0244 }
0245 #endif