#include <iostream>

using namespace std;

template <class Typ> class Stos
  {
   private:
   class Element
     {
      private:
      Typ Dane;
      Element *Nastepny;
      public:
      Element(Typ Dane,Stos<Typ>::Element *Nastepny);
      Element *Pobierz(Typ &Dane,Stos<Typ>::Element *&Nastepny);
      friend class Stos<Typ>;
      friend ostream &operator<<(ostream &out,const Stos<Typ> &S);
     } *Pierwszy;
   Element *ZnajdzOstatni()const;
   void Czysc();
   void Kopiuj(const Stos &S);
   public:
   class Pusty {};
   Stos():Pierwszy(0) {}
   Stos(const Stos &S):Pierwszy(0) { Kopiuj(S); }
   ~Stos() { Czysc(); }
   Stos &operator<<(Typ Dane);
   Stos &operator>>(Typ &Dane);
   operator bool()const { return Pierwszy; }
   void operator~() { Czysc(); }
   Stos &operator=(const Stos &S) { Czysc(); Kopiuj(S); return *this; }
   friend ostream &operator<<(ostream &out,const Stos<Typ> &S);
  };

template <class Typ> Stos<Typ>::Element::Element(Typ Dane,Stos<Typ>::Element *Nastepny):
  Dane(Dane),Nastepny(Nastepny)
  {
  }

template <class Typ> Stos<Typ>::Element *Stos<Typ>::Element::Pobierz(Typ &Dane,Stos<Typ>::Element *&Nastepny)
  {
   if(!this) throw Pusty();
   Dane=Stos<Typ>::Element::Dane;
   Nastepny=Stos<Typ>::Element::Nastepny;
   return this;
  }

template <class Typ> Stos<Typ>::Element *Stos<Typ>::ZnajdzOstatni()const
  {
   Stos<Typ>::Element *Ostatni=0;
   for(Stos<Typ>::Element *i=Pierwszy;i;i=i->Nastepny) Ostatni=i;
   return Ostatni;
  }

template <class Typ> void Stos<Typ>::Czysc()
  {
   while(Pierwszy)
     {
      Stos<Typ>::Element *Tmp=Pierwszy->Nastepny;
      delete Pierwszy;
      Pierwszy=Tmp;
     }
  }

template <class Typ> void Stos<Typ>::Kopiuj(const Stos<Typ> &S)
  {
   Stos<Typ>::Element *Ostatni=ZnajdzOstatni();
   for(Stos<Typ>::Element *i=S.Pierwszy;i;i=i->Nastepny)
     {
      Ostatni=(Ostatni?Ostatni->Nastepny:Pierwszy)=new Stos<Typ>::Element(i->Dane,0);
/*
      Stos<Typ>::Element *Nowy=new Stos<Typ>::Element(i->Dane,0);
      if(Ostatni) Ostatni->Nastepny=Nowy;
      else Pierwszy=Nowy;
      Ostatni=Nowy;
*/
     }
  }

template <class Typ> Stos<Typ> &Stos<Typ>::operator<<(Typ Dane)
  {
   Pierwszy=new Element(Dane,Pierwszy);
   return *this;
  }

template <class Typ> Stos<Typ> &Stos<Typ>::operator>>(Typ &Dane)
  {
   delete Pierwszy->Pobierz(Dane,Pierwszy);
   return *this;
  }

/*
template <class Typ> ostream &operator<<(ostream &out,const Stos<Typ> &S)
  {
   out<<'{';
   bool F=false;
   for(Stos<Typ>::Element *i=S.Pierwszy;i;i=i->Nastepny)
     {
      if(F) out<<',';
      out<<i->Dane;
      F=true;
     }
   return out<<'}';
  }*/

ostream &operator<<(ostream &out,const Stos<double> &S)
  {
   out<<'{';
   bool F=false;
   for(Stos<double>::Element *i=S.Pierwszy;i;i=i->Nastepny)
     {
      if(F) out<<',';
      out<<i->Dane;
      F=true;
     }
   return out<<'}';
  }

#define Wartosc(Var) #Var<<'='<<Var<<';'

int main()
  {
   Stos<double> S;
   cout<<Wartosc(S)<<endl;
   double X=3,Y;
   S<<1<<2<<X;
   cout<<Wartosc(S)<<endl;
   Stos<double> T(S);
   cout<<Wartosc(T)<<endl;
   S>>Y>>X;
   cout<<Wartosc(Y)<<endl;
   cout<<Wartosc(X)<<endl;
   cout<<Wartosc(S)<<endl;
   S=T;
   cout<<Wartosc(S)<<endl;
   if(S)
     {
      ~S;
      cout<<Wartosc(S)<<endl;
     }
   if(S) cout<<"Blad"<<endl;
   try
     {
      S>>X;
     }
   catch(Stos<double>::Pusty)
     {
      cout<<"Stos jest pusty!"<<endl;
     }

   cin.get();
   return 0;
  }




