Back to home page

Project CMSSW displayed by LXR

 
 

    


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

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