/*
BOIL (Brunni's Own Interpreter Language)
(c) 1998 netEstate (http://www.netestate.de/, info@netestate.de),
Michael Brunnbauer & Markus Hendel, Gesellschaft fuer Netzwerkkommunikation bR
Am Bluetenanger 8, 80995 Muenchen, Germany

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
any later version.

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

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

template<class T> struct hlist
{
  joined_list<T> values;
  joined_list<unsigned long> handles;
  joined_list<bool> cleanup;

  long insert(T&);
  void del(long);
  long ishandle(long);
  T& gethandle(long);
};

template<class T>
long hlist<T>::insert(T& value)
{
  unsigned long handle=0;
  bool dummybool=1;
  unsigned long i;

  /* find the biggest handle. if there is a gap in the list, stop */
  for (i=0;i!=handles.length();i++)
    {
      if (handles[i]-handle > 1) { break; };
      handle=handles[i];
    };

  /* use the next number as handle */
  handle++;
  if (!handle)
    {
      log(LOG_FATAL,__FILE__,__LINE__,ERROR_UNSPECIFIED,
	  "handles<T>::insert(): too much handles");
    };

  handles.insert_listelem(handle,i);
  values.insert_listelem(value,i);
  cleanup.insert_listelem(dummybool,i);

  return (long) handle;
}

template<class T>
void hlist<T>::del(long lhandle)
{
  unsigned long handle=(unsigned long) lhandle;

  for (unsigned i=0;i!=handles.length();i++)
    {
      if (handles[i]==handle)
	{
	  handles.remove_listelem(i);
	  values.remove_listelem(i);
	  cleanup.remove_listelem(i);
	  return;
	};
    };

  log(LOG_FATAL,__FILE__,__LINE__,ERROR_UNSPECIFIED,
      "handles<T>::delete(): handle not found");
  return;
}

template<class T>
long hlist<T>::ishandle(long lhandle)
{
  unsigned long handle=(unsigned long) lhandle;

  for (unsigned i=0;i!=handles.length();i++)
    {
      if (handles[i]==handle)
        {
          return 1;
        };
    };

  return 0;
}

template<class T>
T& hlist<T>::gethandle(long lhandle)
{
  unsigned long handle=(unsigned long) lhandle;

  for (unsigned i=0;i!=handles.length();i++)
    {
      if (handles[i]==handle)
        {
          return values[i];
        };
    };

  log(LOG_FATAL,__FILE__,__LINE__,ERROR_UNSPECIFIED,
      "handles<T>::gethandle(): handle not found");

  /* not reached */
  return values[0];
}
