Run Code  | API  | Code Wall  | Misc  | Feedback  | Login  | Theme  | Privacy  | Patreon 

MSVC14 <exception> header

Language: Layout:
+ ] Compiler args + ] Show input
Compilation time: 2,28 sec, absolute running time: 0,33 sec, absolute service time: 2,63 sec 
edit mode |  history  | discussion
// exception standard header for Microsoft
#pragma once
#ifndef _EXCEPTION_
#define _EXCEPTION_
#ifndef RC_INVOKED

#include <type_traits>

 #pragma pack(push,_CRT_PACKING)
 #pragma warning(push,3)
 #pragma push_macro("new")
 #undef new

_STD_BEGIN

  #define _USE_EXCEPTION \
	using _STDEXT exception;

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

  #ifdef _M_CEE_PURE
  #define _USE_EX \
	using ::terminate; \
	using ::unexpected;
  #else /* _M_CEE_PURE */
  #define _USE_EX \
	using ::set_terminate; using ::terminate_handler; using ::terminate; \
	using ::set_unexpected; using ::unexpected_handler; using ::unexpected;
  #endif /* _M_CEE_PURE */

_CRTIMP2_PURE bool __CLRCALL_PURE_OR_CDECL uncaught_exception() _NOEXCEPT;
_CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL uncaught_exceptions() _NOEXCEPT;

_STD_END

 #if _HAS_EXCEPTIONS

#include <malloc.h>
#include <vcruntime_exception.h>

_STD_BEGIN

_USE_EX

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

#ifndef _M_CEE_PURE
inline terminate_handler __CRTDECL get_terminate() _NOEXCEPT
	{	// get current terminate handler
	return (_get_terminate());
	}

inline unexpected_handler __CRTDECL get_unexpected() _NOEXCEPT
	{	// get current unexpected handler
	return (_get_unexpected());
	}
#endif /* _M_CEE_PURE */

_STD_END

 #else /* _HAS_EXCEPTIONS */

		// CLASS exception
_STDEXT_BEGIN
class exception;
_STDEXT_END

_STD_BEGIN

_USE_EXCEPTION

typedef void (__cdecl *_Prhand)(const exception&);
extern _CRTIMP2_NCEEPURE _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 __CLR_OR_THIS_CALL exception(const char *_Message = "unknown", int x=1)
		_THROW0()
		: _Ptr(_Message)
		{	// construct from message string
				(void)x;
		}

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

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

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

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

	void __CLR_OR_THIS_CALL _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 __CLR_OR_THIS_CALL _Doraise() const
		{	// perform class-specific exception handling
		}

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

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

	virtual __CLR_OR_THIS_CALL ~bad_exception() _NOEXCEPT
		{	// destroy the object
		}

protected:
	virtual void __CLR_OR_THIS_CALL _Doraise() const
		{	// raise this exception
		_RAISE(*this);
		}
	};

	// CLASS bad_alloc
class bad_alloc : public exception
	{	// base of all bad allocation exceptions
public:
	__CLR_OR_THIS_CALL bad_alloc() _THROW0()
		: exception("bad allocation", 1)
		{	// construct from message string with no memory allocation
		}

	virtual __CLR_OR_THIS_CALL ~bad_alloc() _NOEXCEPT
		{	// destroy the object
		}

private:
	friend class bad_array_new_length;

	__CLR_OR_THIS_CALL bad_alloc(const char *_Message) _THROW0()
		: exception(_Message, 1)
		{	// construct from message string with no memory allocation
		}

protected:
	virtual void __CLR_OR_THIS_CALL _Doraise() const
		{	// perform class-specific exception handling
		_RAISE(*this);
		}
	};

_STDEXT_END

_STD_BEGIN

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

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

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

inline void __CRTDECL terminate() _NOEXCEPT
	{	// handle exception termination
	}

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

inline terminate_handler __CRTDECL get_terminate() _NOEXCEPT
	{	// get current terminate handler
	return (0);
	}

