::value || std::is_same
::value || std::is_same
::value,
+ "scope_guard requires on_exit_policy, on_fail_policy or on_success_policy.");
+#if defined(SCOPE_GUARD_NO_THROW_ACTION)
+ static_assert(is_nothrow_invocable_action::value,
+ "scope_guard requires noexcept invocable action.");
+#endif
+#if defined(SCOPE_GUARD_NO_THROW_CONSTRUCTIBLE)
+ static_assert(std::is_nothrow_move_constructible::value,
+ "scope_guard requires nothrow constructible action.");
+#endif
+
+ P policy_;
+ A action_;
+
+ void* operator new(std::size_t) = delete;
+ void operator delete(void*) = delete;
+
+ public:
+ scope_guard() = delete;
+ scope_guard(const scope_guard&) = delete;
+ scope_guard& operator=(const scope_guard&) = delete;
+ scope_guard& operator=(scope_guard&&) = delete;
+
+ scope_guard(scope_guard&& other) noexcept(std::is_nothrow_move_constructible::value)
+ : policy_{false},
+ action_{NEARGYE_MOV(other.action_)} {
+ policy_ = NEARGYE_MOV(other.policy_);
+ other.policy_.dismiss();
+ }
+
+ scope_guard(const A& action) = delete;
+ scope_guard(A& action) = delete;
+
+ explicit scope_guard(A&& action) noexcept(std::is_nothrow_move_constructible::value)
+ : policy_{true},
+ action_{NEARGYE_MOV(action)} {}
+
+ void dismiss() noexcept {
+ policy_.dismiss();
+ }
+
+ ~scope_guard() NEARGYE_NOEXCEPT(is_nothrow_invocable_action::value) {
+ if (policy_.should_execute()) {
+ NEARGYE_TRY
+ action_();
+ NEARGYE_CATCH
+ }
+ }
+};
+
+template