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 + -
显示快捷键?