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