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

Message ID 20250804233152.11538-2-laurent.pinchart@ideasonboard.com
State Accepted
Commit 6ef2d79a730b79e7cb075678f81b327637a3d29f
Headers show
Series
  • libcamera: Introduce and use scope_exit
Related show

Commit Message

Laurent Pinchart Aug. 4, 2025, 11:31 p.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>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
---
Changes since v3:

- Use LIBCAMERA_DISABLE_COPY_AND_MOVE()

Changes since v2:

- Drop lvalue reference constraint in constructor
- Delete move constructor
---
 include/libcamera/base/utils.h | 38 ++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

Comments

Stefan Klug Aug. 6, 2025, 6:34 a.m. UTC | #1
Hi Laurent,

Thank you for the patch.


Quoting Laurent Pinchart (2025-08-05 01:31:50)
> 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.

Hah I was just going to ask for docs - neat trick :-)

> 
> [1] https://en.cppreference.com/w/cpp/experimental/scope_exit/scope_exit.html
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>

This is useful.
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>

Cheers,
Stefan

> ---
> Changes since v3:
> 
> - Use LIBCAMERA_DISABLE_COPY_AND_MOVE()
> 
> Changes since v2:
> 
> - Drop lvalue reference constraint in constructor
> - Delete move constructor
> ---
>  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..f21c6dc016ec 100644
> --- a/include/libcamera/base/utils.h
> +++ b/include/libcamera/base/utils.h
> @@ -21,6 +21,7 @@
>  #include <utility>
>  #include <vector>
>  
> +#include <libcamera/base/class.h>
>  #include <libcamera/base/private.h>
>  
>  #ifndef __DOXYGEN__
> @@ -428,6 +429,43 @@ 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()
> +       {
> +               if (active_)
> +                       exitFunction_();
> +       }
> +
> +       void release()
> +       {
> +               active_ = false;
> +       }
> +
> +private:
> +       LIBCAMERA_DISABLE_COPY_AND_MOVE(scope_exit)
> +
> +       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..f21c6dc016ec 100644
--- a/include/libcamera/base/utils.h
+++ b/include/libcamera/base/utils.h
@@ -21,6 +21,7 @@ 
 #include <utility>
 #include <vector>
 
+#include <libcamera/base/class.h>
 #include <libcamera/base/private.h>
 
 #ifndef __DOXYGEN__
@@ -428,6 +429,43 @@  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()
+	{
+		if (active_)
+			exitFunction_();
+	}
+
+	void release()
+	{
+		active_ = false;
+	}
+
+private:
+	LIBCAMERA_DISABLE_COPY_AND_MOVE(scope_exit)
+
+	EF exitFunction_;
+	bool active_ = true;
+};
+
+template<typename EF>
+scope_exit(EF) -> scope_exit<EF>;
+
+#endif /* __DOXYGEN__ */
+
 } /* namespace utils */
 
 #ifndef __DOXYGEN__