Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 10:49:26

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       typedef size_t size_type;
0017       typedef RefHolderBase value_type;
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         typedef ptrdiff_t difference_type;
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 : public std::iterator<std::random_access_iterator_tag, void*> {
0048         typedef std::shared_ptr<RefHolderBase> value_type;
0049         typedef std::ptrdiff_t difference_type;
0050         const_iterator() : i(nullptr) {}
0051         const_iterator(const_iterator_imp* it) : i(it) {}
0052         const_iterator(const_iterator const& it) : i(it.isValid() ? it.i->clone() : nullptr) {}
0053         ~const_iterator() { delete i; }
0054         const_iterator& operator=(const_iterator const& it) {
0055           if (isInvalid())
0056             i = it.i;
0057           else
0058             i->assign(it.i);
0059           return *this;
0060         }
0061         const_iterator& operator++() {
0062           if (isInvalid())
0063             Exception::throwThis(errors::InvalidReference,
0064                                  "Trying to increment an inavlid RefToBaseVector<T>::const_iterator\n");
0065           i->increase();
0066           return *this;
0067         }
0068         const_iterator operator++(int) {
0069           if (isInvalid())
0070             Exception::throwThis(errors::InvalidReference,
0071                                  "Trying to postincrement an inavlid RefToBaseVector<T>::const_iterator\n");
0072           const_iterator ci = *this;
0073           i->increase();
0074           return ci;
0075         }
0076         const_iterator& operator--() {
0077           if (isInvalid())
0078             Exception::throwThis(errors::InvalidReference,
0079                                  "Trying to decrement an inavlid RefToBaseVector<T>::const_iterator\n");
0080           i->decrease();
0081           return *this;
0082         }
0083         const_iterator operator--(int) {
0084           if (isInvalid())
0085             Exception::throwThis(errors::InvalidReference,
0086                                  "Trying to postdecrement an inavlid RefToBaseVector<T>::const_iterator\n");
0087           const_iterator ci = *this;
0088           i->decrease();
0089           return ci;
0090         }
0091         difference_type operator-(const_iterator const& o) const {
0092           if (isInvalid() && o.isInvalid())
0093             return 0;
0094           if (isInvalid() || o.isInvalid())
0095             Exception::throwThis(errors::InvalidReference,
0096                                  "Trying to compute difference with an inavlid RefToBaseVector<T>::const_iterator\n");
0097           return i->difference(o.i);
0098         }
0099         const_iterator operator+(difference_type n) const {
0100           if (isInvalid())
0101             Exception::throwThis(errors::InvalidReference,
0102                                  "Trying to compute sum with an inavlid RefToBaseVector<T>::const_iterator\n");
0103           const_iterator_imp* ii = i->clone();
0104           ii->increase(n);
0105           return const_iterator(ii);
0106         }
0107         const_iterator operator-(difference_type n) const {
0108           if (isInvalid())
0109             Exception::throwThis(errors::InvalidReference,
0110                                  "Trying to compute difference with an inavlid RefToBaseVector<T>::const_iterator\n");
0111           const_iterator_imp* ii = i->clone();
0112           ii->decrease(n);
0113           return const_iterator(ii);
0114         }
0115         bool operator<(const_iterator const& o) const {
0116           if (isInvalid() && o.isInvalid())
0117             return false;
0118           if (isInvalid() || o.isInvalid())
0119             Exception::throwThis(errors::InvalidReference,
0120                                  "Trying to compute < operator with an inavlid RefToBaseVector<T>::const_iterator\n");
0121           return i->less_than(o.i);
0122         }
0123         bool operator==(const const_iterator& ci) const {
0124           if (isInvalid() && ci.isInvalid())
0125             return true;
0126           if (isInvalid() || ci.isInvalid())
0127             return false;
0128           return i->equal_to(ci.i);
0129         }
0130         bool operator!=(const const_iterator& ci) const {
0131           if (isInvalid() && ci.isInvalid())
0132             return false;
0133           if (isInvalid() || ci.isInvalid())
0134             return true;
0135           return !i->equal_to(ci.i);
0136         }
0137         value_type operator*() const {
0138           if (isInvalid())
0139             Exception::throwThis(errors::InvalidReference,
0140                                  "Trying to dereference an inavlid RefToBaseVector<T>::const_iterator\n");
0141           return i->deref();
0142         }
0143         const_iterator& operator-=(difference_type d) {
0144           if (isInvalid())
0145             Exception::throwThis(errors::InvalidReference,
0146                                  "Trying to decrement an inavlid RefToBaseVector<T>::const_iterator\n");
0147           i->decrease(d);
0148           return *this;
0149         }
0150         const_iterator& operator+=(difference_type d) {
0151           if (isInvalid())
0152             Exception::throwThis(errors::InvalidReference,
0153                                  "Trying to increment an inavlid RefToBaseVector<T>::const_iterator\n");
0154           i->increase(d);
0155           return *this;
0156         }
0157         bool isValid() const { return i != nullptr; }
0158         bool isInvalid() const { return i == nullptr; }
0159 
0160       private:
0161         const_iterator_imp* i;
0162       };
0163 
0164       virtual const_iterator begin() const = 0;
0165       virtual const_iterator end() const = 0;
0166       template <typename T>
0167       RefToBase<T> getRef(size_t idx) const;
0168       virtual size_t keyForIndex(size_t idx) const = 0;
0169 
0170       /// Checks if product collection is in memory or available
0171       /// in the Event. No type checking is done.
0172       virtual bool isAvailable() const = 0;
0173 
0174     private:
0175       virtual std::shared_ptr<reftobase::RefHolderBase> refBase(size_t idx) const = 0;
0176     };
0177 
0178     template <typename T>
0179     RefToBase<T> RefVectorHolderBase::getRef(size_t idx) const {
0180       std::shared_ptr<reftobase::RefHolderBase> rb = refBase(idx);
0181       return RefToBase<T>(rb);
0182     }
0183 
0184     // Free swap function
0185     inline void swap(RefVectorHolderBase& lhs, RefVectorHolderBase& rhs) { lhs.swap(rhs); }
0186   }  // namespace reftobase
0187 }  // namespace edm
0188 
0189 #endif