//
// 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.
//
// Created: MBN 08/31/89 -- Initial design and implementation
// Updated: MBN 10/03/89 -- Predecrement instead of postdecrement on prev()
// Updated: MBN 10/10/89 -- Added current_position() method for Iterator<Type>
//
// The Vector class is publicly derived from  the Generic class  and is used to
// implement non-type specific functionality for the parameterized Vector<Type>
// class. In this manner, code common to all instances of  the Vector class can
// be shared to reduce code  replication. The Vector<Type>  class is dynamic in
// the sense that an object can grow dynamically if necessary.  The growth size
// is determined by the  value  of a  static  allocation size variable  for the
// class.  However, fixed length vectors  are also  supported by  setting  this
// variable  to INVALID.   The Vector class  implements the notion of a current
// position. This is useful  for iterating through  the  elements of a  vector.
// The current position is maintained in an integer and  is set or reset by all
// methods  affecting elements in the  Vector class. Methods to reset,  move to
// the next and previous, find,  and get the value at  the current position are
// provided.
// 
// Each Vector object contains a protected data section that has a slot to hold
// the current  size  of the  vector and a pointer  to an allocated block large
// enough to hold "size" elements of type "Type". A  slot to hold the number of
// elements is also provided. A single protected  slot contains  a pointer to a
// compare  function to be  used in equality operations.  The  default function
// used is the built-in == operator.  Finally, a current  position slot is used
// to maintain the index of the last element affected by an operation.
//
// Three different constructors are  provided.  The first constructor  takes no
// arguments and creates an empty Vector object. The second constructor takes a
// single argument specifying  the  initial  size  of  the  Vector.   The third
// constructor takes takes a  single argument consisting of  a  reference  to a
// Vector and duplicates its size and element values.
// 
// Methods are provided  to  destructively   perform reverse, remove,  replace,
// prepend, append, merge, sort, and insert operations on a Vector object.   In
// addition, several miscelaneous methods  support  resize, copy, fill, length,
// search,  push, push_new, pop,  and   position functions.  The assignment and
// element accessor functions allow for individual elements of the vector to be
// set and read.  Finally, both equality and non-equality tests are implemented
// via  a user-defined  comparison function  as  well as  overloaded input  and
// output operators.
//

#ifndef BASE_VECTORH				// If no definition for Vector
#define BASE_VECTORH				// define the vector symbol

#ifndef GEN_CLASSH				// If no definition for Generic
#include <cool/Gen_class.h>				// Include the class header
#endif

#define MEM_BLK_SZ 100

typedef long Vector_state;			// Current position state

class Vector : public Generic {
protected:
  long size;					// Size of allocated storage 
  long number_elements;				// Number of elements in vector
  int alloc_size;				// Allocation size for growth
  static float growth_ratio;			// If non-zero, growth ratio 
  Vector_state curpos;				// Keeps current position

  void bracket_error (const char*, const long) CONST;   // Raise exception
  void value_error (const char*) CONST;		        // Raise exception
  void resize_error (const char*, const long) CONST;	// Raise exception
  void static_error (const char*) CONST;		// Raise exception
  void assign_error (const char*) CONST;		// Raise exception
  void fill_start_error(const char*,const long) CONST;	// Raise exception
  void fill_end_error (const char*, const long) CONST;	// Raise exception
  void copy_start_error(const char*,const long) CONST;	// Raise exception
  void copy_end_error (const char*, const long) CONST;	// Raise exception
  void copy_error (const char*);			// Raise exception
  void remove_error (const char*) CONST;		// Raise exception

public:
  Vector ();					// Vector v; 
  Vector (long);				// Vector v(10);
  Vector (const Vector&);			// Vector v = y;
  ~Vector ();					// Destructor

  inline void reset ();				// Invalidate current position
  inline Boolean next ();			// Advance current position
  inline Boolean prev ();			// Backup current position 
  inline long position () CONST;		// Return current position
  inline Vector_state& current_position ();	// Set/Get current position

  Vector& operator= (const Vector&);		// Overload assignment operator
  void clear();					// Removes all elements
  Boolean is_empty();				// Any elements in vector?
  inline long length () CONST;			// Number of elements
  inline long capacity () CONST;		// Maximum number of elements

  long set_length (long, const char*);		// Set number of elements
  void set_growth_ratio (float, const char*);	// Set growth percentage
  void set_alloc_size (int, const char*);	// Set alloc size
};


// void reset () -- Set current position to INVALID.
// Input:           None
// Output:          None

inline void Vector::reset () {
  this->curpos = INVALID;			// Invalidate current position
}


// Boolean next () -- Increment current position. If INVALID, set to first.
// Input:             None
// Output:            TRUE/FALSE

inline Boolean Vector::next () {
  return ((++this->curpos >= this->number_elements) ?
	  (this->curpos = INVALID, FALSE) : TRUE);
}
    

// Boolean prev () -- Decrement current position. If INVALID, set to last.
// Input:             None
// Output:            TRUE/FALSE

inline Boolean Vector::prev () {
  if (this->curpos == INVALID)			// If INVALID current position
    this->curpos = this->number_elements;	// Set to last element
  return (--this->curpos >= 0);			// Else decrement and return
}


// long length () -- Return the number of elements in a Vector object.
// Input:            None
// Output:           Integer representing number of elements

inline long Vector::length () CONST {
  return (this->number_elements);
}


// long capacity () -- Return maximum number of elements Vector object can hold.
// Input:              None
// Output:             Integer value of maximum number of elements

inline long Vector::capacity () CONST {
  return (this->size);				// Maximum number of elements
}


// long position () -- Return current position.
// Input:              None
// Output:             Integer representing current position

inline long Vector::position () CONST {
  return this->curpos;
}


// current_position () -- Return current position state
// Input:                 None
// Output:                Reference to current position state

inline Vector_state& Vector::current_position () {
  return this->curpos;
}

#endif						// End of BASE_VECTORH

