Back to home page

Project CMSSW displayed by LXR

 
 

    


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       //Needed for ROOT storage
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       /// Checks if product collection is in memory or available
0080       /// in the Event. No type checking is done.
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     // implementations for RefVectorHolder<REFV>
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     // Free swap function
0157     template <typename REFV>
0158     inline void swap(RefVectorHolder<REFV>& lhs, RefVectorHolder<REFV>& rhs) {
0159       lhs.swap(rhs);
0160     }
0161   }  // namespace reftobase
0162 }  // namespace edm
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   }  // namespace reftobase
0193 }  // namespace edm
0194 
0195 #endif