123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- /*
- * 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
|