inline unexpected_handler __CRTDECL get_unexpected() _NOEXCEPT
	{	// get current unexpected handler
	return (0);
	}

_STD_END

 #endif /* _HAS_EXCEPTIONS */

#if !(_HAS_EXCEPTIONS)

_STD_BEGIN

_USE_BAD_EXCEPTION

_STD_END

#endif

_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrCreate(_Out_ void*);
_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrDestroy(_Inout_ void*);
_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrCopy(_Out_ void*, _In_ const void*);
_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrAssign(_Inout_ void*, _In_ const void*);
_CRTIMP2_PURE bool __CLRCALL_PURE_OR_CDECL __ExceptionPtrCompare(_In_ const void*, _In_ const void*);
_CRTIMP2_PURE bool __CLRCALL_PURE_OR_CDECL __ExceptionPtrToBool(_In_ const void*);
_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrSwap(_Inout_ void*, _Inout_ void*);
_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrCurrentException(_Out_ void*);
[[noreturn]] _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrRethrow(_In_ const void*);
_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrCopyException(_Inout_ void*, _In_ const void*, _In_ const void*);

_STD_BEGIN

class exception_ptr
	{
public:
	exception_ptr() throw ()
		{
		__ExceptionPtrCreate(this);
		}

	exception_ptr(nullptr_t) throw ()
		{
		__ExceptionPtrCreate(this);
		}

	~exception_ptr() throw ()
		{
		__ExceptionPtrDestroy(this);
		}

	exception_ptr(const exception_ptr& _Rhs) throw ()
		{
		__ExceptionPtrCopy(this, &_Rhs);
		}

	exception_ptr& operator=(const exception_ptr& _Rhs) throw ()
		{
		__ExceptionPtrAssign(this, &_Rhs);
		return *this;
		}

	exception_ptr& operator=(nullptr_t) throw ()
		{
		exception_ptr _Ptr;
		__ExceptionPtrAssign(this, &_Ptr);
		return *this;
		}

	explicit operator bool() const throw ()
		{
		return __ExceptionPtrToBool(this);
		}

	[[noreturn]] void _RethrowException() const
		{
		__ExceptionPtrRethrow(this);
		}

	static exception_ptr _Current_exception() throw ()
		{
		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 void swap(exception_ptr& _Lhs, exception_ptr& _Rhs) throw ()
	{
	__ExceptionPtrSwap(&_Lhs, &_Rhs);
	}

inline bool operator==(const exception_ptr& _Lhs, const exception_ptr& _Rhs) throw ()
	{
	return __ExceptionPtrCompare(&_Lhs, &_Rhs);
	}

inline bool operator==(nullptr_t, const exception_ptr& _Rhs) throw ()
	{
	return !_Rhs;
	}

inline bool operator==(const exception_ptr& _Lhs, nullptr_t) throw ()
	{
	return !_Lhs;
	}

inline bool operator!=(const exception_ptr& _Lhs, const exception_ptr& _Rhs) throw ()
	{
	return !(_Lhs == _Rhs);
	}

inline bool operator!=(nullptr_t _Lhs, const exception_ptr& _Rhs) throw ()
	{
	return !(_Lhs == _Rhs);
	}

inline bool operator!=(const exception_ptr& _Lhs, nullptr_t _Rhs) throw ()
	{
	return !(_Lhs == _Rhs);
	}

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

[[noreturn]] inline void rethrow_exception(_In_ exception_ptr _Ptr)
	{
	_Ptr._RethrowException();
	}

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

template<class _Ex> exception_ptr make_exception_ptr(_Ex _Except) _NOEXCEPT
	{
 #ifdef __clang__ /* TRANSITION */
  #if _HAS_EXCEPTIONS
	try
		{
		throw _Except;
		}
	catch (...)
		{
		return _XSTD current_exception();
		}
  #else /* _HAS_EXCEPTIONS */
	(void) _Except;
	return exception_ptr();
  #endif /* _HAS_EXCEPTIONS */
 #else /* __clang__ */
	return exception_ptr::_Copy_exception(_STD addressof(_Except), __GetExceptionInfo(_Except));
 #endif /* __clang__ */
	}

	// CLASS nested_exception
class nested_exception
	{	// wrap an exception_ptr
public:
	nested_exception() _NOEXCEPT
		: _Exc(_XSTD current_exception())
		{	// default construct
		}

	nested_exception(const nested_exception&) _NOEXCEPT = default;
	nested_exception& operator=(const nested_exception&) _NOEXCEPT = default;
	virtual ~nested_exception() _NOEXCEPT = default;

	[[noreturn]] void rethrow_nested() const
		{	// throw wrapped exception_ptr
		if (_Exc)
			_XSTD rethrow_exception(_Exc);
		else
			_XSTD terminate();
		}

	_XSTD exception_ptr nested_ptr() const _NOEXCEPT
		{	// return wrapped exception_ptr
		return (_Exc);
		}

private:
	_XSTD exception_ptr _Exc;
	};

	// TEMPLATE FUNCTION throw_with_nested
template<class _Ty,
	class _Uty>
	struct _With_nested
		: _Uty, nested_exception
	{	// glue user exception to nested_exception
	explicit _With_nested(_Ty&& _Arg)
		: _Uty(_STD forward<_Ty>(_Arg)), nested_exception()
		{	// store user exception and current_exception()
		}
	};

template<class _Ty>
	[[noreturn]] inline void _Throw_with_nested(_Ty&& _Arg, true_type)
	{	// throw user exception glued to nested_exception
	typedef typename remove_reference<_Ty>::type _Uty;
	typedef _With_nested<_Ty, _Uty> _Glued;

	_THROW_NCEE(_Glued, _STD forward<_Ty>(_Arg));
	}

template<class _Ty>
	[[noreturn]] inline void _Throw_with_nested(_Ty&& _Arg, false_type)
	{	// throw user exception by itself
	typedef typename decay<_Ty>::type _Decayed;

	_THROW_NCEE(_Decayed, _STD forward<_Ty>(_Arg));
	}

template<class _Ty>
	[[noreturn]] inline void throw_with_nested(_Ty&& _Arg)
	{	// throw user exception, glued to nested_exception if possible
	typedef typename remove_reference<_Ty>::type _Uty;

	integral_constant<bool,
		is_class<_Uty>::value
		&& !is_base_of<nested_exception, _Uty>::value
		&& !is_final<_Uty>::value> _Tag;

	_Throw_with_nested(_STD forward<_Ty>(_Arg), _Tag);
	}

	// TEMPLATE FUNCTION rethrow_if_nested
template<class _Ty> inline
	void _Rethrow_if_nested(const _Ty *_Ptr, true_type)
	{	// use dynamic_cast
	const auto _Nested = dynamic_cast<const nested_exception *>(_Ptr);

	if (_Nested)
		_Nested->rethrow_nested();
	}

template<class _Ty> inline
	void _Rethrow_if_nested(const _Ty *, false_type)
	{	// can't use dynamic_cast
	}

template<class _Ty> inline
	void rethrow_if_nested(const _Ty& _Arg)
	{	// detect nested_exception inheritance
	integral_constant<bool,
		is_polymorphic<_Ty>::value
		&& (!is_base_of<nested_exception, _Ty>::value
			|| is_convertible<_Ty *, nested_exception *>::value)> _Tag;

	_Rethrow_if_nested(_STD addressof(_Arg), _Tag);
	}
_STD_END

 #pragma pop_macro("new")
 #pragma warning(pop)
 #pragma pack(pop)

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

/*
 * Copyright (c) by P.J. Plauger. All rights reserved.
 * Consult your license regarding permissions and restrictions.
V6.50:0009 */