[v3,1/2] libcamera: utils: Add scope_exit class
diff mbox series

Message ID 20250730102733.21314-2-laurent.pinchart@ideasonboard.com
State New
Headers show
Series
  • libcamera: Introduce and use scope_exit
Related show

Commit Message

Laurent Pinchart July 30, 2025, 10:27 a.m. UTC
The scope_exit class is an implementation of the identically named C++
library fundamentals TS v3 class, as documented in [1]. It is a simpler
version of the libcamera-specific ScopeExitActions class and doesn't
require dynamic heap memory allocation, making it more suitable for hot
paths.

The class is not documented as it implements a C++ standard (even if
experimental) API.

[1] https://en.cppreference.com/w/cpp/experimental/scope_exit/scope_exit.html

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
Changes since v2:

- Drop lvalue reference constraint in constructor
- Delete move constructor

I have named the class scope_exit instead of ScopeExit to match the C++
library fundamentals TS v3 class, and have not documented it as it's
meant as an implementation of the standard. It is however not clear if
and when scope_exit would become part of a ratified C++ standard, so I'm
open to instead create a libcamera-specific ScopeExit class and document
it.
---
 include/libcamera/base/utils.h | 38 ++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

--
Regards,

Laurent Pinchart

Comments

Barnabás Pőcze July 31, 2025, 7:36 a.m. UTC | #1
Hi

2025. 07. 30. 12:27 keltezéssel, Laurent Pinchart írta:
> The scope_exit class is an implementation of the identically named C++
> library fundamentals TS v3 class, as documented in [1]. It is a simpler
> version of the libcamera-specific ScopeExitActions class and doesn't
> require dynamic heap memory allocation, making it more suitable for hot
> paths.
> 
> The class is not documented as it implements a C++ standard (even if
> experimental) API.
> 
> [1] https://en.cppreference.com/w/cpp/experimental/scope_exit/scope_exit.html
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
> Changes since v2:
> 
> - Drop lvalue reference constraint in constructor
> - Delete move constructor
> 
> I have named the class scope_exit instead of ScopeExit to match the C++
> library fundamentals TS v3 class, and have not documented it as it's
> meant as an implementation of the standard. It is however not clear if
> and when scope_exit would become part of a ratified C++ standard, so I'm
> open to instead create a libcamera-specific ScopeExit class and document
> it.
> ---
>   include/libcamera/base/utils.h | 38 ++++++++++++++++++++++++++++++++++
>   1 file changed, 38 insertions(+)
> 
> diff --git a/include/libcamera/base/utils.h b/include/libcamera/base/utils.h
> index 8d5c35782ee3..808e0255b004 100644
> --- a/include/libcamera/base/utils.h
> +++ b/include/libcamera/base/utils.h
> @@ -428,6 +428,44 @@ private:
>   	std::vector<std::function<void()>> actions_;
>   };
> 
> +#ifndef __DOXYGEN__
> +template<typename EF>
> +class scope_exit
> +{
> +public:
> +	template<typename Fn,
> +		 std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Fn>>, scope_exit> &&
> +				  std::is_constructible_v<EF, Fn>> * = nullptr>
> +	explicit scope_exit(Fn &&fn)
> +		: exitFunction_(std::forward<Fn>(fn))
> +	{
> +		static_assert(std::is_nothrow_constructible_v<EF, Fn>);
> +	}
> +
> +	scope_exit(scope_exit &&other) = delete;
> +	scope_exit(const scope_exit &) = delete;

I think I would probably explicitly delete the other 2 as well, but based on
the implicit copy/move ctor/assignment rules, they should be deleted "already".

Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>

> +
> +	~scope_exit()
> +	{
> +		if (active_)
> +			exitFunction_();
> +	}
> +
> +	void release()
> +	{
> +		active_ = false;
> +	}
> +
> +private:
> +	EF exitFunction_;
> +	bool active_ = true;
> +};
> +
> +template<typename EF>
> +scope_exit(EF) -> scope_exit<EF>;
> +
> +#endif /* __DOXYGEN__ */
> +
>   } /* namespace utils */
> 
>   #ifndef __DOXYGEN__
> --
> Regards,
> 
> Laurent Pinchart
>

Patch
diff mbox series

diff --git a/include/libcamera/base/utils.h b/include/libcamera/base/utils.h
index 8d5c35782ee3..808e0255b004 100644
--- a/include/libcamera/base/utils.h
+++ b/include/libcamera/base/utils.h
@@ -428,6 +428,44 @@  private:
 	std::vector<std::function<void()>> actions_;
 };

+#ifndef __DOXYGEN__
+template<typename EF>
+class scope_exit
+{
+public:
+	template<typename Fn,
+		 std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Fn>>, scope_exit> &&
+				  std::is_constructible_v<EF, Fn>> * = nullptr>
+	explicit scope_exit(Fn &&fn)
+		: exitFunction_(std::forward<Fn>(fn))
+	{
+		static_assert(std::is_nothrow_constructible_v<EF, Fn>);
+	}
+
+	scope_exit(scope_exit &&other) = delete;
+	scope_exit(const scope_exit &) = delete;
+
+	~scope_exit()
+	{
+		if (active_)
+			exitFunction_();
+	}
+
+	void release()
+	{
+		active_ = false;
+	}
+
+private:
+	EF exitFunction_;
+	bool active_ = true;
+};
+
+template<typename EF>
+scope_exit(EF) -> scope_exit<EF>;
+
+#endif /* __DOXYGEN__ */
+
 } /* namespace utils */

 #ifndef __DOXYGEN__