File indexing completed on 2021-02-14 12:53:03
0001 #ifndef DataFormats_Common_RefVectorHolder_h
0002 #define DataFormats_Common_RefVectorHolder_h
0003
0004 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
0005 #include "DataFormats/Common/interface/RefVectorHolderBase.h"
0006 #include "FWCore/Utilities/interface/EDMException.h"
0007 #include "DataFormats/Provenance/interface/ProductID.h"
0008
0009 namespace edm {
0010 namespace reftobase {
0011 class RefHolderBase;
0012 template <typename REF>
0013 class RefHolder;
0014
0015 template <typename REFV>
0016 class RefVectorHolder : public RefVectorHolderBase {
0017 public:
0018 RefVectorHolder() : RefVectorHolderBase() {}
0019 RefVectorHolder(REFV const& refs) : RefVectorHolderBase(), refs_(refs) {}
0020 explicit RefVectorHolder(ProductID const& iId) : RefVectorHolderBase(), refs_(iId) {}
0021 ~RefVectorHolder() override {}
0022 void swap(RefVectorHolder& other);
0023 RefVectorHolder& operator=(RefVectorHolder const& rhs);
0024 bool empty() const override;
0025 size_type size() const override;
0026 void clear() override;
0027 void push_back(RefHolderBase const* r) override;
0028 void reserve(size_type n) override;
0029 ProductID id() const override;
0030 EDProductGetter const* productGetter() const override;
0031 RefVectorHolder<REFV>* clone() const override;
0032 RefVectorHolder<REFV>* cloneEmpty() const override;
0033 void setRefs(REFV const& refs);
0034 size_t keyForIndex(size_t idx) const override;
0035
0036
0037 CMS_CLASS_VERSION(10)
0038
0039 private:
0040 typedef typename RefVectorHolderBase::const_iterator_imp const_iterator_imp;
0041
0042 public:
0043 struct const_iterator_imp_specific : public const_iterator_imp {
0044 typedef ptrdiff_t difference_type;
0045 const_iterator_imp_specific() {}
0046 explicit const_iterator_imp_specific(typename REFV::const_iterator const& it) : i(it) {}
0047 ~const_iterator_imp_specific() override {}
0048 const_iterator_imp_specific* clone() const override { return new const_iterator_imp_specific(i); }
0049 void increase() override { ++i; }
0050 void decrease() override { --i; }
0051 void increase(difference_type d) override { i += d; }
0052 void decrease(difference_type d) override { i -= d; }
0053 bool equal_to(const_iterator_imp const* o) const override { return i == dc(o); }
0054 bool less_than(const_iterator_imp const* o) const override { return i < dc(o); }
0055 void assign(const_iterator_imp const* o) override { i = dc(o); }
0056 std::shared_ptr<RefHolderBase> deref() const override;
0057 difference_type difference(const_iterator_imp const* o) const override { return i - dc(o); }
0058
0059 private:
0060 typename REFV::const_iterator const& dc(const_iterator_imp const* o) const {
0061 if (o == nullptr) {
0062 Exception::throwThis(errors::InvalidReference, "In RefVectorHolder trying to dereference a null pointer\n");
0063 }
0064 const_iterator_imp_specific const* oo = dynamic_cast<const_iterator_imp_specific const*>(o);
0065 if (oo == nullptr) {
0066 Exception::throwThis(errors::InvalidReference,
0067 "In RefVectorHolder trying to cast iterator to wrong type\n");
0068 }
0069 return oo->i;
0070 }
0071 typename REFV::const_iterator i;
0072 };
0073
0074 typedef typename RefVectorHolderBase::const_iterator const_iterator;
0075
0076 const_iterator begin() const override { return const_iterator(new const_iterator_imp_specific(refs_.begin())); }
0077 const_iterator end() const override { return const_iterator(new const_iterator_imp_specific(refs_.end())); }
0078
0079
0080
0081 bool isAvailable() const override { return refs_.isAvailable(); }
0082
0083 private:
0084 std::shared_ptr<reftobase::RefHolderBase> refBase(size_t idx) const override;
0085 REFV refs_;
0086 };
0087
0088
0089
0090
0091
0092 template <typename REFV>
0093 inline void RefVectorHolder<REFV>::swap(RefVectorHolder<REFV>& other) {
0094 this->RefVectorHolderBase::swap(other);
0095 refs_.swap(other.refs_);
0096 }
0097
0098 template <typename REFV>
0099 inline RefVectorHolder<REFV>& RefVectorHolder<REFV>::operator=(RefVectorHolder<REFV> const& rhs) {
0100 RefVectorHolder<REFV> temp(rhs);
0101 this->swap(temp);
0102 return *this;
0103 }
0104
0105 template <typename REFV>
0106 inline bool RefVectorHolder<REFV>::empty() const {
0107 return refs_.empty();
0108 }
0109
0110 template <typename REFV>
0111 inline typename RefVectorHolder<REFV>::size_type RefVectorHolder<REFV>::size() const {
0112 return refs_.size();
0113 }
0114
0115 template <typename REFV>
0116 inline void RefVectorHolder<REFV>::clear() {
0117 return refs_.clear();
0118 }
0119
0120 template <typename REFV>
0121 inline void RefVectorHolder<REFV>::reserve(size_type n) {
0122 typename REFV::size_type s = n;
0123 refs_.reserve(s);
0124 }
0125
0126 template <typename REFV>
0127 inline ProductID RefVectorHolder<REFV>::id() const {
0128 return refs_.id();
0129 }
0130
0131 template <typename REFV>
0132 inline EDProductGetter const* RefVectorHolder<REFV>::productGetter() const {
0133 return refs_.productGetter();
0134 }
0135
0136 template <typename REFV>
0137 inline RefVectorHolder<REFV>* RefVectorHolder<REFV>::clone() const {
0138 return new RefVectorHolder<REFV>(*this);
0139 }
0140
0141 template <typename REFV>
0142 inline RefVectorHolder<REFV>* RefVectorHolder<REFV>::cloneEmpty() const {
0143 return new RefVectorHolder<REFV>(id());
0144 }
0145
0146 template <typename REFV>
0147 inline void RefVectorHolder<REFV>::setRefs(REFV const& refs) {
0148 refs_ = refs;
0149 }
0150
0151 template <typename REFV>
0152 inline size_t RefVectorHolder<REFV>::keyForIndex(size_t idx) const {
0153 return refs_[idx].key();
0154 }
0155
0156
0157 template <typename REFV>
0158 inline void swap(RefVectorHolder<REFV>& lhs, RefVectorHolder<REFV>& rhs) {
0159 lhs.swap(rhs);
0160 }
0161 }
0162 }
0163
0164 #include "DataFormats/Common/interface/RefHolder.h"
0165
0166 namespace edm {
0167 namespace reftobase {
0168
0169 template <typename REFV>
0170 void RefVectorHolder<REFV>::push_back(RefHolderBase const* h) {
0171 typedef typename REFV::value_type REF;
0172 RefHolder<REF> const* rh = dynamic_cast<RefHolder<REF> const*>(h);
0173 if (rh == nullptr) {
0174 Exception::throwThis(errors::InvalidReference,
0175 "RefVectorHolder: attempting to cast a RefHolderBase "
0176 "to an invalid type.\nExpected: ",
0177 typeid(REF).name(),
0178 "\n");
0179 }
0180 refs_.push_back(rh->getRef());
0181 }
0182
0183 template <typename REFV>
0184 std::shared_ptr<RefHolderBase> RefVectorHolder<REFV>::refBase(size_t idx) const {
0185 return std::shared_ptr<RefHolderBase>(std::make_shared<RefHolder<typename REFV::value_type> >(refs_[idx]));
0186 }
0187
0188 template <typename REFV>
0189 std::shared_ptr<RefHolderBase> RefVectorHolder<REFV>::const_iterator_imp_specific::deref() const {
0190 return std::shared_ptr<RefHolderBase>(std::make_shared<RefHolder<typename REFV::value_type> >(*i));
0191 }
0192 }
0193 }
0194
0195 #endif