/*
_____       _    _    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 piteratr_h
# define piteratr_h "$Id: piteratr.h 1.2 96/09/16 15:53:05 picoSoft Exp $"
# include "plist.h"


class PIterator : public PObject {
   PCLASS(PIterator, PObject)
   static PObject * NullObject;
   PList * list;
   PListItem * currItem;
   long currIndex;
   void init (PList *l) { list = l; reset(); }
public:
   PIterator (PList *l) { init (l); }
   PIterator (PList &l) { init (&l); }
   PIterator (const PIterator &i) { *this = i; }
   ~PIterator () { }
   PIterator & operator=(const PIterator &i) { list = i.list;
                                               currItem = i.currItem;
                                               currIndex = i.currIndex;
                                               return *this; }
   PObject* operator [](long i);
   void reset () { currItem = list->root; currIndex = 0; } 
   void end () { (*this)[list->itemNum - 1]; }
   long size () { return list->itemNum; }
   PObject* sync ();
   PObject* operator*() {  
                           if (currItem)
                              return currItem->obj;
                           else
                              return NullObject;
                        }
   PObject ** operator++ () { 
                            if (currItem) {  
                               currItem = currItem->right;
                               currIndex++;
                            } else
                               if (currIndex < 0)
                                  reset();
                            if (currItem)
                               return &currItem->obj;
                            else
                               return &NullObject;
                          }
   PObject ** operator-- () { 
                            if (currItem) {  
                               currItem = currItem->left;
                               currIndex--;
                            } else
                               if (currIndex == size())
                                  end();
                            if (currItem)
                               return &currItem->obj;
                            else
                               return &NullObject;
                          }
   PObject ** operator++ (int) {
                            PObject **Return = &NullObject; 
                            if (currItem) {
                               Return = &currItem->obj;
                               currItem = currItem->right;
                               currIndex++;
                            } else
                               if (currIndex < 0)
                                  reset();
                            return Return;
                          }
   PObject ** operator-- (int) {
                            PObject **Return = &NullObject;  
                            if (currItem) {
                               Return = &currItem->obj;  
                               currItem = currItem->left;
                               currIndex--;
                            } else
                               if (currIndex == size())
                                  end();
                            return Return;
                          }
   PList &GetList () {
                       list->current = currItem;
                       return *list;
                     }
   void SetCurrList () {
                          currItem = list->current;
                          for (currIndex = 0, list->GetFirst ();
                               list->current != currItem;
                               currIndex++,   list->GetNext ())
                             ;
                       }
};

# define PITERATOR(a) \
class a##Iterator : public PIterator \
{ \
public: \
   a##Iterator (PList &l) : PIterator (&l) { } \
   a##Iterator (PList *l) : PIterator (l)  { } \
   a * operator *() { return (a *) PIterator::operator*(); } \
   a * operator [](long i) { return (a *) PIterator::operator[](i); } \
   a ** operator++(){ return (a ** )PIterator::operator++();}\
   a ** operator--(){ return (a ** )PIterator::operator--();}\
   a ** operator++(int){return (a ** )PIterator::operator++(0);} \
   a ** operator--(int){return (a ** )PIterator::operator--(0);} \
   a##List & GetList() { return (a##List &)  PIterator::GetList(); } \
} \

# endif

   
