Message ID | 20250730102733.21314-2-laurent.pinchart@ideasonboard.com |
---|---|
State | Superseded |
Headers | show |
Series |
|
Related | show |
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 >
On Thu, Jul 31, 2025 at 09:36:23AM +0200, Barnabás Pőcze wrote: > 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". I'll use LIBCAMERA_DISABLE_COPY_AND_MOVE() > 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__
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__
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