Back to home page

Project CMSSW displayed by LXR

 
 

    


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       //Needed for ROOT storage
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       /// Checks if product collection is in memory or available
0078       /// in the Event. No type checking is done.
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     // implementations for RefVectorHolder<REFV>
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     // Free swap function
0148     template <typename REFV>
0149     inline void swap(RefVectorHolder<REFV>& lhs, RefVectorHolder<REFV>& rhs) {
0150       lhs.swap(rhs);
0151     }
0152   }  // namespace reftobase
0153 }  // namespace edm
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   }  // namespace reftobase
0184 }  // namespace edm
0185 
0186 #endif