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

#ifndef BCBOUND_H
#define BCBOUND_H 1

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

// Class denoting an optimally-packed static container

template<class Container_Item, BC_Index Container_Size>
class BC_TBounded {
public:

  BC_TBounded();
  BC_TBounded(const BC_TBounded<Container_Item, Container_Size>&);
  ~BC_TBounded();

  BC_TBounded<Container_Item, Container_Size>& operator=(const BC_TBounded<Container_Item, Container_Size>&);
  BC_Boolean operator==(const BC_TBounded<Container_Item, Container_Size>&) const;
  BC_Boolean operator!=(const BC_TBounded<Container_Item, Container_Size>& c) const
    {return !operator==(c);}
  const Container_Item& operator[](BC_Index index) const;
  Container_Item& operator[](BC_Index index);

  void Clear()
    {fRepStart = fRepStop = 0;}
  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 Available() const
    {return (Container_Size - Length());}
  BC_Index Length() const;
  const Container_Item& First() const
    {BC_Assert((fRepStart >= 0), BC_XUnderflow("BC_TBounded<>::First()", BC_kEmpty));
     return fRep[fRepStart - 1];}
  const Container_Item& Last() const
    {return fRep[fRepStop - 1];}
  const Container_Item& Item(BC_Index) const;
  Container_Item& Item(BC_Index);
  BC_Extended_Index Location(const Container_Item&) const;

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

protected:

  Container_Item fRep[Container_Size];
  BC_Index fRepStart;
  BC_Index fRepStop;
  
  BC_Index ExpandLeft(BC_Index from);
  BC_Index ExpandRight(BC_Index from);
  void ShrinkLeft(BC_Index from);
  void ShrinkRight(BC_Index from);
  
};

#endif
