// exception standard header for Microsoft
#pragma once
#ifndef _EXCEPTION_
#define _EXCEPTION_
#ifndef RC_INVOKED

#include "xstddef"

 #pragma pack(push,_CRT_PACKING)
 #pragma warning(push,3)

#ifdef _CRT_EXCEPTION_NO_MALLOC

  #pragma push_macro("malloc")
  #pragma push_macro("free")

 #undef malloc
 #undef free
#endif /* _CRT_EXCEPTION_NO_MALLOC */

_STD_BEGIN

  #define _USE_EXCEPTION \
	using _STDEXT exception;

  #define _USE_BAD_EXCEPTION \
	using _STDEXT bad_alloc; \
	using _STDEXT bad_exception;

  #define _USE_EX \
	using ::set_terminate; using ::terminate_handler; using ::terminate; \
	using ::set_unexpected; using ::unexpected_handler; using ::unexpected;

_STD_END

 #if _HAS_EXCEPTIONS

 #include "eh.h"
 #include "malloc.h"
 #include "string.h"

 #if !defined(_WIN32)
  #error ERROR: Only Win32 targets supported!
 #endif /* !defined(_WIN32) */

 #ifndef _CRTIMP

   #define _CRTIMP

 #endif	/* _CRTIMP */

#ifndef _ERRNO_T_DEFINED
#define _ERRNO_T_DEFINED
typedef int errno_t;
#endif

#if __STDC_WANT_SECURE_LIB__
#define _CRT_SECURE_STRCPY(dest, destsize, source) ::strcpy_s((dest), (destsize), (source))
#else
#define _CRT_SECURE_STRCPY(dest, destsize, source) ::strcpy((dest), (source))
#endif

 _STD_BEGIN

 #define _EXCEPTION_INLINE

class exception
    {   // base of all library exceptions
public:
    _EXCEPTION_INLINE exception();
    _EXCEPTION_INLINE explicit exception(const char * const &);
    _EXCEPTION_INLINE exception(const char * const &, int);
    _EXCEPTION_INLINE exception(const exception&);
    _EXCEPTION_INLINE exception& operator=(const exception&);
    _EXCEPTION_INLINE virtual ~exception();
    _EXCEPTION_INLINE virtual const char * what() const;

private:
    _EXCEPTION_INLINE void _Copy_str(const char *);
    _EXCEPTION_INLINE void _Tidy();

    const char * _Mywhat;
    bool _Mydofree;
    };

#ifdef _DEFINE_EXCEPTION_MEMBER_FUNCTIONS

_EXCEPTION_INLINE exception::exception()
    : _Mywhat(NULL), _Mydofree(false) { }

_EXCEPTION_INLINE exception::exception(const char * const & _What)
    : _Mywhat(NULL), _Mydofree(false)
    {
    _Copy_str(_What);
    }

_EXCEPTION_INLINE exception::exception(const char * const & _What, int)
    : _Mywhat(_What), _Mydofree(false) { }

_EXCEPTION_INLINE exception::exception(const exception& _That)
    : _Mywhat(NULL), _Mydofree(false)
    {
    *this = _That;
    }

_EXCEPTION_INLINE exception& exception::operator=(const exception& _That)
    {
    if (this != &_That)
        {
        _Tidy();

        if (_That._Mydofree)
            {
            _Copy_str(_That._Mywhat);
            }
        else
            {
            _Mywhat = _That._Mywhat;
            }
        }

    return *this;
    }

_EXCEPTION_INLINE exception::~exception()
    {
    _Tidy();
    }

_EXCEPTION_INLINE const char * exception::what() const
    {
    return _Mywhat ? _Mywhat : "Unknown exception";
    }

// _Copy_str() assumes that *this is already tidy.
_EXCEPTION_INLINE void exception::_Copy_str(const char * _What)
    {
    if (_What != NULL)
        {
        const size_t _Buf_size = strlen(_What) + 1;
        
        _Mywhat = static_cast<char *>(malloc(_Buf_size));
        
        if (_Mywhat != NULL)
            {
            _CRT_SECURE_STRCPY(const_cast<char *>(_Mywhat), _Buf_size, _What);
            _Mydofree = true;
            }
        }
    }

_EXCEPTION_INLINE void exception::_Tidy()
    {
    if (_Mydofree)
        {
        free(const_cast<char *>(_Mywhat));
        }

    _Mywhat = NULL;
    _Mydofree = false;
    }

#endif /* _DEFINE_EXCEPTION_MEMBER_FUNCTIONS */


_USE_EX

typedef void (__cdecl *_Prhand)(const exception&);

