Re: [boost] [scope] Proposing Boost.Scope
I've written my own replacement and am very much in favor of the scope-utilities. Have you thought about if this can be made to work with system::error_code or even system::result? E.g. make_scope_fail https://lastique.github.io/scope/libs/scope/doc/html/boost/scope/make_scope_...(ec, handle) // checks ec in order to decide if it failed The unique_resource seems very specific for file descriptors to me, because almost everything else can be put into a unique_ptr (e.g. FILE or HANDLE). Why wouldn't I just use a scope_final for those? . On Wed, Mar 22, 2023 at 9:41 AM Andrey Semashev via Boost < boost@lists.boost.org> wrote:
Hi,
I'm proposing a Boost.Scope library for review and potential inclusion into Boost.
Boost.Scope is a small library implementing utilities defined in
from C++ Extensions for Library Fundamentals v3 with a few extensions. Namely, the library contains: * A number of scope guards for various use cases. * A unique resource wrapper that automatically frees the resource on destruction. * Utilities for wrapping POSIX-like file descriptors in the unique resource wrapper.
Compared to
, some notable extensions are: * A new scope_final scope guard, which is a more lightweight alternative to scope_exit. It is accompanied with the BOOST_SCOPE_FINAL macro that allows to simplify scope guard declaration syntax. * Scope guards can be activated/deactivated multiple times. * Scope guards can be created inactive initially. * Scope guard factory functions, for compatibility with C++11. * Support for optional resource traits in unique_resource wrapper, which improves usage with resources having unallocated values. * unique_resource supports swapping. * unique_resource supports dereferencing for any resource types that support dereferencing, not only pointers. * More flexible constructors for unique_resource.
The library requires C++11 at the minimum and will significantly benefit from C++17.
Source:
https://github.com/Lastique/scope
Docs:
https://lastique.github.io/scope/libs/scope/doc/html/index.html
Current state: Feature complete, tested in the CI.
I'm asking for a review manager and endorsements.
I'm also looking forward for any pre-review comments. In particular, I'm interested in community opinion on the following:
* Is there interest in this library at all? * Should it be merged with Boost.ScopeExit, which is currently unmaintained? More on this below. * Should some/all of the library components be lifted to namespace boost? Such is the practice with most vocabulary types in Boost, e.g. boost::atomic, boost::shared_ptr, boost::any, boost::string_view, etc. Currently, the library defines its names in namespace boost::scope. * Comments on the resource traits feature are especially welcome.
Re. Boost.ScopeExit. There is significant functionality overlap with it in the scope guards department. The docs contain comparison with it. I believe there is room for both libraries because Boost.ScopeExit supports C++03 and Boost.Scope provides better syntax and more features, and both can be useful in their own regards, although I expect Boost.Scope to be more appealing in newer code bases. However, if the community decides there's too much overlap, I'm not opposed to merging the two libraries, although Boost.ScopeExit currently depends on Boost.Function, Boost.Preprocessor and Boost.TypeOf, which are unnecessary for Boost.Scope.
Thank you.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
On 3/22/23 05:02, Klemens Morgenstern wrote:
I've written my own replacement and am very much in favor of the scope-utilities.
Have you thought about if this can be made to work with system::error_code or even system::result? E.g.
make_scope_fail https://lastique.github.io/scope/libs/scope/doc/html/boost/scope/make_scope_...(ec, handle) // checks ec in order to decide if it failed
I haven't thought about this, but it sounds like an interesting potential extension. In general, it might be useful to be able to specify a failure detection function, which by default would be to check for an exception, but could be changed to check an error_code or some arbitrary result code (e.g. from errno). This could look like this: error_code ec; scope_fail guard( [&] { std::cout << "Failure" << std::endl; }, [&ec] { return !!ec; }); Similarly with make_scope_fail. There is a small complication with the active flag that can be specified as the second argument currently, but I think I could make it mandatory in this case, or do some type deduction heuristic. I'll need to think about this.
The unique_resource seems very specific for file descriptors to me, because almost everything else can be put into a unique_ptr (e.g. FILE or HANDLE).
unique_ptr is only useful for pointers, and indeed pointers are more
prevalent for as resource handles. unique_resource would fill the gap
for non-pointer resources. And BTW, although HANDLE is a pointer
internally, the type itself is not spelled as a pointer, so you can't
write `unique_ptr
From personal experience, I have seen some libraries which exposed their objects as non-pointer handles (typically structures) that needed to be freed. For example:
https://github.com/xiph/speex/blob/f39602dadbb6d0e8fa7b548c1629388290d4a0f7/...
Why wouldn't I just use a scope_final for those?
Although you can create scope guards as class members, this is not their primary intended use case. You have no access to the stored function object, and consequently, any data it binds, which means the resource itself will need to be stored externally, which is a hassle. Furthermore, this would complicate move operations of your class because you would have to ensure that the scope guard always references the correct external resource object. Just imagine if you had to replace every unique_ptr with a scope guard in your classes.
On 3/22/23 12:03, Andrey Semashev wrote:
On 3/22/23 05:02, Klemens Morgenstern wrote:
I've written my own replacement and am very much in favor of the scope-utilities.
Have you thought about if this can be made to work with system::error_code or even system::result? E.g.
make_scope_fail https://lastique.github.io/scope/libs/scope/doc/html/boost/scope/make_scope_...(ec, handle) // checks ec in order to decide if it failed
I haven't thought about this, but it sounds like an interesting potential extension. In general, it might be useful to be able to specify a failure detection function, which by default would be to check for an exception, but could be changed to check an error_code or some arbitrary result code (e.g. from errno).
This could look like this:
error_code ec; scope_fail guard( [&] { std::cout << "Failure" << std::endl; }, [&ec] { return !!ec; });
Similarly with make_scope_fail. There is a small complication with the active flag that can be specified as the second argument currently, but I think I could make it mandatory in this case, or do some type deduction heuristic. I'll need to think about this.
This is now implemented. https://lastique.github.io/scope/libs/scope/doc/html/scope/scope_guards.html... scope_success and scope_fail now support an optional condition predicate that decides whether the scope guard needs to invoke its action. By default, the scope guards still act depending on whether an exception is thrown, for compatibility with Library Fundamentals TS. Also, added a new scope_check guard that does not have a default condition and requires the user to specify one. Functionally, it is similar to scope_fail and opposite to scope_success. The library provides two scope guard condition predicates out of the box. One is the exception_checker, which is used by scope_success and scope_fail by default. The other is error_code_checker, which can be used to check an error code for an error indication. It supports any type of error code that supports `!ec` expression for testing for "not an error" value. So, the earlier code sample could be written like this: error_code ec; scope_fail guard( [&] { std::cout << "Failure" << std::endl; }, check_error_code(ec)); Here, check_error_code is a factory function for the error_code_checker predicate.
participants (2)
-
Andrey Semashev
-
Klemens Morgenstern