// Copyright (C) 2000, International Business Machines // Corporation and others. All Rights Reserved. #ifndef _BCP_VECTOR_GENERAL_H #define _BCP_VECTOR_GENERAL_H // This file is fully docified. #include /** The class BCP_vec serves the same purpose as the vector class in the standard template library. The main difference is that while the vector class is likely to be implemented as a memory array, BCP_vec is implemented that way. Also, BCP_vec has a number of extra member methods, most of them exist to speed up operations (e.g., there are unchecked versions of the insert member methods, i.e., the method does not check whether there is enough space allocated to fit the new elements). */ template class BCP_vec { public: /**@name Type definitions (needed for using the STL) */ /*@{*/ /// typedef size_t size_type; /// typedef T value_type; /// typedef T* iterator; /// typedef const T* const_iterator; /// typedef T& reference; /// typedef const T& const_reference; /*@}*/ private: inline void destroy(iterator pos); inline void destroy_range(iterator first, iterator last); inline void construct(iterator pos); inline void construct(iterator pos, const_reference x); protected: /**@name Internal methods */ /*@{*/ /** allocate raw, uninitialized memory for len entries. */ inline iterator allocate(size_t len); /** Destroy the entries in the vector and free the memory allocated for the vector. */ inline void deallocate(); /** insert x into the given position in the vector. Reallocate the vector if necessary. */ void insert_aux(iterator position, const_reference x); /*@}*/ protected: /**@name Data members */ /*@{*/ /** Iterator pointing to the beginning of the memory array where the vector is stored. */ iterator start; /** Iterator pointing to right after the last entry in the vector. */ iterator finish; /** Iterator pointing to right after the last memory location usable by the vector without reallocation. */ iterator end_of_storage; /*@}*/ public: /**@name Constructors / Destructor */ /*@{*/ /** The default constructor initializes the data members as 0 pointers. */ BCP_vec(); /** The copy constructor copies over the content of x. */ BCP_vec(const BCP_vec& x); /** Construct a BCP_vec with n elements, all initialized with the second argument (or initialized with the default constructor of T if the second argument is missing). */ BCP_vec(const size_t n, const_reference value = T()); /** Construct a BCP_vec by copying the elements from first to last-1. */ BCP_vec(const_iterator first, const_iterator last); /** Construct a BCP_vec by copying num objects of type T from the memory starting at x. */ BCP_vec(const T* x, const size_t num); /** The destructor deallocates the memory allocated for the BCP_vec. */ virtual ~BCP_vec() { deallocate(); } /*@}*/ /**@name Query methods */ /*@{*/ /** Return an iterator to the beginning of the object. */ iterator begin() { return start; } /** Return a const iterator to the beginning of the object. */ const_iterator begin() const { return start; } /** Return an iterator to the end of the object. */ iterator end() { return finish; } /** Return a const iterator to the end of the object. */ const_iterator end() const { return finish; } /** Return an iterator to the i-th entry. */ iterator entry(const int i) { return start + i; } /** Return a const iterator to the i-th entry. */ const_iterator entry(const int i) const { return start + i; } /** Return the index of the entry pointed to by pos. */ size_t index(const_iterator pos) const { return size_t(pos - start); } /** Return the current number of entries. */ size_t size() const { return finish - start; } /** Return the capacity of the object (space allocated for this many entries). */ size_t capacity() const { return end_of_storage - start;} /** Test if there are any entries in the object. */ bool empty() const { return start == finish; } /** Return a reference to the i-th entry. */ reference operator[](const size_t i) { return *(start + i); } /** Return a const reference to the i-th entry. */ const_reference operator[](const size_t i) const { return *(start + i); } /** Return a reference to the first entry. */ reference front() { return *start; } /** Return a const reference to the first entry. */ const_reference front() const { return *start; } /** Return a reference to the last entry. */ reference back() { return *(finish - 1); } /** Return a const reference to the last entry. */ const_reference back() const { return *(finish - 1); } /*@}*/ /**@name General modifying methods */ /*@{*/ /** Reallocate the object to make space for n entries. */ void reserve(const size_t n); /** Exchange the contents of the object with that of x. */ inline void swap(BCP_vec& x); /** Copy the contents of x into the object and return a reference the the object itself. */ BCP_vec& operator=(const BCP_vec& x); /** Copy num entries of type T starting at the memory location x into the object. (x is a void pointer since it might be located somewhere in a buffer and therefore might not be aligned for type T entries.) */ void assign(const void* x, const size_t num); /** Insert num entries starting from memory location first into the vector from position pos. */ void insert(iterator position, const void* first, const size_t num); /** Insert the entries [first,last) into the vector from position pos. */ void insert(iterator position, const_iterator first, const_iterator last); /** Insert n copies of x into the vector from position pos. */ void insert(iterator position, const size_t n, const_reference x); /** Insert x (a single entry) into the vector at position pos. Return an iterator to the newly inserted entry. */ iterator insert(iterator position, const_reference x); /** Append the entries in x to the end of the vector. */ void append(const BCP_vec& x) { insert(end(), x.begin(), x.end()); } /** Append the entries [first,last) to the end of the vector. */ void append(const_iterator first, const_iterator last) { insert(end(), first, last); } /** Append x to the end of the vector. Check if enough space is allocated (reallocate if necessary). */ inline void push_back(const_reference x); /** Append x to the end of the vector. Does not check if enough space is allcoated. */ inline void unchecked_push_back(const_reference x); /** Delete the last entry. */ inline void pop_back(); /** Delete every entry. */ inline void clear(); /** Update those entries listed in positions to the given values. The two argument vector must be of equal length. Sanity checks are done on the given positions. */ inline void update(const BCP_vec& positions, const BCP_vec& values); /** Same as the previous method but without sanity checks. */ inline void unchecked_update(const BCP_vec& positions, const BCP_vec& values); /*@}*/ //-------------------------------------------------------------------------- /**@name Methods for selectively keeping entries */ /*@{*/ /** Keep only the entry pointed to by pos. */ inline void keep(iterator pos); /** Keep the entries [first,last). */ inline void keep(iterator first, iterator last); /** Keep the entries indexed by indices. Abort if the indices are not in increasing order, if there are duplicate indices or if any of the indices is outside of the range [0,size()). */ inline void keep_by_index(const BCP_vec& positions); /** Same as the previous method but without the sanity checks. */ inline void unchecked_keep_by_index(const BCP_vec& positions); /** Keep the entries indexed by the values in [firstpos,lastpos). Abort if the indices are not in increasing order, if there are duplicate indices or if any of the indices is outside of the range [0,size()). */ inline void keep_by_index(const int * firstpos, const int * lastpos); /** Same as the previous method but without the sanity checks. */ void unchecked_keep_by_index(const int * firstpos, const int * lastpos); /*@}*/ //------------------------------------------------------------------------- /**@name Methods for selectively erasing entries */ /*@{*/ /** Erase the entry pointed to by pos. */ inline void erase(iterator pos); /** Erase the entries [first,last). */ inline void erase(iterator first, iterator last); /** Erase the entries indexed by indices. Abort if the indices are not in increasing order, if there are duplicate indices or if any of the indices is outside of the range [0,size()). */ inline void erase_by_index(const BCP_vec& positions); /** Same as the previous method but without the sanity check. */ inline void unchecked_erase_by_index(const BCP_vec& positions); /** Like the other erase_by_index method (including sanity checks), just the indices of the entries to be erased are given in [firstpos,lastpos). */ inline void erase_by_index(const int * firstpos, const int * lastpos); /** Same as the previous method but without the sanity checks. */ void unchecked_erase_by_index(const int * firstpos, const int * lastpos); /*@}*/ }; //############################################################################## template bool operator==(const BCP_vec& x, const BCP_vec& y) { return x.size() == y.size() && equal(x.begin(), x.end(), y.begin()); } template bool operator< (BCP_vec& x, BCP_vec& y) { return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } //############################################################################# /** This function purges the entries [first,last) from the vector of pointers pvec. Since these entries are pointers, first operator delete is invoked for each of them, then the pointers are erased from the vector. */ template void purge_ptr_vector(BCP_vec& pvec, typename BCP_vec::iterator first, typename BCP_vec::iterator last) { typename BCP_vec::iterator origfirst = first; while (first != last) { delete *first; *first = 0; ++first; } pvec.erase(origfirst, last); } /** This function purges all the entries from the vector of pointers pvec. Since these entries are pointers, first operator delete is invoked for each of them, then the pointers are erased from the vector. */ template void purge_ptr_vector(BCP_vec& pvec) { purge_ptr_vector(pvec, pvec.begin(), pvec.end()); } /** This function purges the entries indexed by [first,last) from the vector of pointers pvec. Since these entries are pointers, first operator delete is invoked for each of them, then the pointers are erased from the vector. */ template void purge_ptr_vector_by_index(BCP_vec& pvec, typename BCP_vec::const_iterator first, typename BCP_vec::const_iterator last) { BCP_vec::const_iterator origfirst = first; while (first != last) { delete pvec[*first]; pvec[*first] = 0; ++first; } pvec.erase_by_index(origfirst, last); } /** This function keeps only the entries indexed by [first,last) from the vector of pointers pvec. No sanity check is performed. */ template void keep_ptr_vector_by_index(BCP_vec& pvec, typename BCP_vec::const_iterator first, typename BCP_vec::const_iterator last) { BCP_vec::const_iterator origfirst = first; const int pvec_size = pvec.size(); int i; for (i = 0; i < pvec_size && first != last; ++i) { if (i != *first) { delete pvec[i]; pvec[i] = 0; } else { ++first; } } for ( ; i < pvec_size; ++i) { delete pvec[i]; pvec[i] = 0; } pvec.keep_by_index(origfirst, last); } /* Now include the implementation of the methods so the compiler could instantiate any requested vector class */ #include #include "BCP_vector_sanity.hpp" #include "BCP_error.hpp" #include "BCP_vector_bool.hpp" #include "BCP_vector_char.hpp" #include "BCP_vector_short.hpp" #include "BCP_vector_int.hpp" #include "BCP_vector_double.hpp" #include "BCP_vector_general.hpp" #endif