bool __cdecl uncaught_exception();

_STD_END

 #else /* _HAS_EXCEPTIONS */

		// CLASS exception
_STDEXT_BEGIN
class exception;
_STDEXT_END

_STD_BEGIN

_USE_EXCEPTION

typedef void (__cdecl *_Prhand)(const exception&);
extern _Prhand _Raise_handler;	// pointer to raise handler

_STD_END

_STDEXT_BEGIN
class exception
	{	// base of all library exceptions
public:

	static _STD _Prhand _Set_raise_handler(_STD _Prhand _Pnew)
		{	// register a handler for _Raise calls
		const _STD _Prhand _Pold = _STD _Raise_handler;
		_STD _Raise_handler = _Pnew;
		return (_Pold);
		}

	// this constructor is necessary to compile 
	// successfully header new for _HAS_EXCEPTIONS==0 scenario
	explicit exception(const char *_Message = "unknown", int x=1)
		_THROW0()
		: _Ptr(_Message)
		{	// construct from message string
                (void)x;
		}

	exception(const exception& _Right) _THROW0()
		: _Ptr(_Right._Ptr)
		{	// construct by copying _Right
		}

	exception& operator=(const exception& _Right) _THROW0()
		{	// assign _Right
		_Ptr = _Right._Ptr;
		return (*this);
		}

	virtual ~exception()
		{	// destroy the object
		}

	virtual const char * what() const _THROW0()
		{	// return pointer to message string
		return (_Ptr != 0 ? _Ptr : "unknown exception");
		}

	void _Raise() const
		{	// raise the exception
		if (_STD _Raise_handler != 0)
			(*_STD _Raise_handler)(*this);	// call raise handler if present

		_Doraise();	// call the protected virtual
		_RAISE(*this);	// raise this exception
		}

protected:
	virtual void _Doraise() const
		{	// perform class-specific exception handling
		}

protected:
	const char *_Ptr;	// the message pointer
	};
_STDEXT_END

_STD_BEGIN

		// TYPES
typedef void (__cdecl *terminate_handler)();
typedef void (__cdecl *unexpected_handler)();

		// DUMMY FUNCTION DECLARATIONS
inline terminate_handler __cdecl set_terminate(terminate_handler)
	_THROW0()
	{	// register a terminate handler
	return 0;
	}

inline unexpected_handler __cdecl set_unexpected(unexpected_handler)
	_THROW0()
	{	// register an unexpected handler
	return 0;
	}

inline void __cdecl terminate()
	{	// handle exception termination
	}

inline void __cdecl unexpected()
	{	// handle unexpected exception
	}

bool __cdecl uncaught_exception();	// handle uncaught exception

_STD_END

 #endif /* _HAS_EXCEPTIONS */

#if _HAS_EXCEPTIONS
_STD_BEGIN
#else
_STDEXT_BEGIN
#endif

		// CLASS bad_exception
class bad_exception : public exception
	{	// base of all bad exceptions
public:
	bad_exception(const char *_Message = "bad exception")
		_THROW0()
		: exception(_Message)
		{	// construct from message string
		}

	virtual ~bad_exception() _THROW0()
		{	// destroy the object
		}

 #if !_HAS_EXCEPTIONS
protected:
	virtual void _Doraise() const
		{	// raise this exception
		_RAISE(*this);
		}
 #endif /* _HAS_EXCEPTIONS */

	};

		// CLASS bad_alloc
class bad_alloc : public exception
	{	// base of all bad allocation exceptions
public:
	bad_alloc(const char *_Message) _THROW0()
		: exception(_Message)
		{	// construct from message string
		}

	bad_alloc() _THROW0()
		: exception("bad allocation", 1)
		{	// construct from message string with no memory allocation
		}

	virtual ~bad_alloc() _THROW0()
		{	// destroy the object
		}

 #if !_HAS_EXCEPTIONS
protected:
	virtual void _Doraise() const
		{	// perform class-specific exception handling
		_RAISE(*this);
		}
#endif  /* _HAS_EXCEPTIONS */

	};

#if _HAS_CPP0X
		// CLASS bad_array_new_length
class bad_array_new_length
	: public bad_alloc
	{	// bad array new exception
public:

	bad_array_new_length() _THROW0()
		: bad_alloc("bad array new length")
		{	// default construct
		}
	};
#endif /* _HAS_CPP0X */

#if _HAS_EXCEPTIONS
_STD_END
#else
_STDEXT_END

_STD_BEGIN

_USE_BAD_EXCEPTION

_STD_END

#endif

