//
// LiDIA - a library for computational number theory
//   Copyright (c) 1995 by the LiDIA Group
//
// File        : hash_table.h
// Author      : Michael Jacobson (MJ)
// Last change : MJ, September 24, 1996
//

#ifndef LIDIA_HASH_TABLE_H
#define LIDIA_HASH_TABLE_H

#if defined(HAVE_MAC_DIRS) || defined(__MWERKS__)
#include <LiDIA:bigint.h>
#else
#include <LiDIA/bigint.h>
#endif
 
template < class T >
class hentry
{
  protected:

  public:

  int item;
  hentry < T > *next, *prev;

  hentry() { item = (int) NULL; next = NULL; prev = NULL; };
  ~hentry() { T *tptr;  tptr = (T *) item;  if (tptr)  delete tptr; };
};



template < class T >
class hash_table
{
  protected:

  lidia_size_t size;			/* capacity of hash table */
  lidia_size_t curr_size;		/* current size */
  int *buckets;				/* array of data buckets */
  T *last_one;				/* last data entry */

  bigint (*key) (const T & G);		/* key function */

  public:

  /**
   ** constructors and destructor 
   **/

  hash_table();
  ~hash_table();

  /**
   ** member functions
   **/

  void assign(const hash_table < T > & old_table);
  hash_table < T > & operator = (const hash_table < T > & old_table);

  void initialize(const lidia_size_t table_size);
  void set_key_function(bigint (*get_key) (const T &));
  lidia_size_t no_of_buckets() const;
  lidia_size_t no_of_elements() const;
  void remove(const T & G);
  void empty();
  const T & last_entry() const;
  void hash(const T & G);
  T * search(const T & G);

  void read  (istream & in);
  void print (ostream & out) const;

  friend istream & operator >> (istream & in, hash_table < T > & HT)
   {HT.read(in); return (in);}

  friend ostream & operator << (ostream & out, const hash_table < T > & HT)
   {HT.print(out); return (out);}
};

#ifdef LIDIA_INCLUDE_C
#include <LiDIA/hash_table.c>
#endif 

#endif
