Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:03:54

0001 #ifndef DataFormats_Common_RefVectorHolderBase_h
0002 #define DataFormats_Common_RefVectorHolderBase_h
0003 
0004 #include "DataFormats/Common/interface/RefHolderBase.h"
0005 #include "FWCore/Utilities/interface/EDMException.h"
0006 #include <cstddef>
0007 #include <memory>
0008 
0009 namespace edm {
0010   template <typename T>
0011   class RefToBase;
0012   namespace reftobase {
0013     class RefVectorHolderBase {
0014     public:
0015       virtual ~RefVectorHolderBase() {}
0016       using size_type = size_t;
0017       using value_type = RefHolderBase;
0018       void swap(RefVectorHolderBase&) {}  // nothing to swap
0019       virtual bool empty() const = 0;
0020       virtual size_type size() const = 0;
0021       virtual void clear() = 0;
0022       virtual void reserve(size_type n) = 0;
0023       virtual ProductID id() const = 0;
0024       virtual EDProductGetter const* productGetter() const = 0;
0025       virtual RefVectorHolderBase* clone() const = 0;
0026       virtual RefVectorHolderBase* cloneEmpty() const = 0;
0027       virtual void push_back(RefHolderBase const* r) = 0;
0028       // the following structure is public
0029       // to allow dictionary to compile
0030       //    protected:
0031       struct const_iterator_imp {
0032         using difference_type = ptrdiff_t;
0033         const_iterator_imp() {}
0034         virtual ~const_iterator_imp() {}
0035         virtual const_iterator_imp* clone() const = 0;
0036         virtual void increase() = 0;
0037         virtual void decrease() = 0;
0038         virtual void increase(difference_type d) = 0;
0039         virtual void decrease(difference_type d) = 0;
0040         virtual bool equal_to(const_iterator_imp const*) const = 0;
0041         virtual bool less_than(const_iterator_imp const*) const = 0;
0042         virtual void assign(const_iterator_imp const*) = 0;
0043         virtual std::shared_ptr<RefHolderBase> deref() const = 0;
0044         virtual difference_type difference(const_iterator_imp const*) const = 0;
0045       };
0046 
0047       struct const_iterator {
0048         using iterator_category = std::random_access_iterator_tag;
0049         using value_type = std::shared_ptr<RefHolderBase>;
0050         using pointer = void**;
0051         using reference = void*&;
0052         using difference_type = std::ptrdiff_t;
0053         const_iterator() : i(nullptr) {}
0054         const_iterator(const_iterator_imp* it) : i(it) {}
0055         const_iterator(const_iterator const& it) : i(it.isValid() ? it.i->clone() : nullptr) {}
0056         ~const_iterator() { delete i; }
0057         const_iterator& operator=(const_iterator const& it) {
0058           if (isInvalid())
0059             i = it.i;
0060           else
0061             i->assign(it.i);
0062           return *this;
0063         }
0064         const_iterator& operator++() {
0065           if (isInvalid())
0066             Exception::throwThis(errors::InvalidReference,
0067                                  "Trying to increment an inavlid RefToBaseVector<T>::const_iterator\n");
0068           i->increase();
0069           return *this;
0070         }
0071         const_iterator operator++(int) {
0072           if (isInvalid())
0073             Exception::throwThis(errors::InvalidReference,
0074                                  "Trying to postincrement an inavlid RefToBaseVector<T>::const_iterator\n");
0075           const_iterator ci = *this;
0076           i->increase();
0077           return ci;
0078         }
0079         const_iterator& operator--() {
0080           if (isInvalid())
0081             Exception::throwThis(errors::InvalidReference,
0082                                  "Trying to decrement an inavlid RefToBaseVector<T>::const_iterator\n");
0083           i->decrease();
0084           return *this;
0085         }
0086         const_iterator operator--(int) {
0087           if (isInvalid())
0088             Exception::throwThis(errors::InvalidReference,
0089                                  "Trying to postdecrement an inavlid RefToBaseVector<T>::const_iterator\n");
0090           const_iterator ci = *this;
0091           i->decrease();
0092           return ci;
0093         }
0094         difference_type operator-(const_iterator const& o) const {
0095           if (isInvalid() && o.isInvalid())
0096             return 0;
0097           if (isInvalid() || o.isInvalid())
0098             Exception::throwThis(errors::InvalidReference,
0099                                  "Trying to compute difference with an inavlid RefToBaseVector<T>::const_iterator\n");
0100           return i->difference(o.i);
0101         }
0102         const_iterator operator+(difference_type n) const {
0103           if (isInvalid())
0104             Exception::throwThis(errors::InvalidReference,
0105                                  "Trying to compute sum with an inavlid RefToBaseVector<T>::const_iterator\n");
0106           const_iterator_imp* ii = i->clone();
0107           ii->increase(n);
0108           return const_iterator(ii);
0109         }
0110         const_iterator operator-(difference_type n) const {
0111           if (isInvalid())
0112             Exception::throwThis(errors::InvalidReference,
0113                                  "Trying to compute difference with an inavlid RefToBaseVector<T>::const_iterator\n");
0114           const_iterator_imp* ii = i->clone();
0115           ii->decrease(n);
0116           return const_iterator(ii);
0117         }
0118         bool operator<(const_iterator const& o) const {
0119           if (isInvalid() && o.isInvalid())
0120             return false;
0121           if (isInvalid() || o.isInvalid())
0122             Exception::throwThis(errors::InvalidReference,
0123                                  "Trying to compute < operator with an inavlid RefToBaseVector<T>::const_iterator\n");
0124           return i->less_than(o.i);
0125         }
0126         bool operator==(const const_iterator& ci) const {
0127           if (isInvalid() && ci.isInvalid())
0128             return true;
0129           if (isInvalid() || ci.isInvalid())
0130             return false;
0131           return i->equal_to(ci.i);
0132         }
0133         bool operator!=(const const_iterator& ci) const {
0134           if (isInvalid() && ci.isInvalid())
0135             return false;
0136           if (isInvalid() || ci.isInvalid())
0137             return true;
0138           return !i->equal_to(ci.i);
0139         }
0140         value_type operator*() const {
0141           if (isInvalid())
0142             Exception::throwThis(errors::InvalidReference,
0143                                  "Trying to dereference an inavlid RefToBaseVector<T>::const_iterator\n");
0144           return i->deref();
0145         }
0146         const_iterator& operator-=(difference_type d) {
0147           if (isInvalid())
0148             Exception::throwThis(errors::InvalidReference,
0149                                  "Trying to decrement an inavlid RefToBaseVector<T>::const_iterator\n");
0150           i->decrease(d);
0151           return *this;
0152         }
0153         const_iterator& operator+=(difference_type d) {
0154           if (isInvalid())
0155             Exception::throwThis(errors::InvalidReference,
0156                                  "Trying to increment an inavlid RefToBaseVector<T>::const_iterator\n");
0157           i->increase(d);
0158           return *this;
0159         }
0160         bool isValid() const { return i != nullptr; }
0161         bool isInvalid() const { return i == nullptr; }
0162 
0163       private:
0164         const_iterator_imp* i;
0165       };
0166 
0167       virtual const_iterator begin() const = 0;
0168       virtual const_iterator end() const = 0;
0169       template <typename T>
0170       RefToBase<T> getRef(size_t idx) const;
0171       virtual size_t keyForIndex(size_t idx) const = 0;
0172 
0173       /// Checks if product collection is in memory or available
0174       /// in the Event. No type checking is done.
0175       virtual bool isAvailable() const = 0;
0176 
0177     private:
0178       virtual std::shared_ptr<reftobase::RefHolderBase> refBase(size_t idx) const = 0;
0179     };
0180 
0181     template <typename T>
0182     RefToBase<T> RefVectorHolderBase::getRef(size_t idx) const {
0183       std::shared_ptr<reftobase::RefHolderBase> rb = refBase(idx);
0184       return RefToBase<T>(rb);
0185     }
0186 
0187     // Free swap function
0188     inline void swap(RefVectorHolderBase& lhs, RefVectorHolderBase& rhs) { lhs.swap(rhs); }
0189   }  // namespace reftobase
0190 }  // namespace edm
0191 
0192 #endif