void __cdecl __ExceptionPtrCreate(_Out_ void* );
void __cdecl __ExceptionPtrDestroy(_Inout_ void* );
void __cdecl __ExceptionPtrCopy(_Out_ void*, _In_ const void* );
void __cdecl __ExceptionPtrAssign(_Inout_ void*, _In_ const void* );
bool __cdecl __ExceptionPtrCompare(_In_ const void*, _In_ const void*);

void __cdecl __ExceptionPtrCurrentException(_Out_ void*);
void __cdecl __ExceptionPtrRethrow(_In_ const void*);
void __cdecl __ExceptionPtrCopyException(_Inout_ void*, _In_ const void*, _In_ const void*);

_STD_BEGIN

#if defined(_NATIVE_NULLPTR_SUPPORTED) && !defined(_DO_NOT_USE_NULLPTR_IN_STL)
typedef _STD nullptr_t _Null_type;
#else /* defined(_NATIVE_NULLPTR_SUPPORTED) && !defined(_DO_NOT_USE_NULLPTR_IN_STL) */
typedef int _Null_type;
#endif /* defined(_NATIVE_NULLPTR_SUPPORTED) && !defined(_DO_NOT_USE_NULLPTR_IN_STL) */

class _Exception_ptr
	{
public:
	_Exception_ptr()
		{
		__ExceptionPtrCreate(this);
		}
	_Exception_ptr(_Null_type)
		{
		__ExceptionPtrCreate(this);
		}
	~_Exception_ptr()
		{
		__ExceptionPtrDestroy(this);
		}
	_Exception_ptr(_In_ const _Exception_ptr& _Rhs)
		{
		__ExceptionPtrCopy(this, const_cast<_Exception_ptr*>(&_Rhs));
		}
	_Exception_ptr& operator=(_In_ const _Exception_ptr& _Rhs)
		{
		__ExceptionPtrAssign(this, const_cast<_Exception_ptr*>(&_Rhs));
		return *this;
		}
	_Exception_ptr& operator=(_Null_type)
		{
		_Exception_ptr _Ptr;
		__ExceptionPtrAssign(this, &_Ptr);
		return *this;
		}

	void _RethrowException() const
		{
		__ExceptionPtrRethrow(const_cast<_Exception_ptr*>(this));
		}

	static _Exception_ptr _Current_exception()
		{
		_Exception_ptr _Retval;
		__ExceptionPtrCurrentException(&_Retval);
		return _Retval;
		}
	static _Exception_ptr _Copy_exception(_In_ void* _Except, _In_ const void* _Ptr)
		{
		_Exception_ptr _Retval = NULL;
		if (!_Ptr)
			{
			// unsupported exceptions
			return _Retval;
			}
		__ExceptionPtrCopyException(&_Retval, _Except, _Ptr);
		return _Retval;
		}
private:
	void* _Data1;
	void* _Data2;
	};

inline bool operator==(_In_ const _Exception_ptr& _Lhs, _In_ const _Exception_ptr& _Rhs)
	{
	return __ExceptionPtrCompare(const_cast<_Exception_ptr*>(&_Lhs),const_cast<_Exception_ptr*>(&_Rhs));
	}

inline bool operator==(_Null_type, _In_ const _Exception_ptr& _Rhs)
	{
	_Exception_ptr _Ptr;
	return __ExceptionPtrCompare(&_Ptr,const_cast<_Exception_ptr*>(&_Rhs));
	}

inline bool operator==(_In_ const _Exception_ptr& _Lhs, _Null_type)
	{
	return operator==(NULL,_Lhs);
	}

typedef _Exception_ptr exception_ptr;

inline exception_ptr current_exception()
	{
	return _Exception_ptr::_Current_exception();
	}

inline void rethrow_exception(_In_ exception_ptr _P)
	{
	_P._RethrowException();
	}

template <class _E> void *__GetExceptionInfo(_E);

template<class _E> exception_ptr copy_exception(_E _Except)
	{
	return _Exception_ptr::_Copy_exception(&_Except, __GetExceptionInfo(_Except));
	}

_STD_END


#ifdef _CRT_EXCEPTION_NO_MALLOC
  #pragma pop_macro("free")
  #pragma pop_macro("malloc")
#endif /* _CRT_EXCEPTION_NO_MALLOC */

 #pragma warning(pop)
 #pragma pack(pop)

#endif /* RC_INVOKED */
#endif /* _EXCEPTION_ */

/*
 * Copyright (c) 1992-2007 by P.J. Plauger.  ALL RIGHTS RESERVED.
 * Consult your license regarding permissions and restrictions.
 V5.03:0009 */
