vector.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 866 行 · 第 1/3 页
C
866 行
//
// Copyright (C) 1991 Texas Instruments Incorporated.
//
// Permission is granted to any individual or institution to use, copy, modify,
// and distribute this software, provided that this complete copyright and
// permission notice is maintained, intact, in all copies and supporting
// documentation.
//
// Texas Instruments Incorporated provides this software "as is" without
// express or implied warranty.
//
// Updated: JAM 08/12/92 -- modernize template syntax, remove macro hacks
// Updated: JAM 08/12/92 -- split up comma expr in some funcs because of
// a a BC++ bug when Type was a float or double
#ifndef VECTORC
#define VECTORC
#include <cool/Vector.h>
// compare_s -- static data member of CoolVector, pointer to Type operator==
template<class Type>
Boolean (*CoolVector<Type>::compare_s)(const Type&, const Type&) = &CoolVector_is_data_equal;
// CoolVector<Type> () -- Empty constructor for the CoolVector class.
// Input: None
// Output: None
template<class Type>
CoolVector<Type>::CoolVector () {
this->data = NULL; // NULL data pointer
}
// CoolVector<Type> (size_t) -- constructor that specifies number of elements.
// Input: Number of elements
// Output: None
template<class Type>
CoolVector<Type>::CoolVector (size_t n)
: CoolBaseVector(n)
{
this->data = new Type[n]; // Allocate memory
}
// CoolVector<Type> (void*, size_t) -- constructor that specifies user-defined static
// size storage and number of elements
// Input: Pointer to storage, number of elements
// Output: None
template<class Type>
CoolVector<Type>::CoolVector (void* s, size_t n)
: CoolBaseVector(n)
{
this->data = (Type*) s; // Pointer to storage block
this->alloc_size = INVALID_ALLOCSZ(); // Indicate static-size object
}
// CoolVector<Type> (size_t, Type&) -- constructor that specifies number of elements
// and also an initialization value to set all
// elements.
// Input: Number of elements and Type reference to initialization value
// Output: None
template<class Type>
CoolVector<Type>::CoolVector (size_t n, const Type& value)
: CoolBaseVector(n)
{
this->data = new Type[n]; // Allocate memory
for (size_t i = 0; i < n; i++) // For each element in Vector
this->data[i] = value; // Set initial value
this->number_elements = n; // Set element count
}
// CoolVector<Type> (size_t,size_t, ...) -- constructor that specifies number of elements
// and also a variable number of references to
// initialization values for successive elements
// in the vector.
// Input: Number of elements, number of initial values, and initial values
// Output: None
// Note: Arguments in ... can only be pointers, primitive types like int,
// and NOT OBJECTS, passed by reference or value, like vectors, matrices;
// because constructors must be known and called at compile time!!!
// Cannot have char in ..., because char is 1 instead of 4 bytes, and
// va_arg expects sizeof(Type) a multiple of 4 bytes.
template<class Type>
CoolVector<Type>::CoolVector (size_t n, size_t nv, Type v0, ...)
: CoolBaseVector(n)
{
#if ERROR_CHECKING
if (((sizeof(Type) % 4) != 0) || // Cause alignment problems
(sizeof(Type) > 8)) // User defined classes?
this->va_arg_error(#Type, sizeof(Type)); // So, cannot use this constructor
#endif
typedef Type xType; // need Type expanded all the way before call to macro va_arg
this->data = new Type[n]; // Allocate memory
this->number_elements = nv; // Update element count
this->data[0] = v0;
va_list argp; // Declare argument list
va_start (argp, v0); // Initialize macro
for (size_t i = 1; i < nv; i++) // For remaining values given
//this->data[i] = va_arg(argp,Type); // Extract and assign
this->data[i] = va_arg(argp, xType); // for v2.1 with fakeup cpp
va_end (argp);
}
// CoolVector<Type> (CoolVector<Type>&) -- Copy constructor
// Input: CoolVector reference
// Output: None
template<class Type>
CoolVector<Type>::CoolVector (const CoolVector<Type>& v)
: CoolBaseVector(v)
{
this->data = new Type[v.size]; // Allocate enough storage
for (size_t i = 0; i < v.number_elements; i++) // For each element in CoolVector
this->data[i] = v.data[i]; // Copy value
}
// ~CoolVector<Type> () -- Destructor for CoolVector class that frees up storage.
// Input: None
// Output: None
template<class Type>
CoolVector<Type>::~CoolVector () {
if (this->size != 0 &&
this->alloc_size != INVALID_ALLOCSZ()) // If not user-provide storage
delete [] this->data; // Free up the memory
}
// void fill () -- Fill elements `start' through `end' inclusive with valuen
// Input: Type reference, start inclusive, and end index exclusive
// Output: None
template<class Type>
void CoolVector<Type>::fill (const Type& value, size_t start, size_t end) {
#if ERROR_CHECKING
if (start >= this->number_elements) // If start out of range
this->fill_start_error (#Type, start); // Raise exception
if (end < start || end > this->number_elements) // If end out of range
this->fill_end_error (#Type, end); // Raise exception
#endif
for (size_t i = start; i < end; i++) // For each element in range
this->data[i] = value; // Assign new value
this->curpos = INVALID_ALLOCSZ(); // Invalidate current position
}
// void copy () -- Copy a specified range of elements from one vector to this
// Input: CoolVector reference, start inclusive, and end index exclusive
// Output: None
template<class Type>
void CoolVector<Type>::copy (const CoolVector<Type>& v, size_t start, size_t end){
#if ERROR_CHECKING
if (start >= v.number_elements) // If start out of range
this->copy_start_error (#Type, start); // Raise exception
if (end < start || end > v.number_elements) // If end out of range
this->copy_end_error (#Type, end); // Raise exception
#endif
if (this->size < end) { // If not enough memory
#if ERROR_CHECKING
if (alloc_size == INVALID_ALLOCSZ()) // If static size vector
this->copy_error (#Type); // Raise exception
#endif
this->grow(end);
}
size_t i;
for (i = start; i < end; i++) // For each element in range
this->data[i] = v.data[i]; // Assign new value
if (i > this->number_elements) // If we added new elements
this->number_elements = i; // Update element count
this->curpos = i; // Update current position
}
// search -- Find a subsequence of elements in a CoolVector
// Input: CoolVector reference to subsequence searching for,
// start inclusive, and end index exclusive
// Output: TRUE/FALSE; current position updated if found
template<class Type>
Boolean CoolVector<Type>::search (const CoolVector<Type>& v, size_t start, size_t end) {
register size_t i, j;
end -= v.number_elements;
for (i = start; i < end; i++) { // Find start of subsequence
for (j = 0; j < v.number_elements; j++)
if (!(*this->compare_s)(this->data[i+j],v.data[j])) // If not equal
goto again2; // try again
this->curpos = i; // Point to start of sequence
return TRUE; // Return starting index
again2:;
}
return FALSE;
}
// Boolean operator== () -- Compare the elements of this CoolVector with a second
// Input: Reference to vector object
// Output: TRUE/FALSE
template<class Type>
Boolean CoolVector<Type>::operator== (const CoolVector<Type>& v) const {
register size_t i;
if (this->number_elements != v.number_elements) // If not same number
return FALSE; // Then not equal
for (i = 0; i < this->number_elements; i++) // For each element in vector
if (!(*this->compare_s)(this->data[i],v.data[i]))
return FALSE;
return TRUE;
}
// Boolean is_data_equal () -- Default data comparison function if user has
// not provided another method
// Input: Two Type references
// Output: TRUE/FALSE
template<class Type>
Boolean CoolVector_is_data_equal (const Type& t1, const Type& t2) {
return (t1 == t2);
}
// void set_compare () -- Specify the comparison function to be used in
// logical comparisons of vector objects
// Input: Pointer to a compare function
// Output: None
template<class Type>
void CoolVector<Type>::set_compare (register Boolean (*cf)(const Type&, const Type&)) {
if (cf)
this->compare_s = cf; // Set to user function
else
this->compare_s = &CoolVector_is_data_equal; // or to default
}
// CoolVector<Type&> operator= () -- Overload the assignment operator
// Input: Reference to CoolVector object
// Output: Reference to copied CoolVector object
template<class Type>
CoolVector<Type>& CoolVector<Type>::operator= (const CoolVector<Type>& v) {
if (this->size < v.size) { // If not enough memory
#if ERROR_CHECKING
if (alloc_size == INVALID_ALLOCSZ()) // If static size vector
this->assign_error (#Type); // Raise exception
#endif
if (this->size != 0)
delete [] this->data; // Free it up
this->data = new Type[v.size]; // and allocate bigger memory
this->size = v.size; // Set new vector size
}
this->CoolBaseVector::operator= (v); // Base class assignment
for (size_t i = 0; i < v.number_elements; i++) // For each element
this->data[i] = v.data[i]; // Copy value
return *this; // Return CoolVector reference
}
// CoolVector<Type>& operator= () -- Overload the assignment operator to assign a
// single value to all the elements of a vector
// Input: Type reference to fill value
// Output: Reference to updated CoolVector object
template<class Type>
CoolVector<Type>& CoolVector<Type>::operator= (const Type& value) {
for (size_t i = 0; i < this->number_elements; i++) // For each element in CoolVector
this->data[i] = value; // Set initial value
this->curpos = INVALID_POS(); // Point to first element
return *this; // Return CoolVector reference
}
// Boolean find () -- Find first/next occurrence of element in a CoolVector.
// from start or end of vector respectively if dir = +1, -1.
// Input: Type reference to search value, starting index
// Output: TRUE/FALSE
template<class Type>
Boolean CoolVector<Type>::find (const Type& value, size_t start, int dir) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?