//  The C++ Booch Components (Version 2.0)
//  (C) Copyright 1990-1993 Grady Booch. All Rights Reserved.
//
//  BCMap.h
//
//  This file contains the declaration of the map abstract base class
//  and its iterators.

#ifndef BCMAP_H
#define BCMAP_H 1

#include "BCType.h"

template<class Map_Item, class Map_Value>
class BC_TMapActiveIterator;

template<class Map_Item, class Map_Value>
class BC_TMapPassiveIterator;

// Map abstract base class

template<class Map_Item, class Map_Value>
class BC_TMap {
public:

  BC_TMap();
  BC_TMap(const BC_TMap<Map_Item, Map_Value>&);
  virtual ~BC_TMap();

  virtual BC_TMap<Map_Item, Map_Value>& operator=(const BC_TMap<Map_Item, Map_Value>&);
  virtual BC_Boolean operator==(const BC_TMap<Map_Item, Map_Value>&) const;
  BC_Boolean operator!=(const BC_TMap<Map_Item, Map_Value>&) const;

  virtual void SetHashFunction(BC_Index (*)(const Map_Item&)) = 0;
  virtual void Clear() = 0;
  virtual BC_Boolean Bind(const Map_Item&, const Map_Value&) = 0;
  virtual BC_Boolean Rebind(const Map_Item&, const Map_Value&) = 0;
  virtual BC_Boolean Unbind(const Map_Item&) = 0;

  virtual BC_Index Extent() const = 0;
  virtual BC_Boolean IsEmpty() const = 0;
  virtual BC_Boolean IsBound(const Map_Item&) const = 0;
  virtual const Map_Value* Value(const Map_Item&) const = 0;

protected:

  virtual void Purge() = 0;
  virtual BC_Boolean Attach(const Map_Item&, const Map_Value&) = 0;
  virtual BC_Index Cardinality() const = 0;
  virtual BC_Index NumberOfBuckets() const = 0;
  virtual BC_Index Length(BC_Index bucket) const = 0;
  virtual BC_Boolean Exists(const Map_Item&) const = 0;
  virtual const Map_Item& Item(BC_Index bucket, BC_Index index) const = 0;
  virtual const Map_Value& Value(BC_Index bucket, BC_Index index) const = 0;

  virtual void Lock();
  virtual void Unlock();
  
private:

  friend class BC_TMapActiveIterator<Map_Item, Map_Value>;
  friend class BC_TMapPassiveIterator<Map_Item, Map_Value>;
  
};

// Map iterators

template <class Map_Item, class Map_Value>
class BC_TMapActiveIterator {
public:

  BC_TMapActiveIterator(const BC_TMap<Map_Item, Map_Value>&);
  ~BC_TMapActiveIterator();
  
  void Reset();
  BC_Boolean Next();

  BC_Boolean IsDone() const;
  const Map_Item* Item() const;
  const Map_Value* Value() const;
  
protected:

  const BC_TMap<Map_Item, Map_Value>& fRepMap;
  BC_Extended_Index fRepBucketIndex;
  BC_Extended_Index fRepIndex;
  
};

template <class Map_Item, class Map_Value>
class BC_TMapPassiveIterator {
public:

  BC_TMapPassiveIterator(const BC_TMap<Map_Item, Map_Value>&);
  ~BC_TMapPassiveIterator();
  
  BC_Boolean Apply(BC_Boolean (*)(const Map_Item&, const Map_Value&));
  
protected:

  const BC_TMap<Map_Item, Map_Value>& fRepMap;

};

#endif
