MeshLib
 
Loading...
Searching...
No Matches
MRFinally.h
Go to the documentation of this file.
1#pragma once
2
3#include "MRMacros.h"
4
5#ifdef __cpp_exceptions
6#include <exception>
7#endif
8#include <utility>
9
11#define MR_FINALLY DETAIL_MR_FINALLY( ScopeGuard )
12
13#ifdef __cpp_exceptions
14
16#define MR_FINALLY_ON_SUCCESS DETAIL_MR_FINALLY( ExceptionScopeGuard<true>::Type )
17
19#define MR_FINALLY_ON_THROW DETAIL_MR_FINALLY( ExceptionScopeGuard<false>::Type )
20
21#else // If no exceptions.
22
24#define MR_FINALLY_ON_SUCCESS MR_FINALLY
26#define MR_FINALLY_ON_THROW (void)[&]()
27
28#endif // If no exceptions.
29
30#define DETAIL_MR_FINALLY( type_ ) \
31 auto MR_CONCAT( _mrScopeGuard, __COUNTER__ ) = ::MR::detail::MakeScopeGuard<::MR::detail::type_>{} ->* [&]() -> void
32
33namespace MR::detail
34{
35
36template <typename F>
38{
39 F func;
40
41public:
42 ScopeGuard( F&& func ) : func( std::move( func ) ) {}
43 ScopeGuard( const ScopeGuard& ) = delete;
44 ScopeGuard& operator=( const ScopeGuard& ) = delete;
45 ~ScopeGuard() { func(); }
46};
47
48#ifdef __cpp_exceptions
49template <bool Success>
50struct ExceptionScopeGuard
51{
52 template <typename F>
53 class Type
54 {
55 F func;
56 int ex = std::uncaught_exceptions();
57
58 public:
59 Type( F&& func ) : func( std::move( func ) ) {}
60 Type( const Type& ) = delete;
61 Type& operator=( const Type& ) = delete;
62 ~Type() noexcept( !Success )
63 {
64 if ( ( ex == std::uncaught_exceptions() ) == Success )
65 func();
66 }
67 };
68};
69#endif
70
71template <template <typename> typename T>
73{
74 template <typename F>
75 T<F> operator->*( F&& func )
76 {
77 return T<F>( std::move( func ) );
78 }
79};
80
81} // namespace MR::detail
Definition MRFinally.h:38
~ScopeGuard()
Definition MRFinally.h:45
ScopeGuard(F &&func)
Definition MRFinally.h:42
ScopeGuard & operator=(const ScopeGuard &)=delete
ScopeGuard(const ScopeGuard &)=delete
Definition MRFinally.h:34
Definition MRFinally.h:73
T< F > operator->*(F &&func)
Definition MRFinally.h:75