#include <iostream>

#ifndef __BORLANDC__
using namespace std;
#endif

struct Punkt
  {
   double x,y;
   Punkt():x(0),y(0) {}
   Punkt(double x,double y):x(x),y(y) {}
  };

ostream &operator<<(ostream &s,const Punkt &P)
  {
   return s<<'('<<P.x<<','<<P.y<<')';
  }

template <class Dane> class Tablica
  {
   private:
   unsigned R;
   Dane *T;
   public:
   Tablica(unsigned Rozmiar=0);
   Tablica(const Tablica &Tb);
   ~Tablica();
   Dane &operator[](unsigned P);
   const Dane &operator[](unsigned P)const;
   operator bool() { return R; }
   Tablica &operator=(const Tablica &Tb);
   unsigned operator()()const { return R; }
   void operator()(unsigned Rozmiar);
  };

template <class Dane> Tablica<Dane>::Tablica(unsigned Rozmiar):
  R(Rozmiar),
  T(R?new Dane[R]:0)
  {
  }

template <class Dane> Tablica<Dane>::Tablica(const Tablica<Dane> &Tb):
  R(Tb.R),
  T(R?new Dane[R]:0)
  {
   memcpy(T,Tb.T,R*sizeof(Dane));
  }

template <class Dane> Tablica<Dane>::~Tablica()
  {
   if(R) delete[] T;
  }

template <class Dane> Dane &Tablica<Dane>::operator[](unsigned P)
  {
   if(P>=R) throw P;
   return T[P];
  }

template <class Dane> const Dane &Tablica<Dane>::operator[](unsigned P)const
  {
   if(P>=R) throw P;
   return T[P];
  }

template <class Dane> Tablica<Dane> &Tablica<Dane>::operator=(const Tablica<Dane> &Tb)
  {
   if(R) delete[] T;
   R=Tb.R;
   T=R?new Dane[R]:0;
   memcpy(T,Tb.T,R*sizeof(Dane));
   return *this;
  }

template <class Dane> void Tablica<Dane>::operator()(unsigned Rozmiar)
  {
   Dane *NT=Rozmiar?new Dane[Rozmiar]:0;
   if(R)
     {
      memcpy(NT,T,(R<Rozmiar?R:Rozmiar)*sizeof(Dane));
      delete[] T;
     }
   T=NT;
   R=Rozmiar;
  }

template <class Dane> ostream &operator<<(ostream &out,const Tablica<Dane> &T)
  {
   out<<'{';
   for(unsigned i=0;i<T();++i)
     {
      if(i) out<<',';
      out<<T[i];
     }
   return out<<'}';
  }

#define Wartosc(Var) #Var<<'='<<Var<<';'

int main()
  {
   Tablica<Punkt> A(5);

   for(unsigned i=0;i<A();++i)
     {
      A[i]=Punkt(i*3.5,i/2.5);
     }
   cout<<Wartosc(A)<<endl;
   const Tablica<Punkt> B(A);
   cout<<Wartosc(B)<<endl;
   A(8);
   cout<<Wartosc(A)<<endl;
   A=B;
   cout<<Wartosc(A)<<endl;

   try
     {
      cout<<"Proba A[100]"<<endl;
      cout<<"A[100]="<<A[100]<<endl;
      cout<<"Udalo sie"<<endl;
     }
   catch(unsigned x)
     {
      cout<<"Indeks "<<x<<" poza zakresem"<<endl;
     }
   typedef Tablica<int> Tint;
   typedef Tablica<Tint> T2int;
   T2int T;
   T(2);
   T[0](3);
   T[1](3);
   int N=0;
   for(unsigned y=0;y<2;++y)
     {
      for(unsigned x=0;x<3;++x)
        {
         T[y][x]=2*(++N);
        }
     }
   cout<<Wartosc(T)<<endl;



   cin.get();
   return 0;
  }

