diff options
Diffstat (limited to 'Src/external_dependencies/openmpt-trunk/misc/mptOSException.h')
-rw-r--r-- | Src/external_dependencies/openmpt-trunk/misc/mptOSException.h | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/Src/external_dependencies/openmpt-trunk/misc/mptOSException.h b/Src/external_dependencies/openmpt-trunk/misc/mptOSException.h new file mode 100644 index 00000000..a85f8bda --- /dev/null +++ b/Src/external_dependencies/openmpt-trunk/misc/mptOSException.h @@ -0,0 +1,180 @@ +/* + * mptOSException.h + * ---------------- + * Purpose: platform-specific exception/signal handling + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + + +#pragma once + +#include "openmpt/all/BuildSettings.hpp" + +#include "mptBaseMacros.h" +#include "mptBaseTypes.h" + +#if MPT_OS_WINDOWS +#include <windows.h> +#endif // MPT_OS_WINDOWS + + +OPENMPT_NAMESPACE_BEGIN + + +#if MPT_OS_WINDOWS + + +namespace Windows +{ + + +namespace SEH +{ + + +struct Code +{ +private: + DWORD m_Code; +public: + constexpr Code(DWORD code) noexcept + : m_Code(code) + { + return; + } +public: + constexpr DWORD code() const noexcept + { + return m_Code; + } +}; + + +template <typename Tfn, typename Tfilter, typename Thandler> +auto TryFilterHandleThrow(const Tfn &fn, const Tfilter &filter, const Thandler &handler) -> decltype(fn()) +{ + static_assert(std::is_trivially_copy_assignable<decltype(fn())>::value); + static_assert(std::is_trivially_copy_constructible<decltype(fn())>::value); + static_assert(std::is_trivially_move_assignable<decltype(fn())>::value); + static_assert(std::is_trivially_move_constructible<decltype(fn())>::value); + DWORD code = 0; + __try + { + return fn(); + } __except(filter(GetExceptionCode(), GetExceptionInformation())) + { + code = GetExceptionCode(); + } + throw Windows::SEH::Code(code); +} + + +template <typename Tfn, typename Tfilter, typename Thandler> +void TryFilterHandleVoid(const Tfn &fn, const Tfilter &filter, const Thandler &handler) +{ + static_assert(std::is_same<decltype(fn()), void>::value || std::is_trivially_copy_assignable<decltype(fn())>::value); + static_assert(std::is_same<decltype(fn()), void>::value || std::is_trivially_copy_constructible<decltype(fn())>::value); + static_assert(std::is_same<decltype(fn()), void>::value || std::is_trivially_move_assignable<decltype(fn())>::value); + static_assert(std::is_same<decltype(fn()), void>::value || std::is_trivially_move_constructible<decltype(fn())>::value); + __try + { + fn(); + return; + } __except(filter(GetExceptionCode(), GetExceptionInformation())) + { + DWORD code = GetExceptionCode(); + handler(code); + } + return; +} + + +template <typename Tfn, typename Tfilter, typename Thandler> +auto TryFilterHandleDefault(const Tfn &fn, const Tfilter &filter, const Thandler &handler, decltype(fn()) def = decltype(fn()){}) -> decltype(fn()) +{ + static_assert(std::is_trivially_copy_assignable<decltype(fn())>::value); + static_assert(std::is_trivially_copy_constructible<decltype(fn())>::value); + static_assert(std::is_trivially_move_assignable<decltype(fn())>::value); + static_assert(std::is_trivially_move_constructible<decltype(fn())>::value); + auto result = def; + __try + { + result = fn(); + } __except(filter(GetExceptionCode(), GetExceptionInformation())) + { + DWORD code = GetExceptionCode(); + result = handler(code); + } + return result; +} + + +template <typename Tfn> +auto TryReturnOrThrow(const Tfn &fn) -> decltype(fn()) +{ + return TryFilterHandleThrow( + fn, + [](auto code, auto eptr) + { + MPT_UNREFERENCED_PARAMETER(code); + MPT_UNREFERENCED_PARAMETER(eptr); + return EXCEPTION_EXECUTE_HANDLER; + }, + [](auto code) + { + throw Windows::SEH::Code(code); + }); +} + + +template <typename Tfn> +DWORD TryOrError(const Tfn &fn) +{ + DWORD result = DWORD{0}; + TryFilterHandleVoid( + fn, + [](auto code, auto eptr) + { + MPT_UNREFERENCED_PARAMETER(code); + MPT_UNREFERENCED_PARAMETER(eptr); + return EXCEPTION_EXECUTE_HANDLER; + }, + [&result](auto code) + { + result = code; + }); + return result; +} + + +template <typename Tfn> +auto TryReturnOrDefault(const Tfn &fn, decltype(fn()) def = decltype(fn()){}) -> decltype(fn()) +{ + return TryFilterHandleDefault( + fn, + [](auto code, auto eptr) + { + MPT_UNREFERENCED_PARAMETER(code); + MPT_UNREFERENCED_PARAMETER(eptr); + return EXCEPTION_EXECUTE_HANDLER; + }, + [def](auto code) + { + MPT_UNREFERENCED_PARAMETER(code); + return def; + }); +} + + +} // namspace SEH + + +} // namespace Windows + + +#endif // MPT_OS_WINDOWS + + +OPENMPT_NAMESPACE_END |