// Nick Cash
// CS II - 810:062 - 2
// Assignment 4


//#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//#+
//#+     Tree Class
//#+     Copyright (C) 2006 by Kevin C. O'Kane
//#+
//#+     Kevin C. O'Kane
//#+     Department of Computer Science
//#+     University of Northern Iowa
//#+     Cedar Falls, IA 50613-0507 USA
//#+
//#+     okane@cs.uni.edu
//#+     anamfianna@earthlink.net
//#+     http://www.cs.uni.edu/~okane
//#+
//#+ This program is free software; you can redistribute it and/or modify
//#+ it under the terms of the GNU General Public License as published by
//#+ the Free Software Foundation; either version 2 of the License, or
//#+ (at your option) any later version.
//#+
//#+ This program is distributed in the hope that it will be useful,
//#+ but WITHOUT ANY WARRANTY; without even the implied warranty of
//#+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//#+ GNU General Public License for more details.
//#+
//#+ You should have received a copy of the GNU General Public License
//#+ along with this program; if not, write to the Free Software
//#+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//#+
//#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

#include <iostream>
using namespace std;

template<class Type> class Vector
{

public:

      Vector(int size=100) { Size=size; x=new Type[size]; for (int i=0; i<size; i++) x[i]=0; }
      Vector(const Vector &A) { Size=A.Size; x=new Type[Size]; for (int i=0; i<Size; i++) x[i]=A.x[i]; }
      ~Vector() { delete [] x; }

      Vector operator++(int) { for (int i=0; i<Size; i++) x[i]++; return *this; } // post increment
      Vector operator++() { for (int i=0; i<Size; i++) x[i]++; return *this; }    // preincrement

      // here is the stuff I wrote/modded
      Type Sum(void) { Type y=0; for ( int i = 0; i < Size; i++) y += x[i]; return y; } // sum of contents
      
      Vector operator--(int) { for (int i=0; i<Size; i++) x[i]--; return *this; } // post decrement
      Vector operator--() { for (int i=0; i<Size; i++) x[i]--; return *this; }    // predecrement

      Vector operator+(Type a)
      {
        Vector<Type> z(Size);
        
        for ( int i = 0; i < Size; i++ )
         z.x[i] = x[i]+a;
         
        return z;       
      }

      Vector operator-(Type a)
      {
        Vector<Type> z(Size);
        
        for ( int i = 0; i < Size; i++ )
         z.x[i] = x[i]-a;
         
        return z;       
      }
      
      Vector operator*(Type a)
      {
        Vector<Type> z(Size);
        
        for ( int i = 0; i < Size; i++ )
         z.x[i] = x[i]*a;
         
        return z;       
      }
      
      Vector operator/(Type a)
      {
        Vector<Type> z(Size);
        
        for ( int i = 0; i < Size; i++ )
         z.x[i] = x[i]/a;
         
        return z;       
      }      
      // vector operations
      Vector operator+(Vector a)
      {
         if (Size!=a.Size) { cout << "Size err\n"; abort(); } // copy constructor for return value
         
         Vector<Type> z(Size);
         
         for(int i=0; i<Size;i++) z.x[i]=x[i]+a.x[i];
         
         
         return z;
      }

      Vector operator-(Vector a)
      {
         if (Size!=a.Size) { cout << "Size err\n"; abort(); } // copy constructor for return value
         
         Vector<Type> z(Size);
         
         for(int i=0; i<Size;i++) z.x[i]=x[i]-a.x[i];
         
         
         return z;
      }

      Vector operator*(Vector a)
      {
         if (Size!=a.Size) { cout << "Size err\n"; abort(); } // copy constructor for return value
         
         Vector<Type> z(Size);
         
         for(int i=0; i<Size;i++) z.x[i]=x[i]*a.x[i];
         
         
         return z;
      }      

      Vector operator/(Vector a)
      {
         if (Size!=a.Size) { cout << "Size err\n"; abort(); } // copy constructor for return value
         
         Vector<Type> z(Size);
         
         for(int i=0; i<Size;i++) z.x[i]=x[i]/a.x[i];
         
         
         return z;
      }      
      
      Vector operator=(Vector a) { delete [] x; x=new Type[a.Size]; Size=a.Size; 
                                   for(int i=0; i<Size; i++) x[i]=a.x[i]; return *this;}
      friend istream& operator>>(istream& in, Vector &a) { for (int i=0; i<a.Size; i++) in>>a.x[i]; return in;}
      friend ostream& operator<<(ostream& out, Vector &a) { for (int i=0; i<a.Size; i++) out<<a.x[i]<<" "; return out;}

private:
      int Size;
      Type *x;
      };

int main()
{

      Vector<int> A(5);
      Vector<int> B(5);
      
      cin >> A;
      cout << A << endl;
      --A;
      cout << A << endl;
      A--;
      cout << A << endl;

      A=A+1;

      cout << "\nA: ";

      cout << A << endl;

      A=A/2;
      
      cout << "\nA/2: " << A << endl;

      cout << "\nEnter B:\n";
      cin >> B;
      
      A=A*B;
      
      cout << "A*B: " << A << endl;

      cout << "A's Sum: " << A.Sum() << endl;
 
      return EXIT_SUCCESS;  // EXIT_SUCCESS and EXIT_FAILURE are defined constants
}