Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:53:04

0001 #ifndef DataFormats_Common_VectorHolder_h
0002 #define DataFormats_Common_VectorHolder_h
0003 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
0004 #include "DataFormats/Common/interface/BaseVectorHolder.h"
0005 #include "DataFormats/Common/interface/Holder.h"
0006 #include <memory>
0007 
0008 namespace edm {
0009   namespace reftobase {
0010 
0011     class RefVectorHolderBase;
0012 
0013     template <class T, class REFV>
0014     class VectorHolder : public BaseVectorHolder<T> {
0015     public:
0016       typedef BaseVectorHolder<T> base_type;
0017       typedef typename base_type::size_type size_type;
0018       typedef typename base_type::element_type element_type;
0019       typedef typename base_type::base_ref_type base_ref_type;
0020       typedef typename base_type::const_iterator const_iterator;
0021       typedef REFV ref_vector_type;
0022 
0023       VectorHolder() : base_type() {}
0024       VectorHolder(VectorHolder const& rh) : base_type(rh), refVector_(rh.refVector_) {}
0025 #if defined(__GXX_EXPERIMENTAL_CXX0X__)
0026       VectorHolder(VectorHolder&& rh) noexcept : base_type(std::forward(rh)), refVector_(std::move(rh.refVector_)) {}
0027 #endif
0028 
0029       explicit VectorHolder(const ref_vector_type& iRefVector) : base_type(), refVector_(iRefVector) {}
0030       explicit VectorHolder(const ProductID& iId) : base_type(), refVector_(iId) {}
0031       ~VectorHolder() noexcept override {}
0032       base_type* clone() const override { return new VectorHolder(*this); }
0033       base_type* cloneEmpty() const override { return new VectorHolder(refVector_.id()); }
0034       base_ref_type const at(size_type idx) const override { return base_ref_type(refVector_.at(idx)); }
0035       bool empty() const override { return refVector_.empty(); }
0036       size_type size() const override { return refVector_.size(); }
0037       //size_type capacity() const { return refVector_.capacity(); }
0038       //void reserve(size_type n) { refVector_.reserve(n); }
0039       void clear() override { refVector_.clear(); }
0040       ProductID id() const override { return refVector_.id(); }
0041       EDProductGetter const* productGetter() const override { return refVector_.productGetter(); }
0042       void swap(VectorHolder& other) noexcept {
0043         this->BaseVectorHolder<T>::swap(other);
0044         refVector_.swap(other.refVector_);
0045       }
0046       VectorHolder& operator=(VectorHolder const& rhs) {
0047         VectorHolder temp(rhs);
0048         this->swap(temp);
0049         return *this;
0050       }
0051 #if defined(__GXX_EXPERIMENTAL_CXX0X__)
0052       VectorHolder& operator=(VectorHolder&& rhs) noexcept {
0053         base_type::operator=(std::forward(rhs));
0054         refVector_ = std::move(rhs.refVector_);
0055         return *this;
0056       }
0057 #endif
0058 
0059       const_iterator begin() const override {
0060         return const_iterator(new const_iterator_imp_specific(refVector_.begin()));
0061       }
0062       const_iterator end() const override { return const_iterator(new const_iterator_imp_specific(refVector_.end())); }
0063       void push_back(const BaseHolder<T>* r) override {
0064         typedef Holder<T, typename REFV::value_type> holder_type;
0065         const holder_type* h = dynamic_cast<const holder_type*>(r);
0066         if (h == nullptr)
0067           Exception::throwThis(errors::InvalidReference,
0068                                "In VectorHolder<T, REFV> trying to push_back wrong reference type");
0069         refVector_.push_back(h->getRef());
0070       }
0071       std::unique_ptr<RefVectorHolderBase> vectorHolder() const override {
0072         return std::unique_ptr<RefVectorHolderBase>(new RefVectorHolder<REFV>(refVector_));
0073       }
0074 
0075       /// Checks if product collection is in memory or available
0076       /// in the Event. No type checking is done.
0077       bool isAvailable() const override { return refVector_.isAvailable(); }
0078 
0079       //Used by ROOT storage
0080       CMS_CLASS_VERSION(10)
0081 
0082     private:
0083       typedef typename base_type::const_iterator_imp const_iterator_imp;
0084 
0085       ref_vector_type refVector_;
0086 
0087       // the following structure is public
0088       // to allow dictionary to compile
0089     public:
0090       struct const_iterator_imp_specific : public const_iterator_imp {
0091         typedef ptrdiff_t difference_type;
0092         const_iterator_imp_specific() {}
0093         explicit const_iterator_imp_specific(const typename REFV::const_iterator& it) : i(it) {}
0094         ~const_iterator_imp_specific() override {}
0095         const_iterator_imp_specific* clone() const override { return new const_iterator_imp_specific(i); }
0096         void increase() override { ++i; }
0097         void decrease() override { --i; }
0098         void increase(difference_type d) override { i += d; }
0099         void decrease(difference_type d) override { i -= d; }
0100         bool equal_to(const const_iterator_imp* o) const override { return i == dc(o); }
0101         bool less_than(const const_iterator_imp* o) const override { return i < dc(o); }
0102         void assign(const const_iterator_imp* o) override { i = dc(o); }
0103         base_ref_type deref() const override { return base_ref_type(*i); }
0104         difference_type difference(const const_iterator_imp* o) const override { return i - dc(o); }
0105 
0106       private:
0107         const typename ref_vector_type::const_iterator& dc(const const_iterator_imp* o) const {
0108           if (o == nullptr)
0109             Exception::throwThis(errors::InvalidReference,
0110                                  "In RefToBaseVector<T> trying to dereference a null pointer");
0111           const const_iterator_imp_specific* oo = dynamic_cast<const const_iterator_imp_specific*>(o);
0112           if (oo == nullptr)
0113             Exception::throwThis(errors::InvalidReference,
0114                                  "In RefToBaseVector<T> trying to cast iterator to wrong type ");
0115           return oo->i;
0116         }
0117         typename ref_vector_type::const_iterator i;
0118       };
0119     };
0120 
0121     // Free swap function
0122     template <typename T, typename REFV>
0123     inline void swap(VectorHolder<T, REFV>& lhs, VectorHolder<T, REFV>& rhs) noexcept {
0124       lhs.swap(rhs);
0125     }
0126   }  // namespace reftobase
0127 }  // namespace edm
0128 
0129 #endif