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&) {}
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
0029
0030
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
0174
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
0188 inline void swap(RefVectorHolderBase& lhs, RefVectorHolderBase& rhs) { lhs.swap(rhs); }
0189 }
0190 }
0191
0192 #endif