except.h

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C头文件 代码 · 共 773 行 · 第 1/2 页

H
773
字号

  // the private state of an object cannot
  // be mapped into a valid public state
  // when such a mapping is required

  // For example: a float value is a NaN, a rational number
  // has a zero denominator

  // Represents either a client protocol violation such
  // as uninitialised value, or a library class programming
  // error

  struct representation_invariant_violation :
    public virtual exception {};

//----------------------------------------------------------------------
// DEBUGGING: ALGORITHMIC FAILURES (BUGS)

  // a user assertion has failed, usually indicating
  // a programming error

  struct assertion_failure :
    public virtual exception {};

    // an invariant of a loop has changed

    struct loop_invariant_violation :
      public virtual assertion_failure {};

    // a loop variant has not changed

    struct loop_variant_violation :
      public virtual assertion_failure {};

    // a user written check on an function's post-conditions
    // has revealed the procedure has not executed successfully

    struct postcondition_failure :
      public virtual assertion_failure {};

    // a point in the program which should not have been reachable
    // has been reached

    struct unreachable_code_reached :
      public virtual assertion_failure {};

//----------------------------------------------------------------------
// DEBUGGING: MESSAGES

  struct exception_message :
    public virtual exception
  {
    virtual char const *what()const=0;
  };

  struct source_reference :
    public virtual exception
  {
    virtual char const* file()const=0;
    virtual int line()const=0;
  };


  struct source_message :
    public virtual exception_message,
    public virtual source_reference {};


//----------------------------------------------------------------------
// DEBUGGING: TRACEBACK BY DELEGATION

  struct exception_backtrace :
    public virtual exception
  {
    virtual exception const *getBacktrace()const=0;
  };

//----------------------------------------------------------------------
// IMPLEMENTATION MIXINS
//
// ALL these classes are concrete implementations of abstractions
// They should be mixed into a derived class.
// Subsequent derivation is possible but must NOT mixin the same
// implementation mixins or duplicate concrete bases will exist
// It is simplest to mixin all implementations in the most
// derived class.

//  #define CLONE(T) T* clone()const { return new T(*this); }
// Metaware doesn't support covariant returns yet
  #define CLONE(T) exception * clone()const {\
    exception *x = new T(*this);\
    dprintf(("%p [%s] Cloned %p [%s]\n",getidx(this),typeid(*this).name(), getidx(x), typeid(*x).name()));\
    return x; }


//----------------------------------------------------------------------
  // backtrace exception mixin maintains a pointer
  // chain of exceptions to enable historical reporting
  // of the source of an exception despite translation.
  // It can also be used to create and throw a list of exceptions.
  //
  // To translate an X to a Y, derive Y from the backtrace
  // implementation, and initialise it with X.
  // The backtrace object creates a clone of the X object.

  // We'd do better here by using a smart pointer.
  // But the rule is to have "very weak coupling". Oh well.

  struct exception_backtrace_impl :
    public virtual exception_backtrace
  {
    exception const * back;
    CLONE(exception_backtrace_impl)

    #if defined(NORTTI)
    char const *name()const { return "exception_backtrace_impl"; }
    #endif

    exception_backtrace_impl() :
      back(0) {dprintf(("WOOPS, constructed backtrace object with NULL attached\n")); }

    // user constructor to link clone of old exception into this one
    exception_backtrace_impl(exception const *b)
//    : back(b->clone())
      {
        if(b) back=b->clone();
        else back=0;
        dprintf(("ATTACH: the clone %p of %p to %p\n",getidx(back),getidx(b),getidx(this)));
      }

    // copy constructor: used by EH system NOT user!!
    exception_backtrace_impl(exception_backtrace_impl const& x)
//    : back(x.back->clone())
      {
      dprintf(("COPY->BEGIN: Copy backtrace object %p --> %p \n",getidx(&x),getidx(this)));
      dprintf(("Linked object of source is %p\n",getidx(x.back)));
      if(x.back)
      {
        back = x.back->clone();
        dprintf(("Linked object cloned to %p and attached to %p\n", getidx(back), getidx(this)));
      }
      else back=0;
      dprintf(("COPY->END:   Copy backtrace object %p --> %p done\n",getidx(&x),getidx(this)));
      }

    void operator=(exception_backtrace_impl const& b)
    {
      if(back != b.back)
      {
        #if defined(DELCONSTCAST)
        delete const_cast<exception*>(back); // ugly const cast!!
        #elif defined (DELOLDCAST)
        delete (exception*)(back); // uglier old style cast const cast!!
        #else
        delete back;
        #endif
        if(b.back)back = b.back->clone();
        else back=0;
      }
    }

    ~exception_backtrace_impl()
    {
      dprintf(("Destructor %p is Deleting backtrace %p\n",getidx(this),getidx(back)));
      #if defined(DELCONSTCAST)
      delete const_cast<exception*>(back); // ugly const cast!!
      #elif defined(DELOLDCAST)
      delete (exception*)(back); // uglier old style cast const cast!!
      #else
      delete back;
      #endif
    }

    exception const * getBacktrace() const { return back; }
    #if defined(NODYNCAST)
    exception_backtrace const * downcast_backtrace()const { return this; }
    #endif
  };

//----------------------------------------------------------------------

  // exception message

  struct exception_message_impl :
    public virtual exception_message
  {
    #if defined(NORTTI)
    char const *name()const { return "exception_message_impl"; }
    #endif
    #if defined(NODYNCAST)
    exception_message const * downcast_exception_message() const { return this; }
    #endif
    CLONE(exception_message_impl)
    strng message;
    exception_message_impl(char const *p) : message(p) {}
    char const *what()const { return message.data; }
  };

