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
0030
0031 virtual void clear() = 0;
0032 virtual ProductID id() const = 0;
0033 virtual EDProductGetter const* productGetter() const = 0;
0034 void swap(BaseVectorHolder&) {}
0035
0036
0037
0038
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
0171
0172 virtual bool isAvailable() const = 0;
0173
0174
0175 CMS_CLASS_VERSION(3)
0176 };
0177
0178
0179 template <typename T>
0180 inline void swap(BaseVectorHolder<T>& lhs, BaseVectorHolder<T>& rhs) {
0181 lhs.swap(rhs);
0182 }
0183 }
0184 }
0185
0186 #endif