/*
_____       _    _    Corso   Italia,  178
(_|__   .  (_   |_|_  56125           Pisa
(_|_) |)|(()_)()| |   tel.  +39  050 46380
  |   |               picosoft@picosoft.it

 picocpp - basic objects library for picoSQL 

 Copyright (C) Picosoft s.r.l. 1994-2002

 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Lesser General Public
 License as published by the Free Software Foundation; either
 version 2.1 of the License, or (at your option) any later version.

 This library 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
 Lesser General Public License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
# ifndef pstack_h
# define pstack_h "$Id: pstack.h 1.2 96/09/16 15:52:40 picoSoft Exp Locker: ROOT_DOS $"
# include "plist.h"

# define PSTACK(a) \
class a##Stack : public PObject \
{ \
   PList stack; \
   int numItems; \
public: \
   void Push (const a & s) {  \
                     a * tmp = new a(s); \
                     numItems++; \
                     stack.AddItem ((PObject *) tmp); } \
   a Pop ()   {      a Return; \
                     a * tmp = (a *) stack.GetCurrent (); \
                     if (tmp != 0) { \
                        Return = *tmp; \
                        delete tmp; \
                        stack.DeleteCurrent (); \
                        numItems --; \
                        return Return; \
                     } \
                     return Return; \
              } \
   int Size () {  return numItems; } \
   a##Stack() {  numItems = 0; } \
   ~a##Stack() {  while (numItems) Pop (); } \
}

# define PSSTACK(a) \
class a##SStack : public PObject \
{ \
   a * array; \
   int numItems; \
public: \
   void Push (const a & s) { array[numItems++] = s; } \
   a Pop () { return array[--numItems]; } \
   int Size () {  return numItems; } \
   a##SStack(int n) { numItems = 0; \
                      if (n>0) array = new a[n]; \
                      else array = 0; } \
   ~a##SStack() {  if (array) delete array; } \
}
# ifdef WIN32
template<class T> class PStack : public PObject {
   T **list;
   int maxSize;
   int numItems;
   void changeSize (int n) {
      register int i = 0;
      T **tmp = new T * [n];
      if (maxSize > 0) {
         for ( ; i < maxSize; i++)
            tmp[i] = list[i];
         delete list;
      }
      list = tmp;
      maxSize = n;
   }
public:
   PStack (int initSize = 10) {
      maxSize = 0;
      changeSize(initSize);
      numItems = 0;
   }
   ~PStack() {
      delete list;
   }
   void Push (T *s) {
      if (numItems == maxSize)
         changeSize (maxSize + maxSize);
      list[numItems++] = s;
   }
   T *Pop () {
      if (numItems > 0)
         return list[--numItems];
      else
         return 0;
   }
   T *getAt (int n) {
      if (numItems > n)
         return list[n];
      else
         return 0;
   }
   int Size () { return numItems; }
};
# define PStack(T) PStack<T>
# else 
# define PTSTACK(T) \
class PStack##T : public PObject { \
   T **list; \
   int maxSize; \
   int numItems; \
   void changeSize (int n) { \
      register int i = 0; \
      T **tmp = new T * [n]; \
      if (maxSize > 0) { \
         for ( ; i < maxSize; i++) \
            tmp[i] = list[i]; \
         delete list; \
      } \
      list = tmp; \
      maxSize = n; \
   } \
public: \
   PStack##T (int initSize = 10) { \
      maxSize = 0; \
      changeSize(initSize); \
      numItems = 0; \
   } \
   ~PStack##T() { \
      delete list; \
   } \
   void Push (T * s) { \
      if (numItems == maxSize) \
         changeSize (maxSize + maxSize); \
      list[numItems++] = s; \
   } \
   T *Pop () { \
      if (numItems > 0) \
         return list[--numItems]; \
      else \
         return 0; \
   } \
   T *getAt (int n) { \
      if (numItems > n) \
         return list[n]; \
      else \
         return 0; \
   } \
   int Size () { return numItems; } \
}
# define PStack(T) PStack##T
# endif

# endif
