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&) {}
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 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
0171
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
0185 inline void swap(RefVectorHolderBase& lhs, RefVectorHolderBase& rhs) { lhs.swap(rhs); }
0186 }
0187 }
0188
0189 #endif