//  The C++ Booch Components (Version 2.0)
//  (C) Copyright 1990-1993 Grady Booch. All Rights Reserved.
//
//  BCUnboun.h
//
//  This file contains the declaration of the list-based class
//  used for the representation of unbounded structures.

#ifndef BCUNBOUN_H
#define BCUNBOUN_H 1

#include <stddef.h>
#include "BCExcept.h"
#include "BCNodes.h"

// Class denoting a list-based container

template<class Container_Item, class Storage_Manager>
class BC_TUnbounded {
public:

  BC_TUnbounded();
  BC_TUnbounded(const BC_TUnbounded<Container_Item, Storage_Manager>&);
  ~BC_TUnbounded();

  BC_TUnbounded<Container_Item, Storage_Manager>& 
    operator=(const BC_TUnbounded<Container_Item, Storage_Manager>&);
  BC_Boolean operator==(const BC_TUnbounded<Container_Item, Storage_Manager>&) const;
  BC_Boolean operator!=(const BC_TUnbounded<Container_Item, Storage_Manager>& c) const
    {return !operator==(c);} 
  Container_Item& operator[](BC_Index index) const
    {BC_Assert((index < Length()),
               BC_XRangeError("BC_TUnbounded<>::operator[]", BC_kInvalidIndex));
     return Item(index);}

  void Clear();
  void Insert(const Container_Item&);
  void Insert(const Container_Item&, BC_Index before);
  void Append(const Container_Item&);
  void Append(const Container_Item&, BC_Index after);
  void Remove(BC_Index at);
  void Replace(BC_Index at, const Container_Item&);

  BC_Index Length() const;
  const Container_Item& First() const
    {BC_Assert(fRepSize, BC_XUnderflow("BC_TUnbounded<>::First()", BC_kEmpty));
     return (fRep->fRepItem);}
  const Container_Item& Last() const
    {return (fRepLast->fRepItem);}
  Container_Item& Item(BC_Index index) const;
  BC_Extended_Index Location(const Container_Item& i) const;

  static void* operator new(size_t);
  static void operator delete(void*, size_t);

protected:

  BC_TNode<Container_Item, Storage_Manager>* fRep;
  BC_TNode<Container_Item, Storage_Manager>* fRepLast;
  BC_Index fRepSize;

  BC_TNode<Container_Item, Storage_Manager>* fRepCache;
  BC_Index fRepCacheIndex;

};

#endif
