vector.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 866 行 · 第 1/3 页
C
866 行
register size_t i = start;
register size_t n = this->number_elements - start; // max number of elmts to search
if (dir == -1) n = start + 1;
for (; n > 0; n--, i += dir)
if ((*(this->compare_s))(this->data[i], value) == TRUE) {
this->curpos = i;
return TRUE;
}
return FALSE;
}
// void grow () -- Adjust the memory size of a CoolVector to accomodate some size
// Input: Interger number of elements to hold
// Output: None
template<class Type>
void CoolVector<Type>::grow (size_t min_size) {
size_t new_size = (size_t)(this->size * (1.0 + growth_ratio)); // New size?
if (new_size < min_size) new_size = min_size + alloc_size;
resize(new_size);
}
// void resize () -- Adjust the memory size of a CoolVector to accomodate some size
// Input: Interger number of elements to hold
// Output: None
template<class Type>
void CoolVector<Type>::resize (size_t new_size) {
if (new_size <= this->size) { // Don't bother shrinking
#if ERROR_CHECKING
if (new_size < 0) // If index out of range
this->resize_error (#Type,new_size); // Raise exception
#endif
return;
}
#if ERROR_CHECKING
if (alloc_size == INVALID_ALLOCSZ()) // If static size vector
this->static_error (#Type); // Raise exception
#endif
Type* temp = new Type[new_size]; // Allocate storage
for (size_t i = 0; i < this->number_elements; i++)// For each element in Vector
temp[i] = this->data[i]; // Copy into new storage
if (this->size != 0)
delete [] this->data; // Free up old memory
this->data = temp; // Assign new memory block
this->size = new_size; // Save new size value
}
// push -- Add element to end of the CoolVector
// Input: Type reference
// Output: TRUE if successful, FALSE if could not grow vector
template<class Type>
Boolean CoolVector<Type>::push (const Type& value) {
if (this->number_elements == this->size) { // If not enough memory
if (this->alloc_size == INVALID_ALLOCSZ()) // If not allowed to grow
return FALSE; // Return failure flag
this->grow(this->size+1); // Else grow the CoolVector
}
this->curpos = this->number_elements; // Set current position
this->data[this->number_elements++] = value; // Assign new value
return TRUE; // Return success status
}
// push_new -- Add an element if it is not already there
// Input: Reference to Type
// Output: TRUE/FALSE
template<class Type>
Boolean CoolVector<Type>::push_new (const Type& value) {
if (this->number_elements == this->size && this->alloc_size == INVALID_ALLOCSZ())
return FALSE; // Return failure flag
if (this->find(value, this->number_elements-1, -1))
return FALSE; // If already in CoolVector
if (this->number_elements >= this->size) // If not enough memory
this->grow(this->size+1); // Else grow the Vector
this->curpos = this->number_elements; // Set current position
this->data[this->number_elements++] = value; // Assign new value
return TRUE; // Return success status
}
// pop -- Return last element in the CoolVector
// Input: None
// Output: Type reference to last element in CoolVector
template<class Type>
Type& CoolVector<Type>::pop () {
if (this->number_elements > 0) { // If there are elements
this->curpos = INVALID_POS(); // Invalidate current position
return (this->data[--this->number_elements]); // Return the last one
}
return (this->data[0]); // Return an arbitrary one
}
// reverse -- Destructively reverse the order of elements in a CoolVector
// Input: None
// Output: None
template<class Type>
void CoolVector<Type>::reverse () {
Type temp;
for (size_t i = 0, j = this->number_elements-1; // Counting from front and rear
i < this->number_elements / 2; i++, j--) { // until we reach the middle
temp = this->data[i]; // Save front data item
this->data[i] = this->data[j]; // Switch with rear data item
this->data[j] = temp; // Copy new rear data item
}
this->curpos = INVALID_POS(); // Invalidate current position
}
// remove -- Destructively remove item at current position.
// Shift remaining elmts to preserve order in vector.
// Input: None
// Output: Type reference to item removed
template<class Type>
Type CoolVector<Type>::remove () {
IterState i = this->curpos;
if (i == INVALID_POS()) this->remove_error("Type");
Type value = this->data[i];
Type* elmts = &this->data[i]; // Shift elements by 1 place
while (++i < this->number_elements) { // Copy over current
*elmts = *(elmts + 1); // Use assignment of class Type
elmts++; // Use assignment of class Type
}
this->number_elements--; // Update element count
if (this->curpos == this->number_elements) // If past end of vector
this->curpos = INVALID_POS(); // Invalidate current position
return value; // Return Vector reference
}
// remove -- Destructively remove the first occurrence of an element
// Input: Type reference
// Output: TRUE if element found and removed, FALSE otherwise
template<class Type>
Boolean CoolVector<Type>::remove (const Type& value, int dir) {
size_t start = 0;
if (dir == -1) start = this->number_elements - 1;
if (this->find(value, start, dir)) { // When found
size_t i = this->curpos;
Type* elmts = &this->data[i]; // Shifts remaining elements
while (++i < this->number_elements) { // by 1 place
*elmts = *(elmts + 1); // Use assignment of class Type
elmts++; // Use assignment of class Type
}
this->number_elements--; // Update element count
return TRUE;
} else
return FALSE;
}
// remove_duplicates -- Destructively remove duplicate elements from CoolVector
// Input: None
// Output: TRUE if any removed, FALSE otherwise
template<class Type>
Boolean CoolVector<Type>::remove_duplicates () {
this->curpos = INVALID_POS(); // Invalidate current position
if (this->size == 0) return FALSE;
Boolean success = FALSE; // Return value
Type* old = this->data; // Old data
this->data = new Type[this->size]; // New data
size_t n = this->number_elements; // length of old data
this->number_elements = 0;
for (size_t i = 0; i < n; i++) { // For each element
if (!this->find(old[i], this->number_elements-1, -1)) { // if not copied yet
this->data[this->number_elements++] = old[i]; // copy value
success = TRUE; // Set flag
}
}
delete [] old; // destroy old data
return success;
}
// replace -- Destructively replace the first occurrence of an element
// Input: Two Type references
// Output: TRUE if element found and replaced, FALSE otherwise
template<class Type>
Boolean CoolVector<Type>::replace (const Type& t1, const Type& t2, int dir) {
size_t start = 0;
if (dir == -1) start = this->number_elements -1;
if (this->find(t1, start, dir)) {
this->data[this->curpos] = t2;
if (dir == +1) this->curpos++; // Point to item after replace
else this->curpos--; // in direction of dir
if (this->curpos > this->number_elements) this->curpos = INVALID_POS();
return TRUE;
} else return FALSE;
}
// replace_all -- Destructively replace all occurrences of an element
// Input: Two Type references
// Output: TRUE if any element replaced, FALSE otherwise
template<class Type>
Boolean CoolVector<Type>::replace_all (const Type& t1, const Type& t2) {
Boolean success = FALSE; // Return value
this->curpos = 0;
for (;;) {
if (!this->find(t1, this->curpos, +1)) return success;
this->data[this->curpos++] = t2; // Point to item after replace
if (this->curpos > this->number_elements) this->curpos = INVALID_POS();
}
}
// prepend -- Destructively insert the elements of some CoolVector at the beginning
// Input: CoolVector reference
// Output: TRUE if successful, FALSE if could not grow CoolVector
template<class Type>
Boolean CoolVector<Type>::prepend (const CoolVector<Type>& v) {
Type* temp; // Declare temporary
size_t old_size = this->size; // Keep old size
size_t new_size = this->number_elements + v.number_elements; // Minimum size
if (this->size < new_size) { // Enough memory?
if (this->alloc_size == INVALID_ALLOCSZ()) // If not allowed to grow
return FALSE; // Return failure flag
this->size = (size_t)(this->size * (1.0 + growth_ratio)); // New size
if (this->size < new_size) // If not enough
this->size = new_size + this->alloc_size; // use alloc_size
}
temp = new Type[this->size]; // Allocate required storage
size_t i;
for (i = 0; i < v.number_elements; i++) // For all elements
temp[i] = v.data[i]; // Copy to beginning of CoolVector
this->curpos = i; // Set current position
for (i = 0; i < this->number_elements; i++) // For each element
temp[i+v.number_elements] = this->data[i]; // Copy into new storage
if (old_size != 0)
delete [] this->data; // Free up old memory
this->data = temp; // Assign new memory block
this->number_elements += v.number_elements; // Update element count
return TRUE; // Return success flag
}
// append -- Destructively append the elements of some CoolVector at the beginning
// Input: CoolVector reference
// Output: TRUE if successful, FALSE if could not grow CoolVector
template<class Type>
Boolean CoolVector<Type>::append (const CoolVector<Type>& v) {
size_t new_size = this->number_elements + v.number_elements; // Minimum size
if (this->size < new_size) { // Enough memory?
if (this->alloc_size == INVALID_ALLOCSZ()) // If not allowed to grow
return FALSE; // Return failure flag
this->grow(new_size);
}
this->curpos = this->number_elements - 1; // Set current position
for (size_t i = 0; i < v.number_elements; i++) // For each element
this->data[i+this->number_elements] = v.data[i]; // Copy to end of CoolVector
this->number_elements += v.number_elements; // Update element count
return TRUE; // Return CoolVector reference
}
// insert_before -- Destructively insert an element before current position
// Input: Type reference
// Output: TRUE if successful, FALSE if could not grow CoolVector
template<class Type>
Boolean CoolVector<Type>::insert_before (const Type& value) {
if (this->curpos == INVALID_POS()) // If no current position
return FALSE; // Return failure flag
return this->insert_before(value, this->curpos);
}
// insert_after -- Destructively insert an element after current position
// Input: Type reference
// Output: TRUE if successful, FALSE if could not grow CoolVector
template<class Type>
Boolean CoolVector<Type>::insert_after (const Type& value) {
if (this->curpos == INVALID_POS()) // If no current position
return FALSE; // Return failure flag
return this->insert_after(value, this->curpos);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?