Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

BCP_vector_general.cpp

00001 // Copyright (C) 2000, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
00003 #include <algorithm>
00004 
00005 #include "BCP_os.hpp"
00006 #include "BCP_error.hpp"
00007 #include "BCP_vector.hpp"
00008 #include "BCP_vector_sanity.hpp"
00009 
00010 //#############################################################################
00011 
00012 template <class T> void
00013 BCP_vec<T>::deallocate() {
00014    if (start) {
00015       while (finish != start) {
00016          BCP_DESTROY(--finish);
00017       }
00018       ::operator delete(start);
00019    }
00020 }
00021 
00022 //#############################################################################
00023 
00024 template <class T> void
00025 BCP_vec<T>::insert_aux(iterator position, const_reference x){
00026    if (finish != end_of_storage) {
00027       BCP_CONSTRUCT(finish, *(finish - 1));
00028       std::copy_backward(position, finish - 1, finish);
00029       *position = x;
00030       ++finish;
00031    } else {
00032       const size_t len = (2*size() + 0x1000) * sizeof(T);
00033       iterator tmp = allocate(len);
00034       iterator tmp_finish = std::uninitialized_copy(start, position, tmp);
00035       BCP_CONSTRUCT(tmp_finish++, x);
00036       tmp_finish = std::uninitialized_copy(position, finish, tmp_finish);
00037       deallocate();
00038       start = tmp;
00039       finish = tmp_finish;
00040       end_of_storage = tmp + len;
00041    }
00042 }
00043 
00044 //#############################################################################
00045 
00046 template <class T>
00047 BCP_vec<T>::BCP_vec(const size_t n, const_reference value) :
00048    start(0), finish(0), end_of_storage(0)
00049 {
00050    if (n > 0) {
00051       start = allocate(n);
00052       end_of_storage = finish = start + n;
00053       std::uninitialized_fill_n(start, n, value);
00054    }
00055 }
00056 
00057 template <class T>
00058 BCP_vec<T>::BCP_vec(const_iterator first, const_iterator last) :
00059    start(0), finish(0), end_of_storage(0)
00060 {
00061    const size_t len = last - first;
00062    if (len > 0) {
00063       start = allocate(len);
00064       end_of_storage = finish = std::uninitialized_copy(first, last, start);
00065    }
00066 }
00067 
00068 template <class T>
00069 BCP_vec<T>::BCP_vec(const T* x, const size_t num) :
00070    start(0), finish(0), end_of_storage(0)
00071 {
00072    if (num > 0) {
00073       finish = start = allocate(num);
00074       const T* const lastx = x + num;
00075       while (x != lastx)
00076          BCP_CONSTRUCT(finish++, *x++);
00077       end_of_storage = finish;
00078    }
00079 }
00080 
00081 //#############################################################################
00082 
00083 template <class T> void
00084 BCP_vec<T>::keep(iterator pos) {
00085    iterator oldfinish = finish;
00086    finish = std::copy(pos, pos + 1, start);
00087    BCP_DESTROY_RANGE(finish, oldfinish);
00088 }
00089 
00090 template <class T> void
00091 BCP_vec<T>::keep(iterator first, iterator last) {
00092    iterator oldfinish = finish;
00093    finish = std::copy(first, last, start);
00094    BCP_DESTROY_RANGE(finish, oldfinish);
00095 }
00096 
00097 //#############################################################################
00098 
00099 template <class T> void
00100 BCP_vec<T>::erase(iterator position) {
00101    if (position + 1 != finish)
00102       std::copy(position + 1, finish, position);
00103    BCP_DESTROY(--finish);
00104 }
00105 
00106 template <class T> void
00107 BCP_vec<T>::erase(iterator first, iterator last) {
00108    iterator oldfinish = finish;
00109    finish = std::copy(last, finish, first);
00110    BCP_DESTROY_RANGE(finish, oldfinish);
00111 }
00112 
00113 //#############################################################################
00114 //#############################################################################
00115 
00116 template <class T> void
00117 BCP_vec<T>::reserve(const size_t n){
00118    if (capacity() < n) {
00119       iterator tmp = allocate(n);
00120       iterator tmp_finish = std::uninitialized_copy(start, finish, tmp);
00121       deallocate();
00122       start = tmp;
00123       finish = tmp_finish;
00124       end_of_storage = start + n;
00125    }
00126 }
00127 
00128 //#############################################################################
00129 
00130 template <class T> void
00131 BCP_vec<T>::swap(BCP_vec<T>& x) {
00132    std::swap(start, x.start);
00133    std::swap(finish, x.finish);
00134    std::swap(end_of_storage, x.end_of_storage);
00135 }
00136    
00137 //#############################################################################
00138 
00139 template <class T> BCP_vec<T>&
00140 BCP_vec<T>::operator=(const BCP_vec<T>& x){
00141    if (&x != this) {
00142       const size_t x_size = x.size();
00143       if (x_size > capacity()) {
00144          deallocate();
00145          start = allocate(x_size);
00146          end_of_storage = start + x_size;
00147          finish = std::uninitialized_copy(x.begin(), x.end(), start);
00148       } else {
00149          if (x_size < size()) {
00150             iterator oldfinish = finish;
00151             finish = std::copy(x.begin(), x.end(), start);
00152             BCP_DESTROY_RANGE(finish, oldfinish);
00153          } else {
00154             std::copy(x.begin(), x.entry(size()), start);
00155             finish = std::uninitialized_copy(x.entry(size()), x.end(), finish);
00156          }
00157       }
00158    }
00159    return *this;
00160 }
00161 
00162 //#############################################################################
00163 // need the void* here, since we occasionally want to copy out of a buffer
00164 
00165 template <class T> void
00166 BCP_vec<T>::assign(const void* x, const size_t num){
00167    if (num > capacity()){
00168       deallocate();
00169       start = allocate(num);
00170       end_of_storage = start + num;
00171    } else {
00172       BCP_DESTROY_RANGE(start, finish);
00173    }
00174    T entry;
00175    finish = start;
00176    const char* charx = static_cast<const char*>(x);
00177    for (int i = num; i > 0; --i) {
00178       memcpy(&entry, charx, sizeof(T));
00179       BCP_CONSTRUCT(finish++, entry);
00180       charx += sizeof(T);
00181    }
00182 }
00183 
00184 //#############################################################################
00185 
00186 template <class T> void
00187 BCP_vec<T>::insert(iterator position, const void* first, const size_t n){
00188    if (n == 0) return;
00189    T entry;
00190    const char* charx = static_cast<const char*>(first);
00191    if ((size_t) (end_of_storage - finish) >= n) {
00192       const size_t to_move = finish - position;
00193       if (to_move <= n) {
00194          std::uninitialized_copy(position, finish, position + n);
00195          finish += n;
00196          size_t i = n;
00197          for ( ; i > to_move; --i) {
00198             memcpy(&entry, charx, sizeof(T));
00199             BCP_CONSTRUCT(position++, entry);
00200             charx += sizeof(T);
00201          }
00202          for ( ; i > 0; --i) {
00203             memcpy(&entry, charx, sizeof(T));
00204             *position++ = entry; 
00205             charx += sizeof(T);
00206          }
00207       } else {
00208          std::uninitialized_copy(finish - n, finish, finish);
00209          std::copy_backward(position, finish - n, finish);
00210          finish += n;
00211          for (int i = n; i > 0; --i) {
00212             memcpy(&entry, charx, sizeof(T));
00213             *position++ = entry; 
00214             charx += sizeof(T);
00215          }
00216       }
00217    } else {
00218       const size_t new_size = (2*size() + n) * sizeof(T);
00219       iterator tmp = allocate(new_size);
00220       iterator tmp_finish = std::uninitialized_copy(start, position, tmp);
00221       for (int i = n; i > 0; --i) {
00222          memcpy(&entry, charx, sizeof(T));
00223          BCP_CONSTRUCT(tmp_finish++, entry);
00224          charx += sizeof(T);
00225       }
00226       tmp_finish = std::uninitialized_copy(position, finish, tmp_finish);
00227       deallocate();
00228       start = tmp;
00229       finish = tmp_finish;
00230       end_of_storage = tmp + new_size;
00231    }
00232 }
00233 
00234 //#############################################################################
00235 
00236 template <class T> void
00237 BCP_vec<T>::insert(iterator position,
00238                    const_iterator first, const_iterator last){
00239    if (first == last) return;
00240    const size_t n = last - first;
00241    if ((size_t) (end_of_storage - finish) >= n) {
00242       const size_t to_move = finish - position;
00243       if (to_move <= n) {
00244          std::uninitialized_copy(position, finish, position + n);
00245          std::copy(first, first + to_move, position);
00246          std::uninitialized_copy(first + to_move, last, finish);
00247       } else {
00248          std::uninitialized_copy(finish - n, finish, finish);
00249          std::copy_backward(position, finish - n, finish);
00250          std::copy(first, last, position);
00251       }
00252       finish += n;
00253    } else {
00254       const size_t new_size = (2*size() + n) * sizeof(T);
00255       iterator tmp = allocate(new_size);
00256       iterator tmp_finish = std::uninitialized_copy(start, position, tmp);
00257       tmp_finish = std::uninitialized_copy(first, last, tmp_finish);
00258       tmp_finish = std::uninitialized_copy(position, finish, tmp_finish);
00259       deallocate();
00260       start = tmp;
00261       finish = tmp_finish;
00262       end_of_storage = tmp + new_size;
00263    }
00264 }
00265 
00266 //#############################################################################
00267 
00268 template <class T> void
00269 BCP_vec<T>::insert(iterator position, const size_t n, const_reference x) {
00270    if (n == 0) return;
00271    if ((size_t) (end_of_storage - finish) >= n) {
00272       const size_t to_move = finish - position;
00273       if (to_move <= n) {
00274          std::uninitialized_copy(position, finish, position + n);
00275          std::fill_n(position, to_move, x);
00276          std::uninitialized_fill_n(finish, n - to_move, x);
00277       } else {
00278          std::uninitialized_copy(finish - n, finish, finish);
00279          std::copy_backward(position, finish - n, finish);
00280          std::fill_n(position, n, x);
00281       }
00282       finish += n;
00283    } else {
00284       const size_t new_size = (2*size() + n) * sizeof(T);
00285       iterator tmp = allocate(new_size);
00286       iterator tmp_finish = std::uninitialized_copy(start, position, tmp);
00287       std::uninitialized_fill_n(tmp_finish, n, x);
00288       tmp_finish += n;
00289       tmp_finish = std::uninitialized_copy(position, finish, tmp_finish);
00290       deallocate();
00291       start = tmp;
00292       finish = tmp_finish;
00293       end_of_storage = tmp + new_size;
00294    }
00295 }
00296 
00297 //#############################################################################
00298 
00299 template <class T> typename BCP_vec<T>::iterator
00300 BCP_vec<T>::insert(iterator position, const_reference x){
00301    const size_t n = position - start;
00302    if (finish != end_of_storage && position == finish) {
00303       BCP_CONSTRUCT(finish++, x);
00304    } else {
00305       insert_aux(position, x);
00306    }
00307    return start + n;
00308 }
00309 
00310 //#############################################################################
00311 
00312 
00313 template <class T> void
00314 BCP_vec<T>::keep_by_index(const BCP_vec<int>& positions){
00315    BCP_vec_sanity_check(positions.begin(), positions.end(), size());
00316    unchecked_keep_by_index(positions.begin(), positions.end());
00317 }
00318 //-----------------------------------------------------------------------------
00319 
00320 template <class T> void
00321 BCP_vec<T>::unchecked_keep_by_index(const BCP_vec<int>& positions){
00322    unchecked_keep_by_index(positions.begin(), positions.end());
00323 }
00324 
00325 //#############################################################################
00326 
00327 template <class T> void
00328 BCP_vec<T>::erase_by_index(const BCP_vec<int>& positions){
00329    BCP_vec_sanity_check(positions.begin(), positions.end(), size());
00330    unchecked_erase_by_index(positions.begin(), positions.end());
00331 }
00332 
00333 //-----------------------------------------------------------------------------
00334 
00335 template <class T> void
00336 BCP_vec<T>::unchecked_erase_by_index(const BCP_vec<int>& positions){
00337    unchecked_erase_by_index(positions.begin(), positions.end());
00338 }
00339 
00340 //#############################################################################
00341 
00342 template <class T> void
00343 BCP_vec<T>::keep_by_index(BCP_vec<int>::const_iterator firstpos,
00344                           BCP_vec<int>::const_iterator lastpos) {
00345    BCP_vec_sanity_check(firstpos, lastpos, size());
00346    unchecked_keep_by_index(firstpos, lastpos);
00347 }
00348 
00349 //-----------------------------------------------------------------------------
00350 
00351 template <class T> void
00352 BCP_vec<T>::unchecked_keep_by_index(BCP_vec<int>::const_iterator firstpos,
00353                                     BCP_vec<int>::const_iterator lastpos) {
00354    if (firstpos == lastpos) {
00355       clear();
00356    } else {
00357       iterator target = start;
00358       while ( firstpos != lastpos )
00359          *target++ = operator[](*firstpos++);
00360       BCP_DESTROY_RANGE(target, finish);
00361       finish = target;
00362    }
00363 }
00364 
00365 //#############################################################################
00366 
00367 template <class T> void
00368 BCP_vec<T>::erase_by_index(BCP_vec<int>::const_iterator firstpos,
00369                            BCP_vec<int>::const_iterator lastpos) {
00370    BCP_vec_sanity_check(firstpos, lastpos, size());
00371    unchecked_erase_by_index(firstpos, lastpos);
00372 }
00373 
00374 //-----------------------------------------------------------------------------
00375 
00376 template <class T> void
00377 BCP_vec<T>::unchecked_erase_by_index(BCP_vec<int>::const_iterator firstpos,
00378                                      BCP_vec<int>::const_iterator lastpos) {
00379    if (firstpos == lastpos)
00380       return;
00381    --lastpos;
00382    int source;
00383    iterator target = entry(*firstpos);
00384    while (firstpos != lastpos){
00385       source = *firstpos + 1;
00386       ++firstpos;
00387       if (*firstpos > source)
00388          target = std::copy( entry(source), entry(*firstpos), target );
00389    }
00390    iterator oldfinish = finish;
00391    finish = std::copy( entry(*firstpos + 1), end(), target );
00392    BCP_DESTROY_RANGE(finish, oldfinish);
00393 }
00394 
00395 //#############################################################################
00396 
00397 template <class T> void
00398 BCP_vec<T>::update(const BCP_vec<int>& positions,
00399                    const BCP_vec<T>& values){
00400    if (positions.size() != values.size())
00401       throw BCP_fatal_error("BCP_vec::update() called with unequal sizes.\n");
00402    BCP_vec_sanity_check(positions.begin(), positions.end(), size());
00403    unchecked_update(positions, values);
00404 }
00405 
00406 //-----------------------------------------------------------------------------
00407 
00408 template <class T> void
00409 BCP_vec<T>::unchecked_update(const BCP_vec<int>& positions,
00410                              const BCP_vec<T>& values){
00411    if (positions.size() == 0)
00412       return;
00413    const_iterator val = values.begin();
00414    BCP_vec<int>::const_iterator pos = positions.begin();
00415    const BCP_vec<int>::const_iterator lastpos = positions.end();
00416    while (pos != lastpos)
00417       operator[](*pos++) = *val++;
00418 }
00419 
00420 //#############################################################################
00421 
00422 template <class T>
00423 bool operator==(const BCP_vec<T>& x, const BCP_vec<T>& y) {
00424    return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
00425 }
00426 
00427 template <class T>
00428 bool operator< (BCP_vec<T>& x, BCP_vec<T>& y) {
00429    return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
00430 }

Generated on Wed Dec 3 14:32:34 2003 for BCP by doxygen 1.3.5