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

#ifndef BCSET_H
#define BCSET_H 1

#include "BCType.h"

template<class Set_Item>
class BC_TSetActiveIterator;

template<class Set_Item>
class BC_TSetPassiveIterator;

// Set abstract base class

template<class Set_Item>
class BC_TSet {
public:

  BC_TSet();
  BC_TSet(const BC_TSet<Set_Item>&);
  virtual ~BC_TSet();

  virtual BC_TSet<Set_Item>& operator=(const BC_TSet<Set_Item>&);
  virtual BC_Boolean operator==(const BC_TSet<Set_Item>&) const;
  BC_Boolean operator!=(const BC_TSet<Set_Item>&) const;

  virtual void SetHashFunction(BC_Index (*)(const Set_Item&)) = 0;
  virtual void Clear() = 0;
  virtual BC_Boolean Add(const Set_Item&) = 0;
  virtual BC_Boolean Remove(const Set_Item& at) = 0;
  virtual void SetUnion(const BC_TSet<Set_Item>&);
  virtual void Intersection(const BC_TSet<Set_Item>&);
  virtual void Difference(const BC_TSet<Set_Item>&);

  virtual BC_Index Extent() const = 0;
  virtual BC_Boolean IsEmpty() const = 0;
  virtual BC_Boolean IsMember(const Set_Item&) const = 0;
  virtual BC_Boolean IsSubset(const BC_TSet<Set_Item>&) const;
  virtual BC_Boolean IsProperSubset(const BC_TSet<Set_Item>&) const;

protected:

  virtual void Purge() = 0;
  virtual BC_Boolean Attach(const Set_Item&) = 0;
  virtual BC_Boolean Detach(const Set_Item&) = 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 Set_Item&) const = 0;
  virtual const Set_Item& Item(BC_Index bucket, BC_Index index) const = 0;
  
  virtual void Lock();
  virtual void Unlock();
  
private:

  friend class BC_TSetActiveIterator<Set_Item>;
  friend class BC_TSetPassiveIterator<Set_Item>;
  
};

// Set iterators

template <class Set_Item>
class BC_TSetActiveIterator {
public:

  BC_TSetActiveIterator(const BC_TSet<Set_Item>&);
  ~BC_TSetActiveIterator();
  
  void Reset();
  BC_Boolean Next();

  BC_Boolean IsDone() const;
  const Set_Item* Item() const;
  
protected:

  const BC_TSet<Set_Item>& fRepSet;
  BC_Extended_Index fRepBucketIndex;
  BC_Extended_Index fRepIndex;
  
};

template <class Set_Item>
class BC_TSetPassiveIterator {
public:

  BC_TSetPassiveIterator(const BC_TSet<Set_Item>&);
  ~BC_TSetPassiveIterator();
  
  BC_Boolean Apply(BC_Boolean (*)(const Set_Item&));
  
protected:

  const BC_TSet<Set_Item>& fRepSet;

};

#endif
