/*********************************************************************



  Filename:  vect_it.cpp

  Section:   13     Templates

  Compiler:  Borland C++     Version 5.0       Summer 1996

  C++ Distilled: Descriptions, Prescriptions and Style  By Ira Pohl



*********************************************************************/



//templates for vect with associated iterator class

#include  

#include        //for assert





template  class  vect_iterator;

template 

class vect {

public:

   //constructors and destructor

   typedef T* iterator;

   explicit vect(int n = 10);//default constructor

   vect(const vect& v);//copy constructor

   vect(const T a[], int n);//from array

   ~vect() { delete [] p; }

   iterator begin(){ return p;}

   iterator end(){ return p + size;}

   T&  operator[](int i) const;

   vect& operator=(const vect& v);

   friend vect

      operator+(const vect& v1,

                const vect& v2);

   friend ostream&

      operator<<(ostream& out,

                 const vect& v);

   friend class vect_iterator;

private:

   T*    p;     //base pointer

   int   size;  //number of elements

};





//default constructor

//default constructor

template 

vect::vect(int n = 10): size(n)

{

   assert(n > 0);

   p = new T[size];

   assert(p != 0);

}





//copy constructor

template

vect::vect(const vect& v)

{

   size = v.size;

   p = new T[size];

   assert (p != 0);

   for (int i = 0; i < size; ++i)

      p[i] = v.p[i];

}



//Initializing vect from an array

template

vect::vect(const T a[], int n) : size (n)

{

   assert (n > 0);

   p = new T[size];

   assert (p != 0);

   for (int i = 0; i < size; ++i)

      p[i] = a[i];

}



//overloaded subscript operator

template

T& vect::operator[](int i) const

{

   assert (i >= 0 && i < size);

   return p[i];

}



//overloaded output operator

template

ostream& operator<<(ostream& out,

                    const vect& v)

{

   for (int i = 0; i <= (v.size-1); ++i)

      out << v.p[i] << '\t';

   return (out << endl);

}



template

vect& vect::operator=

          (const vect& v)

{

   assert(v.size == size);

   for (int i = 0; i < size; ++i)

      p[i] = v.p[i];

   return (*this);

}



template vect

   operator+(const vect& v1, const vect& v2)

{

   int   s = (v1.size < v2.size) ?

             v1.size : v2.size;

   vect  sum(s);

   if (v1.size != v2.size)

      cerr <<

          "adding different size arrays "

           << v1.size << " and " << v2.size

           << endl;

   for (int i = 0; i < s; ++i)

      sum.p[i] = p[i] + v.p[i];

   return sum;

}



template

void init_vect(vect& v,

          int start, int incr)

{

   for (int i = 0; i <= v.ub(); ++i) {

      v[i] = start;

      start += incr;

   }

}



int main()

{

   vect v(5);

   vect::iterator p ;

   int i = 0;



   for (p = v.begin() ; p != v.end(); ++p)

      *p = 1.5 + i++;



   do {

      --p;

      cout << *p << " , ";

   } while (p != v.begin());

   cout << endl;

}