//  The C++ Booch Components (Version 2.0)
//  (C) Copyright 1990-1993 Grady Booch. All Rights Reserved.
//
//  BCExcept.h
//
//  This file contains the declaration of the classes and functions
//  associated with exception handling.

#ifndef BCEXCEPT_H 
#define BCEXCEPT_H 1 

#include "BCType.h"

class ostream;

// Common exception descriptions

extern const char* BC_kDisjoint;
extern const char* BC_kDuplicate;
extern const char* BC_kEmpty;
extern const char* BC_kFull;
extern const char* BC_kIllegal;
extern const char* BC_kInvalidIndex;
extern const char* BC_kInvalidNumber;
extern const char* BC_kMissing;
extern const char* BC_kNotEmpty;
extern const char* BC_kNotRoot;
extern const char* BC_kNULL;
extern const char* BC_kOutOfMemory;
extern const char* BC_kReferenced;
extern const char* BC_kTooLarge;
extern const char* BC_kTooSmall;

// Exception base class

class BC_XException {
public:

  BC_XException(const char* name, const char* who, const char* what);
  
  void Display(ostream&) const;

  const char* Name() const
    {return fRepName;}
  const char* Who() const 
    {return fRepWho;}
  const char* What() const 
    {return fRepWhat;}
  
protected:

  enum {BC_MAXIMUM_LENGTH = 63};

  char fRepName[BC_MAXIMUM_LENGTH + 1];
  char fRepWho [BC_MAXIMUM_LENGTH + 1];
  char fRepWhat[BC_MAXIMUM_LENGTH + 1];

private:

  friend ostream& operator<<(ostream&, const BC_XException&);

};

// Predefined global exceptions

class BC_XContainerError : public BC_XException {
public:

  BC_XContainerError(const char* who, const char* what)
    : BC_XException("Container_Error", who, what) 
    {}

};

class BC_XDuplicate : public BC_XException {
public:

  BC_XDuplicate(const char* who, const char* what)
    : BC_XException("Duplicate", who, what) 
    {}

};

class BC_XIllegalPattern : public BC_XException {
public:

  BC_XIllegalPattern(const char* who, const char* what)
    : BC_XException("Illegal_Pattern", who, what) 
    {}

};

class BC_XIsNull : public BC_XException {
public:

  BC_XIsNull(const char* who, const char* what)
    : BC_XException("IsNull", who, what) 
    {}

};

class BC_XLexicalError : public BC_XException {
public:

  BC_XLexicalError(const char* who, const char* what)
    : BC_XException("Lexical_Error", who, what) 
    {}

};

class BC_XMathError : public BC_XException {
public:

  BC_XMathError(const char* who, const char* what)
    : BC_XException("Math_Error", who, what) 
    {}
   
};

class BC_XNotFound : public BC_XException {
public:

  BC_XNotFound(const char* who, const char* what)
    : BC_XException("Not_Found", who, what) 
    {}

};

class BC_XNotNull : public BC_XException {
public:

  BC_XNotNull(const char* who, const char* what)
    : BC_XException("Not_Null", who, what) 
    {}

};

class BC_XNotRoot : public BC_XException {
public:

  BC_XNotRoot(const char* who, const char* what)
    : BC_XException("Not_Root",who, what) 
    {}

};

class BC_XOverflow : public BC_XException {
public:

  BC_XOverflow(const char* who, const char* what)
    : BC_XException("Overflow", who, what) 
    {}

};

class BC_XRangeError : public BC_XException {
public:

  BC_XRangeError(const char* who, const char* what)
    : BC_XException("Range_Error", who, what) 
    {}

};

class BC_XStorageError : public BC_XException {
public:

  BC_XStorageError(const char* who, const char* what)
    : BC_XException("Storage_Error", who, what) 
    {}

};

class BC_XUnderflow : public BC_XException {
public:

  BC_XUnderflow(const char* who, const char* what)
    : BC_XException("Underflow", who, what) 
    {}

};

// Exception handler

extern void BC_Catch(const BC_XException&);

// Assertion function

#ifdef BC_DEBUG
inline void BC_Assert(BC_Boolean expression, const BC_XException& exception)
{
  if (!expression)
    throw(exception);
}
#else
inline void BC_Assert(BC_Boolean, const BC_XException&) {}
#endif

#endif
