File indexing completed on 2024-04-06 12:03:52
0001 #ifndef DataFormats_Common_IndirectVectorHolder_h
0002 #define DataFormats_Common_IndirectVectorHolder_h
0003 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
0004 #include "DataFormats/Common/interface/BaseVectorHolder.h"
0005 #include "DataFormats/Common/interface/RefVectorHolderBase.h"
0006 #include "DataFormats/Common/interface/IndirectHolder.h"
0007 #include <memory>
0008
0009 namespace edm {
0010 namespace reftobase {
0011
0012 template <typename T>
0013 class IndirectVectorHolder : public BaseVectorHolder<T> {
0014 public:
0015 typedef BaseVectorHolder<T> base_type;
0016 typedef typename base_type::size_type size_type;
0017 typedef typename base_type::element_type element_type;
0018 typedef typename base_type::base_ref_type base_ref_type;
0019 typedef typename base_type::const_iterator const_iterator;
0020
0021 IndirectVectorHolder();
0022 IndirectVectorHolder(const IndirectVectorHolder& other);
0023 IndirectVectorHolder(std::shared_ptr<RefVectorHolderBase> p);
0024 IndirectVectorHolder(RefVectorHolderBase* p);
0025 ~IndirectVectorHolder() override;
0026 IndirectVectorHolder& operator=(IndirectVectorHolder const& rhs);
0027 void swap(IndirectVectorHolder& other);
0028 BaseVectorHolder<T>* clone() const override;
0029 BaseVectorHolder<T>* cloneEmpty() const override;
0030 ProductID id() const override;
0031 EDProductGetter const* productGetter() const override;
0032 bool empty() const override;
0033 size_type size() const override;
0034 void clear() override;
0035 base_ref_type const at(size_type idx) const override;
0036 std::unique_ptr<reftobase::RefVectorHolderBase> vectorHolder() const override {
0037 return std::unique_ptr<reftobase::RefVectorHolderBase>(helper_->clone());
0038 }
0039 void push_back(const BaseHolder<T>* r) override {
0040 typedef IndirectHolder<T> holder_type;
0041 const holder_type* h = dynamic_cast<const holder_type*>(r);
0042 if (h == nullptr)
0043 Exception::throwThis(errors::InvalidReference,
0044 "In IndirectHolder<T> trying to push_back wrong reference type");
0045 helper_->push_back(h->helper_);
0046 }
0047
0048
0049
0050 bool isAvailable() const override { return helper_->isAvailable(); }
0051
0052
0053 CMS_CLASS_VERSION(10)
0054
0055 private:
0056 typedef typename base_type::const_iterator_imp const_iterator_imp;
0057 RefVectorHolderBase* helper_;
0058
0059 public:
0060 struct const_iterator_imp_specific : public const_iterator_imp {
0061 typedef ptrdiff_t difference_type;
0062 const_iterator_imp_specific() {}
0063 explicit const_iterator_imp_specific(const typename RefVectorHolderBase::const_iterator& it) : i(it) {}
0064 ~const_iterator_imp_specific() override {}
0065 const_iterator_imp_specific* clone() const override { return new const_iterator_imp_specific(i); }
0066 void increase() override { ++i; }
0067 void decrease() override { --i; }
0068 void increase(difference_type d) override { i += d; }
0069 void decrease(difference_type d) override { i -= d; }
0070 bool equal_to(const const_iterator_imp* o) const override { return i == dc(o); }
0071 bool less_than(const const_iterator_imp* o) const override { return i < dc(o); }
0072 void assign(const const_iterator_imp* o) override { i = dc(o); }
0073 base_ref_type deref() const override { return base_ref_type(*i); }
0074 difference_type difference(const const_iterator_imp* o) const override { return i - dc(o); }
0075
0076 private:
0077 const typename RefVectorHolderBase::const_iterator& dc(const const_iterator_imp* o) const {
0078 if (o == nullptr) {
0079 Exception::throwThis(edm::errors::InvalidReference,
0080 "In IndirectVectorHolder trying to dereference a null pointer");
0081 }
0082 const const_iterator_imp_specific* oo = dynamic_cast<const const_iterator_imp_specific*>(o);
0083 if (oo == nullptr) {
0084 Exception::throwThis(errors::InvalidReference,
0085 "In IndirectVectorHolder trying to cast iterator to wrong type ");
0086 }
0087 return oo->i;
0088 }
0089 typename RefVectorHolderBase::const_iterator i;
0090 };
0091
0092 const_iterator begin() const override {
0093 return const_iterator(new const_iterator_imp_specific(helper_->begin()));
0094 }
0095 const_iterator end() const override { return const_iterator(new const_iterator_imp_specific(helper_->end())); }
0096 };
0097
0098 template <typename T>
0099 IndirectVectorHolder<T>::IndirectVectorHolder() : BaseVectorHolder<T>(), helper_(nullptr) {}
0100
0101 template <typename T>
0102 IndirectVectorHolder<T>::IndirectVectorHolder(std::shared_ptr<RefVectorHolderBase> p)
0103 : BaseVectorHolder<T>(), helper_(p->clone()) {}
0104
0105 template <typename T>
0106 IndirectVectorHolder<T>::IndirectVectorHolder(RefVectorHolderBase* p) : BaseVectorHolder<T>(), helper_(p) {}
0107
0108 template <typename T>
0109 IndirectVectorHolder<T>::IndirectVectorHolder(const IndirectVectorHolder& other)
0110 : BaseVectorHolder<T>(), helper_(other.helper_->clone()) {}
0111
0112 template <typename T>
0113 IndirectVectorHolder<T>::~IndirectVectorHolder() {
0114 delete helper_;
0115 }
0116
0117 template <typename T>
0118 inline void IndirectVectorHolder<T>::swap(IndirectVectorHolder& other) {
0119 this->BaseVectorHolder<T>::swap(other);
0120 std::swap(helper_, other.helper_);
0121 }
0122
0123 template <typename T>
0124 inline IndirectVectorHolder<T>& IndirectVectorHolder<T>::operator=(IndirectVectorHolder const& rhs) {
0125 IndirectVectorHolder temp(rhs);
0126 swap(temp);
0127 return *this;
0128 }
0129
0130 template <typename T>
0131 BaseVectorHolder<T>* IndirectVectorHolder<T>::clone() const {
0132 return new IndirectVectorHolder<T>(*this);
0133 }
0134
0135 template <typename T>
0136 BaseVectorHolder<T>* IndirectVectorHolder<T>::cloneEmpty() const {
0137 return new IndirectVectorHolder<T>(helper_->cloneEmpty());
0138 }
0139
0140 template <typename T>
0141 ProductID IndirectVectorHolder<T>::id() const {
0142 return helper_->id();
0143 }
0144
0145 template <typename T>
0146 EDProductGetter const* IndirectVectorHolder<T>::productGetter() const {
0147 return helper_->productGetter();
0148 }
0149
0150 template <typename T>
0151 bool IndirectVectorHolder<T>::empty() const {
0152 return helper_->empty();
0153 }
0154
0155 template <typename T>
0156 typename IndirectVectorHolder<T>::size_type IndirectVectorHolder<T>::size() const {
0157 return helper_->size();
0158 }
0159
0160 template <typename T>
0161 void IndirectVectorHolder<T>::clear() {
0162 return helper_->clear();
0163 }
0164
0165 template <typename T>
0166 typename IndirectVectorHolder<T>::base_ref_type const IndirectVectorHolder<T>::at(size_type idx) const {
0167 return helper_ ? helper_->template getRef<T>(idx) : typename IndirectVectorHolder<T>::base_ref_type();
0168 }
0169
0170
0171 template <typename T>
0172 inline void swap(IndirectVectorHolder<T>& lhs, IndirectVectorHolder<T>& rhs) {
0173 lhs.swap(rhs);
0174 }
0175 }
0176 }
0177
0178 #endif