//  The C++ Booch Components (Version 2.0)
//  (C) Copyright 1990-1993 Grady Booch. All Rights Reserved.
//
//  BCHashTa.h
//
//  This file contains the declaration of the open hash table class.
 
#ifndef BCHASHTA_H
#define BCHASHTA_H 1

#include "BCType.h"
#include "BCExcept.h"
#include "BCNodes.h"

// Class denoting an open hash table

template<class Container_Item, class Container_Value, BC_Index Buckets, class Container>
class BC_TTable {
public:

  BC_TTable()
    : fRepValidCache(0),
      fRepSize(0),
      fRepHash(0)
    {}
  BC_TTable(BC_Index (*hash)(const Container_Item&))
    : fRepValidCache(0),
      fRepSize(0),
      fRepHash(hash)
    {}
  BC_TTable(const BC_TTable<Container_Item, Container_Value, Buckets, Container>&);
  ~BC_TTable()
    {Clear();}

  BC_TTable<Container_Item, Container_Value, Buckets, Container>& operator=
    (const BC_TTable<Container_Item, Container_Value, Buckets, Container>&);
  BC_Boolean operator==(const BC_TTable<Container_Item, Container_Value, Buckets, Container>&) const;
  BC_Boolean operator!=(const BC_TTable<Container_Item, Container_Value, Buckets, Container>& t) const
    {return !operator==(t);}

  void SetHashFunction(BC_Index (*hash)(const Container_Item&))
    {BC_Assert((!fRepHash), BC_XDuplicate("BC_TTable<>::SetHashFunction", BC_kDuplicate));
     fRepHash = hash;}
  void Clear();
  BC_Boolean Bind(const Container_Item&, const Container_Value&);
  BC_Boolean Rebind(const Container_Item&, const Container_Value&);
  BC_Boolean Unbind(const Container_Item&);

  BC_Index Extent() const
    {return fRepSize;}
  BC_Boolean IsBound(const Container_Item&) const;
  const Container_Value* Value(const Container_Item&) const;
  const Container *const Bucket(BC_Index bucket) const
    {BC_Assert((bucket < Buckets), BC_XRangeError("BC_TTable<>::Bucket", BC_kInvalidIndex));
     return &fRep[bucket];}
  Container *const Bucket(BC_Index bucket)
    {BC_Assert((bucket < Buckets), BC_XRangeError("BC_TTable<>::Bucket", BC_kInvalidIndex));
     return &fRep[bucket];}

protected:

  Container fRep[Buckets];
  BC_TPair<Container_Item, Container_Value> fRepCache;
  BC_Boolean fRepValidCache;
  BC_Index fRepSize;
  BC_Index (*fRepHash)(const Container_Item&);
  
};

#endif
