00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #if !defined(_Vector_h_)
00032 #define _Vector_h_
00033
00034 #if !defined (cap_use_pdvector)
00035 #include <vector>
00036 #include <algorithm>
00037 #include <functional>
00038
00039 #define pdvector std::vector
00040 #define VECTOR_SORT(l1, f) std::sort(l1.begin(), l1.end(), ptr_fun(f));
00041
00042
00043 #define VECTOR_ERASE(v, start_pos, end_pos) v.erase(v.begin() + start_pos, v.begin() + (end_pos + 1))
00044 #define VECTOR_APPEND(v1, v2) v1.insert(v1.end(), v2.begin(), v2.end())
00045 #define GET_ITER(v, pos) (v.begin() + pos)
00046
00047 #else
00048
00049 #if defined(external_templates)
00050 #pragma interface
00051 #endif
00052
00053 #include "common/h/language.h"
00054
00055 #if defined(os_windows)
00056
00057 #pragma warning (disable: 4786)
00058 #endif
00059
00060 #define VECTOR_APPEND(l1, l2) { for (unsigned int _i=0; _i < (l2).size(); _i++) (l1).push_back((l2)[_i]); }
00061 #define VECTOR_SORT(l1, f) l1.sort((qsort_cmpfunc_t)f);
00062 #define VECTOR_ERASE(v, start_pos, end_pos) v.erase(start_pos, end_pos)
00063 #define GET_ITER(v, pos) v.getIter(pos)
00064
00065
00066 #ifdef _KERNEL
00067 #include <sys/types.h>
00068 #include <sys/kmem.h>
00069 #include <sys/debug.h>
00070 #define assert ASSERT
00071 #else
00072 #include <assert.h>
00073 #include <stdlib.h>
00074 #include <stdio.h>
00075 #include <sys/types.h>
00076 #endif
00077
00078 extern "C" {
00079 typedef int (*qsort_cmpfunc_t)(const void *, const void *);
00080 }
00081
00082 #ifndef _KERNEL
00083 #include <new>
00084 #elif defined(_LP64)
00085 inline void *operator new(unsigned long , void *place) {
00086 return place;
00087 }
00088 #else
00089 inline void *operator new(unsigned , void *place) {
00090 return place;
00091 }
00092 #endif
00093
00094 #ifndef NULL
00095 #define NULL 0
00096 #endif
00097
00098 #if !defined(DO_INLINE_P)
00099 #define DO_INLINE_P
00100 #endif
00101
00102 #if !defined(DO_INLINE_F)
00103 #define DO_INLINE_F
00104 #endif
00105
00106 template <class T>
00107 class vec_stdalloc {
00108 public:
00109 static T *alloc(unsigned nelems) {
00110 const size_t nbytes = nelems * sizeof(T);
00111
00112 #ifdef _KERNEL
00113 T* result = (T*)kmem_alloc(nbytes, KM_SLEEP);
00114
00115 #else
00116 T* result = (T*)malloc(nbytes);
00117 if (!result) {
00118 unsigned long lnbytes = nbytes;
00119 fprintf(stderr, "%s[%d]: FATAL: malloc (%lu) failed\n", __FILE__, __LINE__, lnbytes);
00120 assert(result);
00121 }
00122 #endif
00123
00124 return result;
00125 }
00126
00127 #ifdef _KERNEL
00128 static void free(T *vec, unsigned nelems) {
00129 kmem_free(vec, sizeof(T)*nelems);
00130 }
00131 #else
00132 static void free(T *vec, unsigned ) {
00133 ::free(vec);
00134 }
00135 #endif
00136 };
00137
00138 template<class T, class A=vec_stdalloc<T> >
00139 class pdvector {
00140 public:
00141
00142 typedef T value_type;
00143 typedef T* pointer;
00144 typedef const T* const_pointer;
00145 typedef T* iterator;
00146 typedef const T* const_iterator;
00147 typedef T& reference;
00148 typedef const T& const_reference;
00149
00150 pdvector() {
00151 data_ = NULL;
00152 sz_ = tsz_ = 0;
00153 }
00154
00155 #ifndef _KERNEL
00156 explicit
00157 #endif
00158 DO_INLINE_F
00159 pdvector(unsigned sz) {
00160
00161
00162
00163
00164
00165
00166
00167 initialize_1(sz, T());
00168 }
00169
00170 DO_INLINE_F
00171 pdvector(unsigned sz, const T &t) {
00172 initialize_1(sz, t);
00173 }
00174
00175 DO_INLINE_F
00176 pdvector(const pdvector<T, A> &src) {
00177 initialize_copy(src.sz_, src.begin(), src.end());
00178 }
00179
00180 DO_INLINE_F
00181 pdvector(const pdvector<T, A> &src1, const T &src2) {
00182
00183 sz_ = tsz_ = src1.size() + 1;
00184 data_ = A::alloc(sz_);
00185 assert(data_);
00186
00187
00188 copy_into_uninitialized_space(data_,
00189 src1.begin(), src1.end());
00190
00191
00192 (void)new((void*)(data_ + sz_ - 1))T(src2);
00193 }
00194
00195 DO_INLINE_F
00196 pdvector(const pdvector<T,A> &src1, const pdvector<T,A> &src2) {
00197
00198 sz_ = tsz_ = src1.size() + src2.size();
00199 data_ = A::alloc(sz_);
00200 assert(data_);
00201
00202
00203 copy_into_uninitialized_space(data_,
00204 src1.begin(), src1.end());
00205
00206
00207 copy_into_uninitialized_space(data_ + src1.size(),
00208 src2.begin(), src2.end());
00209 }
00210
00211 DO_INLINE_F
00212 ~pdvector() {
00213 zap();
00214 }
00215 DO_INLINE_F bool operator==(const pdvector<T, A> &) const;
00216
00217 DO_INLINE_F pdvector<T, A>& operator=(const pdvector<T, A> &);
00218 DO_INLINE_F pdvector<T, A>& operator+=(const pdvector<T, A> &);
00219 DO_INLINE_F pdvector<T, A>& operator+=(const T &);
00220 DO_INLINE_F
00221 pdvector<T, A> operator+(const T &item) const {
00222
00223
00224 pdvector<T, A> result(*this);
00225 result += item;
00226 return result;
00227 }
00228
00229 DO_INLINE_F
00230 reference operator[] (unsigned i) {
00231 assert((i < sz_) && data_);
00232 return *(data_ + i);
00233 }
00234
00235 DO_INLINE_F
00236 const_reference operator[] (unsigned i) const {
00237 assert((i < sz_) && data_);
00238 return *(data_ + i);
00239 }
00240
00241 DO_INLINE_F
00242 void pop_back() {
00243 shrink(sz_ - 1);
00244 }
00245
00246 DO_INLINE_F pdvector<T, A>& push_back(const T &);
00247
00248
00249
00250
00251
00252 DO_INLINE_F void erase(unsigned start, unsigned end);
00253 DO_INLINE_F void erase(iterator itr);
00254 DO_INLINE_F void sort(qsort_cmpfunc_t cmpfunc);
00255
00256 DO_INLINE_F
00257 void swap(pdvector<T, A> &other) {
00258 T *mydata = data_;
00259 const unsigned mysz = sz_;
00260 const unsigned mytsz = tsz_;
00261
00262 data_ = other.data_;
00263 sz_ = other.sz_;
00264 tsz_ = other.tsz_;
00265
00266 other.data_ = mydata;
00267 other.sz_ = mysz;
00268 other.tsz_ = mytsz;
00269 }
00270
00271 DO_INLINE_F reference front() { return *begin(); }
00272 DO_INLINE_F const_reference front() const { return *begin(); }
00273 DO_INLINE_F reference back() { return *(end()-1); }
00274 DO_INLINE_F const_reference back() const { return *(end()-1); }
00275
00276 DO_INLINE_F unsigned size() const {return sz_;}
00277
00278 DO_INLINE_F void resize(unsigned, bool exact=true);
00279
00280
00281
00282 DO_INLINE_F void shrink(unsigned newsize);
00283
00284
00285
00286 DO_INLINE_F void clear() {if (sz_ > 0) shrink(0);}
00287
00288
00289
00290
00291
00292 DO_INLINE_F
00293 void zap() {
00294
00295
00296 destroy();
00297 sz_ = tsz_ = 0;
00298 }
00299
00300 DO_INLINE_F void grow(unsigned newsize, bool exact=false);
00301
00302
00303 DO_INLINE_F void reserve(unsigned nelems) { reserve_exact(nelems); }
00304
00305 DO_INLINE_F void reserve_exact(unsigned nelems);
00306 DO_INLINE_F void reserve_roundup(unsigned nelems);
00307
00308 DO_INLINE_F
00309 unsigned capacity() const {
00310
00311
00312
00313 return tsz_;
00314 }
00315
00316 DO_INLINE_F iterator reserve_for_inplace_construction(unsigned nelems);
00317
00318
00319
00320
00321 DO_INLINE_F iterator append_with_inplace_construction();
00322
00323
00324
00325
00326 DO_INLINE_F iterator begin() { return data_; }
00327 DO_INLINE_F const_iterator begin() const { return data_; }
00328 DO_INLINE_F iterator end() { return begin() + sz_; }
00329 DO_INLINE_F const_iterator end() const { return begin() + sz_; }
00330
00331 DO_INLINE_F iterator getIter(unsigned index) {
00332 assert(index < sz_);
00333 return data_ + index;
00334 }
00335 DO_INLINE_F const_iterator getIter(unsigned index) const {
00336 assert(index < sz_);
00337 return data_ + index;
00338 }
00339
00340 private:
00341 DO_INLINE_P
00342 static void deconstruct_items(T *first, T *last) {
00343 for (; first != last; ++first)
00344 first->~T();
00345 }
00346
00347 DO_INLINE_P
00348 static void copy_into_uninitialized_space(T *dest, const T *src_first,
00349 const T *src_last) {
00350
00351
00352
00353 while (src_first != src_last)
00354 new((void*)dest++) T(*src_first++);
00355 }
00356
00357 DO_INLINE_P
00358 static void copy_1item_into_uninitialized_space(T *dest, const T &src,
00359 unsigned n) {
00360 while (n--)
00361 new((void*)dest++) T(src);
00362 }
00363
00364 DO_INLINE_P void initialize_1(unsigned sz, const T &t);
00365 DO_INLINE_P void initialize_copy(unsigned sz, const T *srcfirst, const T *srcend);
00366
00367 DO_INLINE_P void destroy();
00368
00369 T* data_;
00370 unsigned sz_;
00371 unsigned tsz_;
00372 };
00373
00374 template<class T, class A>
00375 DO_INLINE_F
00376 pdvector<T, A>&
00377 pdvector<T, A>::operator=(const pdvector<T, A>& src) {
00378 if (this == &src)
00379 return *this;
00380
00381 bool fryAndRecreate = (src.sz_ > tsz_);
00382
00383 if (fryAndRecreate) {
00384
00385 destroy();
00386
00387
00388 initialize_copy(src.sz_, src.begin(), src.end());
00389 }
00390 else {
00391
00392 deconstruct_items(begin(), end());
00393
00394 sz_ = src.sz_;
00395 copy_into_uninitialized_space(data_,
00396 src.begin(), src.end());
00397 }
00398
00399 return *this;
00400 }
00401
00402 template<class T, class A>
00403 DO_INLINE_F
00404 pdvector<T, A>&
00405 pdvector<T, A>::operator+=(const pdvector<T,A>& src) {
00406 const unsigned newsize = sz_ + src.sz_;
00407 if (newsize > tsz_)
00408 reserve_roundup(newsize);
00409
00410 copy_into_uninitialized_space(data_ + sz_,
00411 src.begin(), src.end());
00412
00413 sz_ += src.sz_;
00414 assert(tsz_ >= sz_);
00415
00416 return *this;
00417 }
00418
00419 template<class T, class A>
00420 DO_INLINE_F
00421 pdvector<T, A>&
00422 pdvector<T, A>::operator+=(const T& t) {
00423 const unsigned newsize = sz_ + 1;
00424 if (newsize > tsz_)
00425 reserve_roundup(newsize);
00426
00427 copy_1item_into_uninitialized_space(data_ + sz_,
00428 t,
00429 1);
00430 sz_++;
00431 assert(tsz_ >= sz_);
00432
00433 return *this;
00434 }
00435
00436 template<class T, class A>
00437 DO_INLINE_F
00438 pdvector<T, A>&
00439 pdvector<T, A>::push_back(const T& t) {
00440 const unsigned newsize = sz_ + 1;
00441 if (newsize > tsz_)
00442 reserve_roundup(newsize);
00443
00444 copy_1item_into_uninitialized_space(data_ + sz_,
00445 t,
00446 1);
00447 sz_++;
00448 assert(tsz_ >= sz_);
00449
00450 return *this;
00451 }
00452
00453 template<class T, class A>
00454 DO_INLINE_F
00455 void pdvector<T, A>::sort(qsort_cmpfunc_t cmpfunc) {
00456 if (sz_)
00457 qsort((void *) data_, sz_, sizeof(T), cmpfunc);
00458 }
00459
00460 template<class T, class A>
00461 DO_INLINE_F
00462 void pdvector<T, A>::shrink(unsigned newsize) {
00463 if (newsize == sz_) return;
00464 if (newsize > sz_) {
00465 fprintf(stderr, "%s[%d]: FAILING: cannot shrink %d to %d\n", __FILE__, __LINE__, sz_, newsize);
00466 }
00467 assert(newsize < sz_);
00468 deconstruct_items(begin() + newsize, end());
00469 sz_ = newsize;
00470 }
00471
00472 template<class T, class A>
00473 DO_INLINE_F
00474 void pdvector<T, A>::grow(unsigned newsize, bool exact) {
00475
00476 if (exact)
00477 reserve_exact(newsize);
00478 else
00479 reserve_roundup(newsize);
00480
00481 copy_1item_into_uninitialized_space(data_ + sz_,
00482 T(),
00483 newsize - sz_);
00484 sz_ = newsize;
00485 assert(tsz_ >= sz_);
00486 }
00487
00488
00489 template<class T, class A>
00490 DO_INLINE_F
00491 void pdvector<T, A>::resize(unsigned newsize, bool exact) {
00492 if (newsize == sz_)
00493 ;
00494 else if (newsize < sz_)
00495 shrink(newsize);
00496 else
00497 grow(newsize, exact);
00498 }
00499
00500 template<class T, class A>
00501 DO_INLINE_F
00502 void pdvector<T, A>::erase(unsigned start, unsigned end) {
00503 int origSz = sz_;
00504 int emptyIndex = start;
00505 int copyIndex = end + 1;
00506 while(copyIndex<origSz) {
00507 data_[emptyIndex++] = data_[copyIndex++];
00508 }
00509
00510 shrink(origSz - (end - start + 1));
00511 }
00512
00513 template<class T, class A>
00514 DO_INLINE_F
00515 void pdvector<T, A>::erase(iterator itr) {
00516 unsigned index = itr - data_;
00517 erase(index, index);
00518 }
00519
00520 template<class T, class A>
00521 DO_INLINE_P
00522 void pdvector<T, A>::initialize_1(unsigned sz, const T &t) {
00523 sz_ = tsz_ = sz;
00524 if (sz_ > 0) {
00525 data_ = A::alloc(sz_);
00526 assert(data_);
00527 copy_1item_into_uninitialized_space(data_, t, sz_);
00528 }
00529 else
00530 data_ = NULL;
00531 }
00532
00533 template<class T, class A>
00534 DO_INLINE_P
00535 void pdvector<T, A>::initialize_copy(unsigned sz, const T *srcfirst, const T *srclast) {
00536 sz_ = tsz_ = sz;
00537 if (sz_ > 0) {
00538 data_ = A::alloc(sz_);
00539 assert(data_ && srcfirst && srclast);
00540 copy_into_uninitialized_space(data_,
00541 srcfirst, srclast);
00542 }
00543 else
00544 data_ = NULL;
00545 }
00546
00547 template<class T, class A>
00548 DO_INLINE_P
00549 void pdvector<T, A>::destroy() {
00550 if (data_) {
00551 deconstruct_items(begin(), end());
00552 assert(tsz_ > 0);
00553 A::free(data_, tsz_);
00554 data_ = NULL;
00555 }
00556 else {
00557 if(sz_ == 0) assert(tsz_==0);
00558 }
00559 }
00560
00561 template<class T, class A>
00562 DO_INLINE_F
00563 void pdvector<T, A>::reserve_roundup(unsigned nelems) {
00564
00565 assert(nelems >= sz_);
00566
00567 if (tsz_ > nelems)
00568 return;
00569
00570
00571 unsigned roundup_nelems = 1;
00572 while (roundup_nelems < nelems)
00573 roundup_nelems <<= 1;
00574
00575 assert(roundup_nelems >= nelems);
00576
00577 reserve_exact(roundup_nelems);
00578 }
00579
00580 template<class T, class A>
00581 DO_INLINE_F
00582 TYPENAME pdvector<T,A>::iterator
00583 pdvector<T, A>::append_with_inplace_construction() {
00584 reserve_roundup(sz_ + 1);
00585
00586
00587 ++sz_;
00588
00589 return end()-1;
00590 }
00591
00592
00593 template<class T, class A>
00594 DO_INLINE_F
00595 TYPENAME pdvector<T, A>::iterator
00596 pdvector<T, A>::reserve_for_inplace_construction(unsigned nelems) {
00597
00598
00599
00600
00601 assert(sz_ == 0);
00602 assert(tsz_ == 0);
00603 assert(data_ == NULL);
00604
00605 if (nelems > 0) {
00606
00607
00608
00609
00610
00611 data_ = A::alloc(nelems);
00612 tsz_ = nelems;
00613 }
00614
00615 assert(sz_ == 0);
00616 assert(tsz_ >= nelems);
00617 if (nelems > 0)
00618 assert(data_ != NULL);
00619
00620 sz_ = nelems;
00621
00622 return begin();
00623 }
00624
00625 template<class T, class A>
00626 DO_INLINE_F
00627 void pdvector<T, A>::reserve_exact(unsigned nelems) {
00628
00629
00630
00631 assert(nelems >= sz_);
00632
00633
00634 if (nelems == 0)
00635 return;
00636
00637
00638
00639
00640
00641 T *newdata = A::alloc(nelems);
00642
00643
00644 if (data_) {
00645 assert(tsz_ > 0);
00646 copy_into_uninitialized_space(newdata,
00647 begin(), end());
00648 }
00649 else
00650 assert(tsz_ == 0 && sz_ == 0);
00651
00652
00653 destroy();
00654
00655
00656 data_ = newdata;
00657 tsz_ = nelems;
00658
00659 }
00660
00661 template<class T, class A>
00662 DO_INLINE_P
00663 bool
00664 find(const pdvector<T, A> &v, const T &v0, unsigned &l) {
00665 unsigned i, sz;
00666 sz = v.size();
00667 for( i = 0; i < sz; ++i ) {
00668 if( v[ i ] == v0 ) {
00669 l = i;
00670 return true;
00671 }
00672 }
00673 return false;
00674 }
00675
00676 template<class T, class A>
00677 DO_INLINE_P
00678 bool pdvector<T, A>::operator== (const pdvector<T,A> &) const
00679 {
00680 return false;
00681 }
00682 #endif
00683 #endif