From 6496c1b8061fb3ea32726ed436e02b4cbb8f06c5 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max.kellermann@gmail.com>
Date: Mon, 22 May 2023 21:20:41 +0200
Subject: [PATCH] util/ScopeExit: convert the function from base class to
 member

This allows using `final` callables.
---
 src/util/ScopeExit.hxx | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/src/util/ScopeExit.hxx b/src/util/ScopeExit.hxx
index c6278a977..9e1cc5dde 100644
--- a/src/util/ScopeExit.hxx
+++ b/src/util/ScopeExit.hxx
@@ -10,14 +10,18 @@
  * Internal class.  Do not use directly.
  */
 template<typename F>
-class ScopeExitGuard : F {
+class ScopeExitGuard {
+	[[no_unique_address]]
+	F function;
+
 	bool enabled = true;
 
 public:
-	explicit ScopeExitGuard(F &&f) noexcept:F(std::forward<F>(f)) {}
+	explicit ScopeExitGuard(F &&f) noexcept
+		:function(std::forward<F>(f)) {}
 
 	ScopeExitGuard(ScopeExitGuard &&src) noexcept
-		:F(std::move(src)),
+		:function(std::move(src.function)),
 		 enabled(std::exchange(src.enabled, false)) {}
 
 	/* destructors are "noexcept" by default; this explicit
@@ -26,7 +30,7 @@ public:
 	   would std::terminate() */
 	~ScopeExitGuard() noexcept(noexcept(std::declval<F>()())) {
 		if (enabled)
-			F::operator()();
+			function();
 	}
 
 	ScopeExitGuard(const ScopeExitGuard &) = delete;