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