//
//	File:	     state_set.h
//      Version:     ASTL 1.1
//	Copyright:   Vincent LE MAOUT
//	Date:	     Thu Oct 29 13:52:55 MET 1998
//	Descrition:  Used by DFA and NFA classes to keep track of allocated states
//                   and export the const_iterator type. This is a vector of
//                   pointers. Elements are designated by unsigned long integers.
//

#ifndef ASTL_CLASS_STATE_SET
#define ASTL_CLASS_STATE_SET

#include <vector>
#include <iterator>
#include <astl.h>

#ifdef WIN32

template <class T>
class State_set : public vector<T*>
#else

template <class T, class Allocator = default_allocator>
class State_set : public vector<T*, Allocator>
#endif // WIN32
{
private:
  unsigned long how_many;
  unsigned long _small;
#ifdef WIN32
  typedef vector<T*> super;
#else
  typedef vector<T*, Allocator> super;
#endif

public:
  typedef super::size_type State;
  
  State_set() : super(1, NULL), how_many(0),_small(1) 
  { }
  
  State add(T *object) // gros goret signer DR 
  {
	  State hh = size() ;
	if (how_many == size()-1) // si y a plus de place 
	   {
		push_back(object);
		++how_many;
		return (size() - 1);
	}
	else // trouver un emplacement vide 
	{
		State pos;
		for(pos=_small; pos <  size() &&  operator[](pos) != NULL; ++pos);
		(*this)[pos] = object;
		_small = pos+1;
		++how_many;
		return pos ;
	}
  }

  void del(State s)
  {
	  if ( s < _small ) _small  = s ;
    --how_many;
    (*this)[s] = NULL;
  }

  unsigned long card() const { 
    return (how_many); 
  }

#ifdef WIN32
  class const_iterator 
	//  : public iterator<forward_iterator_tag, State, unsigned int>
#else
  class const_iterator 
    : public forward_iterator<State, unsigned int>
#endif // WIN32

  {
    friend State_set;
    typedef const_iterator self;

  private:
    const State_set *Q;
    State pos;

    const_iterator(const State_set *_Q, State _pos)
      : Q(_Q), pos(_pos) { }

  public:
    const_iterator() : Q(NULL), pos(0) { }
    const_iterator(const self &x) : Q(x.Q), pos(x.pos) { }
    const_iterator& operator = (const self &x)
    {
      Q = x.Q;
      pos = x.pos;
      return (*this);
    }

    bool operator == (const const_iterator &x) {
      return (x.pos == pos && x.Q == Q);
    }
    
    bool operator != (const const_iterator &x) {
      return (x.pos != pos || x.Q != Q);
    }

    State operator * () { 
      return (pos); 
    }
    
    self& operator ++ ()
    {
      for(++pos; pos < Q->size() && Q->operator[](pos) == NULL; ++pos);
      return (*this);
    }

    self operator ++ (int)
    {
      const_iterator tmp = *this;
      ++(*this);
      return (tmp);
    }
  };

  const_iterator begin() const 
  {
    const_iterator i(this, 0);
    ++i;
    return (i);
  }

  const_iterator end() const
  {
    return (const_iterator(this, size()));
  }

//	friend bool operator == (const State_set &x, const State_set &y) {
//		return (super::operator==(x, y));
//	}
};

#endif // ASTL_CLASS_STATE_SET
