File indexing completed on 2021-02-14 12:53:04
0001 #ifndef DataFormats_Common_View_h
0002 #define DataFormats_Common_View_h
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include "DataFormats/Common/interface/Ptr.h"
0019 #include "DataFormats/Common/interface/RefToBase.h"
0020 #include "DataFormats/Common/interface/IndirectHolder.h"
0021 #include "DataFormats/Common/interface/RefHolder_.h"
0022 #include "boost/iterator/indirect_iterator.hpp"
0023
0024 #include <vector>
0025 #include <memory>
0026 #include <algorithm>
0027 #include <iterator>
0028 #include <utility>
0029 #include <cassert>
0030
0031 namespace edm {
0032 class EDProductGetter;
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043 class ViewBase {
0044 public:
0045 virtual ~ViewBase();
0046 std::unique_ptr<ViewBase> clone() const;
0047
0048 protected:
0049 ViewBase();
0050 ViewBase(ViewBase const&);
0051 ViewBase& operator=(ViewBase const&);
0052 virtual std::unique_ptr<ViewBase> doClone() const = 0;
0053 void swap(ViewBase&) {}
0054 };
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073 template <typename T>
0074 class View : public ViewBase {
0075 typedef std::vector<T const*> seq_t;
0076
0077 public:
0078 typedef T const* pointer;
0079 typedef T const* const_pointer;
0080
0081 typedef T const& reference;
0082 typedef T const& const_reference;
0083
0084 typedef T value_type;
0085
0086 typedef boost::indirect_iterator<typename seq_t::const_iterator> const_iterator;
0087
0088
0089
0090 typedef unsigned int size_type;
0091 typedef typename seq_t::difference_type difference_type;
0092
0093 typedef boost::indirect_iterator<typename seq_t::const_reverse_iterator> const_reverse_iterator;
0094
0095
0096
0097
0098 View();
0099
0100
0101
0102 View(std::vector<void const*> const& pointers, FillViewHelperVector const& helpers, EDProductGetter const* getter);
0103
0104 ~View() override;
0105
0106 void swap(View& other);
0107
0108 View& operator=(View const& rhs);
0109
0110 size_type capacity() const;
0111
0112
0113
0114
0115 const_iterator begin() const;
0116 const_iterator end() const;
0117
0118 const_reverse_iterator rbegin() const;
0119 const_reverse_iterator rend() const;
0120
0121 size_type size() const;
0122 size_type max_size() const;
0123 bool empty() const;
0124 const_reference at(size_type pos) const;
0125 const_reference operator[](size_type pos) const;
0126 RefToBase<value_type> refAt(size_type i) const;
0127 Ptr<value_type> ptrAt(size_type i) const;
0128 std::vector<Ptr<value_type>> const& ptrs() const;
0129
0130 const_reference front() const;
0131 const_reference back() const;
0132
0133
0134
0135
0136
0137 static void fill_from_range(T* first, T* last, View& output);
0138
0139 private:
0140 seq_t items_;
0141 std::vector<Ptr<value_type>> vPtrs_;
0142 std::unique_ptr<ViewBase> doClone() const override;
0143 };
0144
0145
0146 template <typename T>
0147 bool operator==(View<T> const&, View<T> const&);
0148 template <typename T>
0149 bool operator!=(View<T> const&, View<T> const&);
0150 template <typename T>
0151 bool operator<(View<T> const&, View<T> const&);
0152 template <typename T>
0153 bool operator<=(View<T> const&, View<T> const&);
0154 template <typename T>
0155 bool operator>(View<T> const&, View<T> const&);
0156 template <typename T>
0157 bool operator>=(View<T> const&, View<T> const&);
0158
0159
0160
0161
0162
0163 template <typename T>
0164 inline View<T>::View() : items_(), vPtrs_() {}
0165
0166 template <typename T>
0167 View<T>::View(std::vector<void const*> const& pointers,
0168 FillViewHelperVector const& helpers,
0169 EDProductGetter const* getter)
0170 : items_(), vPtrs_() {
0171 size_type numElements = pointers.size();
0172
0173
0174
0175
0176 assert(numElements == helpers.size());
0177
0178 items_.reserve(numElements);
0179 vPtrs_.reserve(numElements);
0180 for (std::vector<void const*>::size_type i = 0; i < pointers.size(); ++i) {
0181 void const* p = pointers[i];
0182 auto const& h = helpers[i];
0183 items_.push_back(static_cast<pointer>(p));
0184 if (nullptr != p) {
0185 vPtrs_.push_back(Ptr<T>(h.first, static_cast<T const*>(p), h.second));
0186 } else if (getter != nullptr) {
0187 vPtrs_.push_back(Ptr<T>(h.first, h.second, getter));
0188 } else {
0189 vPtrs_.push_back(Ptr<T>(h.first, nullptr, h.second));
0190 }
0191 }
0192 }
0193
0194 template <typename T>
0195 View<T>::~View() {}
0196
0197 template <typename T>
0198 inline void View<T>::swap(View& other) {
0199 this->ViewBase::swap(other);
0200 items_.swap(other.items_);
0201 vPtrs_.swap(other.vPtrs_);
0202 }
0203
0204 template <typename T>
0205 inline typename View<T>::size_type View<T>::capacity() const {
0206 return items_.capacity();
0207 }
0208
0209 template <typename T>
0210 inline typename View<T>::const_iterator View<T>::begin() const {
0211 return items_.begin();
0212 }
0213
0214 template <typename T>
0215 inline typename View<T>::const_iterator View<T>::end() const {
0216 return items_.end();
0217 }
0218
0219 template <typename T>
0220 inline typename View<T>::const_reverse_iterator View<T>::rbegin() const {
0221 return items_.rbegin();
0222 }
0223
0224 template <typename T>
0225 inline typename View<T>::const_reverse_iterator View<T>::rend() const {
0226 return items_.rend();
0227 }
0228
0229 template <typename T>
0230 inline typename View<T>::size_type View<T>::size() const {
0231 return items_.size();
0232 }
0233
0234 template <typename T>
0235 inline typename View<T>::size_type View<T>::max_size() const {
0236 return items_.max_size();
0237 }
0238
0239 template <typename T>
0240 inline bool View<T>::empty() const {
0241 return items_.empty();
0242 }
0243
0244 template <typename T>
0245 inline typename View<T>::const_reference View<T>::at(size_type pos) const {
0246 return *items_.at(pos);
0247 }
0248
0249 template <typename T>
0250 inline typename View<T>::const_reference View<T>::operator[](size_type pos) const {
0251 return *items_[pos];
0252 }
0253
0254 template <typename T>
0255 inline RefToBase<T> View<T>::refAt(size_type i) const {
0256
0257
0258
0259
0260 return RefToBase<T>(std::unique_ptr<reftobase::BaseHolder<T>>{new reftobase::IndirectHolder<T>{
0261 std::unique_ptr<reftobase::RefHolder<edm::Ptr<T>>>{new reftobase::RefHolder<Ptr<T>>{ptrAt(i)}}}});
0262 }
0263
0264 template <typename T>
0265 inline Ptr<T> View<T>::ptrAt(size_type i) const {
0266 return vPtrs_[i];
0267 }
0268
0269 template <typename T>
0270 inline std::vector<Ptr<T>> const& View<T>::ptrs() const {
0271 return vPtrs_;
0272 }
0273
0274 template <typename T>
0275 inline typename View<T>::const_reference View<T>::front() const {
0276 return *items_.front();
0277 }
0278
0279 template <typename T>
0280 inline typename View<T>::const_reference View<T>::back() const {
0281 return *items_.back();
0282 }
0283
0284
0285 template <typename T>
0286 inline void View<T>::fill_from_range(T* first, T* last, View& output) {
0287 output.items_.resize(std::distance(first, last));
0288 for (typename View<T>::size_type i = 0; first != last; ++i, ++first)
0289 output.items_[i] = first;
0290 }
0291
0292 template <typename T>
0293 std::unique_ptr<ViewBase> View<T>::doClone() const {
0294 return std::unique_ptr<ViewBase>{new View(*this)};
0295 }
0296
0297 template <typename T>
0298 inline View<T>& View<T>::operator=(View<T> const& rhs) {
0299 View<T> temp(rhs);
0300 this->swap(temp);
0301 return *this;
0302 }
0303
0304 template <typename T>
0305 inline bool operator==(View<T> const& lhs, View<T> const& rhs) {
0306 return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
0307 }
0308
0309 template <typename T>
0310 inline bool operator!=(View<T> const& lhs, View<T> const& rhs) {
0311 return !(lhs == rhs);
0312 }
0313
0314 template <typename T>
0315 inline bool operator<(View<T> const& lhs, View<T> const& rhs) {
0316 return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
0317 }
0318
0319 template <typename T>
0320 inline bool operator<=(View<T> const& lhs, View<T> const& rhs) {
0321 return !(rhs < lhs);
0322 }
0323
0324 template <typename T>
0325 inline bool operator>(View<T> const& lhs, View<T> const& rhs) {
0326 return rhs < lhs;
0327 }
0328
0329 template <typename T>
0330 inline bool operator>=(View<T> const& lhs, View<T> const& rhs) {
0331 return !(lhs < rhs);
0332 }
0333
0334
0335 template <typename T>
0336 inline void swap(View<T>& lhs, View<T>& rhs) {
0337 lhs.swap(rhs);
0338 }
0339 }
0340
0341 #endif