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