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