Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:52:59

0001 #ifndef DataFormats_Common_IndirectVectorHolder_h
0002 #define DataFormats_Common_IndirectVectorHolder_h
0003 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
0004 #include "DataFormats/Common/interface/BaseVectorHolder.h"
0005 #include "DataFormats/Common/interface/RefVectorHolderBase.h"
0006 #include "DataFormats/Common/interface/IndirectHolder.h"
0007 #include <memory>
0008 
0009 namespace edm {
0010   namespace reftobase {
0011 
0012     template <typename T>
0013     class IndirectVectorHolder : public BaseVectorHolder<T> {
0014     public:
0015       typedef BaseVectorHolder<T> base_type;
0016       typedef typename base_type::size_type size_type;
0017       typedef typename base_type::element_type element_type;
0018       typedef typename base_type::base_ref_type base_ref_type;
0019       typedef typename base_type::const_iterator const_iterator;
0020 
0021       IndirectVectorHolder();
0022       IndirectVectorHolder(const IndirectVectorHolder& other);
0023       IndirectVectorHolder(std::shared_ptr<RefVectorHolderBase> p);
0024       IndirectVectorHolder(RefVectorHolderBase* p);
0025       ~IndirectVectorHolder() override;
0026       IndirectVectorHolder& operator=(IndirectVectorHolder const& rhs);
0027       void swap(IndirectVectorHolder& other);
0028       BaseVectorHolder<T>* clone() const override;
0029       BaseVectorHolder<T>* cloneEmpty() const override;
0030       ProductID id() const override;
0031       EDProductGetter const* productGetter() const override;
0032       bool empty() const override;
0033       size_type size() const override;
0034       void clear() override;
0035       base_ref_type const at(size_type idx) const override;
0036       std::unique_ptr<reftobase::RefVectorHolderBase> vectorHolder() const override {
0037         return std::unique_ptr<reftobase::RefVectorHolderBase>(helper_->clone());
0038       }
0039       void push_back(const BaseHolder<T>* r) override {
0040         typedef IndirectHolder<T> holder_type;
0041         const holder_type* h = dynamic_cast<const holder_type*>(r);
0042         if (h == nullptr)
0043           Exception::throwThis(errors::InvalidReference,
0044                                "In IndirectHolder<T> trying to push_back wrong reference type");
0045         helper_->push_back(h->helper_);
0046       }
0047 
0048       /// Checks if product collection is in memory or available
0049       /// in the Event. No type checking is done.
0050       bool isAvailable() const override { return helper_->isAvailable(); }
0051 
0052       //Used by ROOT storage
0053       CMS_CLASS_VERSION(10)
0054 
0055     private:
0056       typedef typename base_type::const_iterator_imp const_iterator_imp;
0057       RefVectorHolderBase* helper_;
0058 
0059     public:
0060       struct const_iterator_imp_specific : public const_iterator_imp {
0061         typedef ptrdiff_t difference_type;
0062         const_iterator_imp_specific() {}
0063         explicit const_iterator_imp_specific(const typename RefVectorHolderBase::const_iterator& it) : i(it) {}
0064         ~const_iterator_imp_specific() override {}
0065         const_iterator_imp_specific* clone() const override { return new const_iterator_imp_specific(i); }
0066         void increase() override { ++i; }
0067         void decrease() override { --i; }
0068         void increase(difference_type d) override { i += d; }
0069         void decrease(difference_type d) override { i -= d; }
0070         bool equal_to(const const_iterator_imp* o) const override { return i == dc(o); }
0071         bool less_than(const const_iterator_imp* o) const override { return i < dc(o); }
0072         void assign(const const_iterator_imp* o) override { i = dc(o); }
0073         base_ref_type deref() const override { return base_ref_type(*i); }
0074         difference_type difference(const const_iterator_imp* o) const override { return i - dc(o); }
0075 
0076       private:
0077         const typename RefVectorHolderBase::const_iterator& dc(const const_iterator_imp* o) const {
0078           if (o == nullptr) {
0079             Exception::throwThis(edm::errors::InvalidReference,
0080                                  "In IndirectVectorHolder trying to dereference a null pointer");
0081           }
0082           const const_iterator_imp_specific* oo = dynamic_cast<const const_iterator_imp_specific*>(o);
0083           if (oo == nullptr) {
0084             Exception::throwThis(errors::InvalidReference,
0085                                  "In IndirectVectorHolder trying to cast iterator to wrong type ");
0086           }
0087           return oo->i;
0088         }
0089         typename RefVectorHolderBase::const_iterator i;
0090       };
0091 
0092       const_iterator begin() const override {
0093         return const_iterator(new const_iterator_imp_specific(helper_->begin()));
0094       }
0095       const_iterator end() const override { return const_iterator(new const_iterator_imp_specific(helper_->end())); }
0096     };
0097 
0098     template <typename T>
0099     IndirectVectorHolder<T>::IndirectVectorHolder() : BaseVectorHolder<T>(), helper_(nullptr) {}
0100 
0101     template <typename T>
0102     IndirectVectorHolder<T>::IndirectVectorHolder(std::shared_ptr<RefVectorHolderBase> p)
0103         : BaseVectorHolder<T>(), helper_(p->clone()) {}
0104 
0105     template <typename T>
0106     IndirectVectorHolder<T>::IndirectVectorHolder(RefVectorHolderBase* p) : BaseVectorHolder<T>(), helper_(p) {}
0107 
0108     template <typename T>
0109     IndirectVectorHolder<T>::IndirectVectorHolder(const IndirectVectorHolder& other)
0110         : BaseVectorHolder<T>(), helper_(other.helper_->clone()) {}
0111 
0112     template <typename T>
0113     IndirectVectorHolder<T>::~IndirectVectorHolder() {
0114       delete helper_;
0115     }
0116 
0117     template <typename T>
0118     inline void IndirectVectorHolder<T>::swap(IndirectVectorHolder& other) {
0119       this->BaseVectorHolder<T>::swap(other);
0120       std::swap(helper_, other.helper_);
0121     }
0122 
0123     template <typename T>
0124     inline IndirectVectorHolder<T>& IndirectVectorHolder<T>::operator=(IndirectVectorHolder const& rhs) {
0125       IndirectVectorHolder temp(rhs);
0126       swap(temp);
0127       return *this;
0128     }
0129 
0130     template <typename T>
0131     BaseVectorHolder<T>* IndirectVectorHolder<T>::clone() const {
0132       return new IndirectVectorHolder<T>(*this);
0133     }
0134 
0135     template <typename T>
0136     BaseVectorHolder<T>* IndirectVectorHolder<T>::cloneEmpty() const {
0137       return new IndirectVectorHolder<T>(helper_->cloneEmpty());
0138     }
0139 
0140     template <typename T>
0141     ProductID IndirectVectorHolder<T>::id() const {
0142       return helper_->id();
0143     }
0144 
0145     template <typename T>
0146     EDProductGetter const* IndirectVectorHolder<T>::productGetter() const {
0147       return helper_->productGetter();
0148     }
0149 
0150     template <typename T>
0151     bool IndirectVectorHolder<T>::empty() const {
0152       return helper_->empty();
0153     }
0154 
0155     template <typename T>
0156     typename IndirectVectorHolder<T>::size_type IndirectVectorHolder<T>::size() const {
0157       return helper_->size();
0158     }
0159 
0160     template <typename T>
0161     void IndirectVectorHolder<T>::clear() {
0162       return helper_->clear();
0163     }
0164 
0165     template <typename T>
0166     typename IndirectVectorHolder<T>::base_ref_type const IndirectVectorHolder<T>::at(size_type idx) const {
0167       return helper_ ? helper_->template getRef<T>(idx) : typename IndirectVectorHolder<T>::base_ref_type();
0168     }
0169 
0170     // Free swap function
0171     template <typename T>
0172     inline void swap(IndirectVectorHolder<T>& lhs, IndirectVectorHolder<T>& rhs) {
0173       lhs.swap(rhs);
0174     }
0175   }  // namespace reftobase
0176 }  // namespace edm
0177 
0178 #endif