Back to home page

Project CMSSW displayed by LXR

 
 

    


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

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