00001 #ifndef DataFormats_Common_OwnVector_h
00002 #define DataFormats_Common_OwnVector_h
00003
00004 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
00005 #include "DataFormats/Common/interface/ClonePolicy.h"
00006 #include "DataFormats/Common/interface/fillPtrVector.h"
00007 #include "DataFormats/Common/interface/Ref.h"
00008 #include "DataFormats/Common/interface/setPtr.h"
00009 #include "DataFormats/Common/interface/traits.h"
00010
00011 #if defined CMS_USE_DEBUGGING_ALLOCATOR
00012 #include "DataFormats/Common/interface/debugging_allocator.h"
00013 #endif
00014 #include "FWCore/Utilities/interface/EDMException.h"
00015
00016 #include <algorithm>
00017 #include <functional>
00018 #include <typeinfo>
00019 #include <vector>
00020 #include "FWCore/Utilities/interface/GCC11Compatibility.h"
00021
00022 namespace edm {
00023 class ProductID;
00024 template <typename T, typename P = ClonePolicy<T> >
00025 class OwnVector {
00026 private:
00027 #if defined(CMS_USE_DEBUGGING_ALLOCATOR)
00028 typedef std::vector<T*, debugging_allocator<T> > base;
00029 #else
00030 typedef std::vector<T*> base;
00031 #endif
00032
00033 public:
00034 typedef typename base::size_type size_type;
00035 typedef T value_type;
00036 typedef T* pointer;
00037 typedef T& reference;
00038 typedef T const& const_reference;
00039 typedef P policy_type;
00040
00041 class iterator;
00042 class const_iterator {
00043 public:
00044 typedef T value_type;
00045 typedef T* pointer;
00046 typedef T const& reference;
00047 typedef ptrdiff_t difference_type;
00048 typedef typename base::const_iterator::iterator_category iterator_category;
00049 const_iterator(typename base::const_iterator const& it) : i(it) { }
00050 const_iterator(iterator const& it) : i(it.i) { }
00051 const_iterator() {}
00052 const_iterator& operator++() { ++i; return *this; }
00053 const_iterator operator++(int) { const_iterator ci = *this; ++i; return ci; }
00054 const_iterator& operator--() { --i; return *this; }
00055 const_iterator operator--(int) { const_iterator ci = *this; --i; return ci; }
00056 difference_type operator-(const_iterator const& o) const { return i - o.i; }
00057 const_iterator operator+(difference_type n) const { return const_iterator(i + n); }
00058 const_iterator operator-(difference_type n) const { return const_iterator(i - n); }
00059 bool operator<(const_iterator const& o) const { return i < o.i; }
00060 bool operator==(const_iterator const& ci) const { return i == ci.i; }
00061 bool operator!=(const_iterator const& ci) const { return i != ci.i; }
00062 T const& operator *() const { return **i; }
00063
00064 T const* operator->() const { return & (operator*()); }
00065 const_iterator & operator +=(difference_type d) { i += d; return *this; }
00066 const_iterator & operator -=(difference_type d) { i -= d; return *this; }
00067 reference operator[](difference_type d) const { return *const_iterator(i+d); }
00068 private:
00069 typename base::const_iterator i;
00070 };
00071 class iterator {
00072 public:
00073 typedef T value_type;
00074 typedef T * pointer;
00075 typedef T & reference;
00076 typedef ptrdiff_t difference_type;
00077 typedef typename base::iterator::iterator_category iterator_category;
00078 iterator(typename base::iterator const& it) : i(it) { }
00079 iterator() {}
00080 iterator& operator++() { ++i; return *this; }
00081 iterator operator++(int) { iterator ci = *this; ++i; return ci; }
00082 iterator& operator--() { --i; return *this; }
00083 iterator operator--(int) { iterator ci = *this; --i; return ci; }
00084 difference_type operator-(iterator const& o) const { return i - o.i; }
00085 iterator operator+(difference_type n) const { return iterator(i + n); }
00086 iterator operator-(difference_type n) const { return iterator(i - n); }
00087 bool operator<(iterator const& o) const { return i < o.i; }
00088 bool operator==(iterator const& ci) const { return i == ci.i; }
00089 bool operator!=(iterator const& ci) const { return i != ci.i; }
00090 T & operator *() const { return **i; }
00091
00092
00093 T * operator->() const { return & (operator*()); }
00094 iterator & operator +=(difference_type d) { i += d; return *this; }
00095 iterator & operator -=(difference_type d) { i -= d; return *this; }
00096 reference operator[](difference_type d) const { return *iterator(i+d); }
00097 private:
00098 typename base::iterator i;
00099 friend class const_iterator;
00100 friend class OwnVector<T, P>;
00101 };
00102
00103
00104 OwnVector();
00105 OwnVector(size_type);
00106 OwnVector(OwnVector const&);
00107 #if defined(__GXX_EXPERIMENTAL_CXX0X__)
00108 OwnVector(OwnVector&&) noexcept;
00109 #endif
00110
00111 ~OwnVector() noexcept;
00112
00113 iterator begin();
00114 iterator end();
00115 const_iterator begin() const;
00116 const_iterator end() const;
00117 size_type size() const;
00118 bool empty() const;
00119 reference operator[](size_type);
00120 const_reference operator[](size_type) const;
00121
00122 OwnVector<T, P>& operator=(OwnVector<T, P> const&);
00123 #if defined(__GXX_EXPERIMENTAL_CXX0X__)
00124 OwnVector<T, P>& operator=(OwnVector<T, P>&&) noexcept;
00125 #endif
00126
00127
00128 void reserve(size_t);
00129 template <typename D> void push_back(D*& d);
00130 template <typename D> void push_back(D* const& d);
00131 template <typename D> void push_back(std::auto_ptr<D> d);
00132 void push_back(T const& valueToCopy);
00133 bool is_back_safe() const;
00134 void pop_back();
00135 reference back();
00136 const_reference back() const;
00137 reference front();
00138 const_reference front() const;
00139 base const& data() const;
00140 void clear();
00141 iterator erase(iterator pos);
00142 iterator erase(iterator first, iterator last);
00143 template<typename S>
00144 void sort(S s);
00145 void sort();
00146
00147 void swap(OwnVector<T, P>& other) noexcept;
00148
00149 void fillView(ProductID const& id,
00150 std::vector<void const*>& pointers,
00151 helper_vector& helpers) const;
00152
00153 void setPtr(std::type_info const& toType,
00154 unsigned long index,
00155 void const*& ptr) const;
00156
00157 void fillPtrVector(std::type_info const& toType,
00158 std::vector<unsigned long> const& indices,
00159 std::vector<void const*>& ptrs) const;
00160
00161
00162
00163 CMS_CLASS_VERSION(11)
00164
00165 private:
00166 void destroy() noexcept;
00167 template<typename O>
00168 struct Ordering {
00169 Ordering(O const& c) : comp(c) { }
00170 bool operator()(T const* t1, T const* t2) const {
00171 return comp(*t1, *t2);
00172 }
00173 private:
00174 O comp;
00175 };
00176 template<typename O>
00177 static Ordering<O> ordering(O const& comp) {
00178 return Ordering<O>(comp);
00179 }
00180 base data_;
00181 };
00182
00183 template<typename T, typename P>
00184 inline OwnVector<T, P>::OwnVector() : data_() {
00185 }
00186
00187 template<typename T, typename P>
00188 inline OwnVector<T, P>::OwnVector(size_type n) : data_(n) {
00189 }
00190
00191 template<typename T, typename P>
00192 inline OwnVector<T, P>::OwnVector(OwnVector<T, P> const& o) : data_(o.size()) {
00193 size_type current = 0;
00194 for (const_iterator i = o.begin(), e = o.end(); i != e; ++i,++current)
00195 data_[current] = policy_type::clone(*i);
00196 }
00197
00198 #if defined(__GXX_EXPERIMENTAL_CXX0X__)
00199 template<typename T, typename P>
00200 inline OwnVector<T, P>::OwnVector(OwnVector<T, P>&& o) noexcept{
00201 data_.swap(o.data_);
00202 }
00203 #endif
00204
00205 template<typename T, typename P>
00206 inline OwnVector<T, P>::~OwnVector() noexcept {
00207 destroy();
00208 }
00209
00210 template<typename T, typename P>
00211 inline OwnVector<T, P>& OwnVector<T, P>::operator=(OwnVector<T, P> const& o) {
00212 OwnVector<T,P> temp(o);
00213 swap(temp);
00214 return *this;
00215 }
00216
00217 #if defined(__GXX_EXPERIMENTAL_CXX0X__)
00218 template<typename T, typename P>
00219 inline OwnVector<T, P>& OwnVector<T, P>::operator=(OwnVector<T, P>&& o) noexcept {
00220 data_.swap(o.data_);
00221 return *this;
00222 }
00223 #endif
00224
00225
00226 template<typename T, typename P>
00227 inline typename OwnVector<T, P>::iterator OwnVector<T, P>::begin() {
00228 return iterator(data_.begin());
00229 }
00230
00231 template<typename T, typename P>
00232 inline typename OwnVector<T, P>::iterator OwnVector<T, P>::end() {
00233 return iterator(data_.end());
00234 }
00235
00236 template<typename T, typename P>
00237 inline typename OwnVector<T, P>::const_iterator OwnVector<T, P>::begin() const {
00238 return const_iterator(data_.begin());
00239 }
00240
00241 template<typename T, typename P>
00242 inline typename OwnVector<T, P>::const_iterator OwnVector<T, P>::end() const {
00243 return const_iterator(data_.end());
00244 }
00245
00246 template<typename T, typename P>
00247 inline typename OwnVector<T, P>::size_type OwnVector<T, P>::size() const {
00248 return data_.size();
00249 }
00250
00251 template<typename T, typename P>
00252 inline bool OwnVector<T, P>::empty() const {
00253 return data_.empty();
00254 }
00255
00256 template<typename T, typename P>
00257 inline typename OwnVector<T, P>::reference OwnVector<T, P>::operator[](size_type n) {
00258 return *data_[n];
00259 }
00260
00261 template<typename T, typename P>
00262 inline typename OwnVector<T, P>::const_reference OwnVector<T, P>::operator[](size_type n) const {
00263 return *data_[n];
00264 }
00265
00266 template<typename T, typename P>
00267 inline void OwnVector<T, P>::reserve(size_t n) {
00268 data_.reserve(n);
00269 }
00270
00271 template<typename T, typename P>
00272 template<typename D>
00273 inline void OwnVector<T, P>::push_back(D*& d) {
00274
00275
00276
00277 data_.push_back(d);
00278 d = 0;
00279 }
00280
00281 template<typename T, typename P>
00282 template<typename D>
00283 inline void OwnVector<T, P>::push_back(D* const& d) {
00284
00285
00286
00287
00288
00289 data_.push_back(d);
00290 }
00291
00292
00293 template<typename T, typename P>
00294 template<typename D>
00295 inline void OwnVector<T, P>::push_back(std::auto_ptr<D> d) {
00296 data_.push_back(d.release());
00297 }
00298
00299
00300 template<typename T, typename P>
00301 inline void OwnVector<T, P>::push_back(T const& d) {
00302 data_.push_back(policy_type::clone(d));
00303 }
00304
00305
00306 template<typename T, typename P>
00307 inline void OwnVector<T, P>::pop_back() {
00308
00309
00310 delete data_.back();
00311 data_.pop_back();
00312 }
00313
00314 template <typename T, typename P>
00315 inline bool OwnVector<T, P>::is_back_safe() const {
00316 return data_.back() != 0;
00317 }
00318
00319 template<typename T, typename P>
00320 inline typename OwnVector<T, P>::reference OwnVector<T, P>::back() {
00321 T* result = data_.back();
00322 if (result == 0) {
00323 Exception::throwThis(errors::NullPointerError,
00324 "In OwnVector::back() we have intercepted an attempt to dereference a null pointer\n"
00325 "Since OwnVector is allowed to contain null pointers, you much assure that the\n"
00326 "pointer at the end of the collection is not null before calling back()\n"
00327 "if you wish to avoid this exception.\n"
00328 "Consider using OwnVector::is_back_safe()\n");
00329 }
00330 return *data_.back();
00331 }
00332
00333 template<typename T, typename P>
00334 inline typename OwnVector<T, P>::const_reference OwnVector<T, P>::back() const {
00335 T* result = data_.back();
00336 if (result == 0) {
00337 Exception::throwThis(errors::NullPointerError,
00338 "In OwnVector::back() we have intercepted an attempt to dereference a null pointer\n"
00339 "Since OwnVector is allowed to contain null pointers, you much assure that the\n"
00340 "pointer at the end of the collection is not null before calling back()\n"
00341 "if you wish to avoid this exception.\n"
00342 "Consider using OwnVector::is_back_safe()\n");
00343 }
00344 return *data_.back();
00345 }
00346
00347 template<typename T, typename P>
00348 inline typename OwnVector<T, P>::reference OwnVector<T, P>::front() {
00349 return *data_.front();
00350 }
00351
00352 template<typename T, typename P>
00353 inline typename OwnVector<T, P>::const_reference OwnVector<T, P>::front() const {
00354 return *data_.front();
00355 }
00356
00357 template<typename T, typename P>
00358 inline void OwnVector<T, P>::destroy() noexcept {
00359 typename base::const_iterator b = data_.begin(), e = data_.end();
00360 for(typename base::const_iterator i = b; i != e; ++ i)
00361 delete * i;
00362 }
00363
00364 template<typename T, typename P>
00365 inline typename OwnVector<T, P>::base const& OwnVector<T, P>::data() const {
00366 return data_;
00367 }
00368
00369 template<typename T, typename P>
00370 inline void OwnVector<T, P>::clear() {
00371 destroy();
00372 data_.clear();
00373 }
00374
00375 template<typename T, typename P>
00376 typename OwnVector<T, P>::iterator OwnVector<T, P>::erase(iterator pos) {
00377 delete * pos.i;
00378 return iterator(data_.erase(pos.i));
00379 }
00380
00381 template<typename T, typename P>
00382 typename OwnVector<T, P>::iterator OwnVector<T, P>::erase(iterator first, iterator last) {
00383 typename base::iterator b = first.i, e = last.i;
00384 for(typename base::iterator i = b; i != e; ++ i)
00385 delete * i;
00386 return iterator(data_.erase(b, e));
00387 }
00388
00389 template<typename T, typename P> template<typename S>
00390 void OwnVector<T, P>::sort(S comp) {
00391 std::sort(data_.begin(), data_.end(), ordering(comp));
00392 }
00393
00394 template<typename T, typename P>
00395 void OwnVector<T, P>::sort() {
00396 std::sort(data_.begin(), data_.end(), ordering(std::less<value_type>()));
00397 }
00398
00399 template<typename T, typename P>
00400 inline void OwnVector<T, P>::swap(OwnVector<T, P>& other) noexcept {
00401 data_.swap(other.data_);
00402 }
00403
00404 template<typename T, typename P>
00405 void OwnVector<T, P>::fillView(ProductID const& id,
00406 std::vector<void const*>& pointers,
00407 helper_vector& helpers) const {
00408 typedef Ref<OwnVector> ref_type ;
00409 typedef reftobase::RefHolder<ref_type> holder_type;
00410
00411 size_type numElements = this->size();
00412 pointers.reserve(numElements);
00413 helpers.reserve(numElements);
00414 size_type key = 0;
00415 for(typename base::const_iterator i=data_.begin(), e=data_.end(); i!=e; ++i, ++key) {
00416
00417 if (*i == 0) {
00418 Exception::throwThis(errors::NullPointerError,
00419 "In OwnVector::fillView() we have intercepted an attempt to put a null pointer\n"
00420 "into a View and that is not allowed. It is probably an error that the null\n"
00421 "pointer was in the OwnVector in the first place.\n");
00422 }
00423 else {
00424 pointers.push_back(*i);
00425 holder_type h(ref_type(id, *i, key,this));
00426 helpers.push_back(&h);
00427 }
00428 }
00429 }
00430
00431 template<typename T, typename P>
00432 inline void swap(OwnVector<T, P>& a, OwnVector<T, P>& b) noexcept {
00433 a.swap(b);
00434 }
00435
00436
00437
00438
00439
00440 template <typename T, typename P>
00441 inline
00442 void
00443 fillView(OwnVector<T,P> const& obj,
00444 ProductID const& id,
00445 std::vector<void const*>& pointers,
00446 helper_vector& helpers) {
00447 obj.fillView(id, pointers, helpers);
00448 }
00449
00450
00451 template <typename T, typename P>
00452 struct has_fillView<edm::OwnVector<T, P> > {
00453 static bool const value = true;
00454 };
00455
00456
00457
00458
00459 template <typename T, typename P>
00460 inline
00461 void
00462 OwnVector<T,P>::setPtr(std::type_info const& toType,
00463 unsigned long index,
00464 void const*& ptr) const {
00465 detail::reallySetPtr<OwnVector<T,P> >(*this, toType, index, ptr);
00466 }
00467
00468 template <typename T, typename P>
00469 inline
00470 void
00471 setPtr(OwnVector<T,P> const& obj,
00472 std::type_info const& toType,
00473 unsigned long index,
00474 void const*& ptr) {
00475 obj.setPtr(toType, index, ptr);
00476 }
00477
00478 template <typename T, typename P>
00479 inline
00480 void
00481 OwnVector<T,P>::fillPtrVector(std::type_info const& toType,
00482 std::vector<unsigned long> const& indices,
00483 std::vector<void const*>& ptrs) const {
00484 detail::reallyfillPtrVector(*this, toType, indices, ptrs);
00485 }
00486
00487
00488 template <typename T, typename P>
00489 inline
00490 void
00491 fillPtrVector(OwnVector<T,P> const& obj,
00492 std::type_info const& toType,
00493 std::vector<unsigned long> const& indices,
00494 std::vector<void const*>& ptrs) {
00495 obj.fillPtrVector(toType, indices, ptrs);
00496 }
00497
00498
00499 template <typename T, typename P>
00500 struct has_setPtr<edm::OwnVector<T,P> > {
00501 static bool const value = true;
00502 };
00503
00504
00505 }
00506
00507
00508 #endif