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