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