//----------------------------------------------------------------------

  // source reference

  struct source_reference_impl :
    public virtual source_reference
  {
    #if defined(NORTTI)
    char const *name()const { return "source_reference_impl"; }
    #endif
    #if defined(NODYNCAST)
    source_reference const * downcast_source_reference() const { return this; }
    #endif
    CLONE(source_reference_impl)

    char const* fileName;
    int lineNumber;

    source_reference_impl(char const *f, int l) :
      fileName(f), lineNumber(l) {}

    char const *file()const { return fileName; }
    int line()const { return lineNumber; }
  };

  struct source_message_impl :
    public virtual source_message,
    public source_reference_impl,
    public exception_message_impl
  {
    #if defined(NORTTI)
    char const *name()const { return "source_message_impl"; }
    #endif
    CLONE(source_message_impl)
    source_message_impl(char *fi, int li, char *msg) :
      source_reference_impl(fi,li),
      exception_message_impl(msg) {}
  };

//----------------------------------------------------------------------

  // implementation of bad_alloc

  struct bad_alloc_impl :
    public virtual bad_alloc
  {
    #if defined(NORTTI)
    char const *name()const { return "bad_alloc_impl"; }
    #endif
    size_t requested;
    size_t available;
    bad_alloc_impl() : requested(0), available(0) {}
    bad_alloc_impl(size_t r, size_t a) : requested(r), available(a) {}
    size_t requested_store() const { return requested; }
    size_t available_block() const { return available; }
    CLONE(bad_alloc_impl)
  };

  struct bad_alloc_msg :
    public bad_alloc_impl,
    public exception_message_impl
  {
    #if defined(NORTTI)
    char const *name()const { return "bad_alloc_msg"; }
    #endif
    CLONE(bad_alloc_msg)
    bad_alloc_msg(bad_alloc_impl e, char const* p) :
      bad_alloc_impl(e),
      exception_message_impl(p) {}
  };

//----------------------------------------------------------------------

  // implementation of bad_cast_diagnostic

  struct bad_cast_diagnostic_impl : public virtual bad_cast_diagnostic
  {
    #if defined(NORTTI)
    char const *name()const { return "bad_cast_diagnostic_impl"; }
    #endif
    CLONE(bad_cast_diagnostic_impl)

    Type_info const &typeid_destination() const
      {
        return *dst;
      }

    Type_info const &typeid_source() const
      {
        return *src;
      }

  // implementor sets these pointers inside dynamic_cast
    Type_info *dst;
    Type_info *src;
  };

//----------------------------------------------------------------------
//
// Note that exception_message_impl is used as a _non-virtual_
// base of the T##_msg class. Thats because it requires nondefault
// initialisation.

#if defined(NORTTI)
  #define IMPLEMENT(T)                         \
  struct T##_impl : public virtual T           \
  {                                            \
    char const *name()const { return #T"_impl"; } \
    CLONE(T##_impl)                            \
  };                                           \
                                               \
  struct T##_msg :                             \
    public virtual T,                          \
    public exception_message_impl              \
  {                                            \
    char const *name()const { return #T"_msg"; }   \
    CLONE(T##_msg)                             \
    T##_msg(char const* p) :                   \
      exception_message_impl(p) {}             \
  };                                           \
                                               \
  struct T##_src:                              \
    public virtual T,                          \
    public source_reference_impl               \
  {                                            \
    char const *name()const { return #T"_src"; }   \
    CLONE(T##_src)                             \
    T##_src(char const* p, int l) :            \
      source_reference_impl(p,l) {}            \
  };

#else

  #define IMPLEMENT(T)                         \
  struct T##_impl : public virtual T           \
  {                                            \
    CLONE(T##_impl)                            \
  };                                           \
                                               \
  struct T##_msg :                             \
    public virtual T,                          \
    public exception_message_impl              \
  {                                            \
    CLONE(T##_msg)                             \
    T##_msg(char const* p) :                   \
      exception_message_impl(p) {}             \
  };                                           \
                                               \
  struct T##_src:                              \
    public virtual T,                          \
    public source_reference_impl               \
  {                                            \
    CLONE(T##_src)                             \
    T##_src(char const* p, int l) :            \
      source_reference_impl(p,l) {}            \
  };

#endif

  IMPLEMENT(exception)
  IMPLEMENT(resource_acquisition_failure)
  IMPLEMENT(timeout)
  IMPLEMENT(precondition_violation)
  IMPLEMENT(null_pointer_error)
  IMPLEMENT(arithmetic_domain_error)
  IMPLEMENT(arithmetic_argument_error)
  IMPLEMENT(index_error)
  IMPLEMENT(implementation_limit_exceeded)
  IMPLEMENT(floating_overflow)
  IMPLEMENT(floating_underflow)
  IMPLEMENT(integral_overflow)
  IMPLEMENT(protocol_violation)
  IMPLEMENT(pure_virtual_called)
  IMPLEMENT(exception_specification_violation)
  IMPLEMENT(representation_invariant_violation)
  IMPLEMENT(assertion_failure)
  IMPLEMENT(loop_invariant_violation)
  IMPLEMENT(loop_variant_violation)
  IMPLEMENT(postcondition_failure)
  IMPLEMENT(unreachable_code_reached)

  #undef IMPLEMENT
//  #undef CLONE
//}

// END LIBRARY HEADER ------------------------------------------------
#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?