Boost C++ Libraries

Next

Chapter 1. Boost.Scope

Andrey Semashev

Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt).

Table of Contents

Introduction
Installation and compatibility
Scope guards
Conditional scope guards: scope_exit, scope_success and scope_fail
Scope guard condition functions
Unconditional scope guard: scope_final
Setting up scope exit actions at run time
Comparison with Boost.ScopeExit library
Unique resource wrapper
Resource traits
Reference
Header <boost/scope/error_code_checker.hpp>
Header <boost/scope/exception_checker.hpp>
Header <boost/scope/fd_deleter.hpp>
Header <boost/scope/fd_resource_traits.hpp>
Header <boost/scope/scope_exit.hpp>
Header <boost/scope/scope_fail.hpp>
Header <boost/scope/scope_final.hpp>
Header <boost/scope/scope_success.hpp>
Header <boost/scope/unique_fd.hpp>
Header <boost/scope/unique_resource.hpp>
Header <boost/scope/unique_resource_fwd.hpp>
Changelog

The Boost.Scope library is a collection of utilities helping with code execution upon leaving a scope and automatic resource management. The library contains components that were defined in the C++ Extensions for Library Fundamentals, Version 3 technical specification, in the <experimental/scope> standard library header. The library also contains extensions to the Fundamentals TS that improve usability or efficiency of the components.

The components provided by the library can be divided into two categories:

  • A set of scope guards that allow executing arbitrary code when the scope guard is destroyed,
  • A generic resource wrapper that automatically frees the owned resource upon destruction.

There is some overlap in terms of functionality with Boost.ScopeExit, Boost.SmartPtr as well as C++ standard library smart-pointers. Compared to Boost.ScopeExit, scope guards provided by Boost.Scope offer simpler syntax (especially with C++17 capable compilers) and new features for specific use cases. You can see the syntax differences in the table below:

Table 1.1. Boost.ScopeExit and Boost.Scope syntax overview

Boost.ScopeExit (C++03)

Boost.Scope (C++11)

Boost.Scope (C++17)

class adder
{
    int x, y;

public:
    int compute()
    {
        // Reset variables on return
        BOOST_SCOPE_EXIT(this_)
        {
            this_->x = 0;
            this_->y = 0;
        }
        BOOST_SCOPE_EXIT_END;

        return x + y;
    }
};
class adder
{
    int x, y;

public:
    int compute()
    {
        // Reset variables on return
        auto cleanup = boost::scope::make_scope_exit([this]
        {
            x = 0;
            y = 0;
        });

        return x + y;
    }
};
class adder
{
    int x, y;

public:
    int compute()
    {
        // Reset variables on return
        BOOST_SCOPE_FINAL [this]
        {
            x = 0;
            y = 0;
        };

        return x + y;
    }
};
template< typename Object >
class collection
{
    std::set< Object > objects;

public:
    template< typename T >
    void add_object(T const& arg)
    {
        typename std::set< Object >::iterator it =
            objects.insert(Object());

        // Remove the object on failure
        unsigned int uncaught_count =
            boost::core::uncaught_exceptions();
        BOOST_SCOPE_EXIT_TPL(this_, it, uncaught_count)
        {
            if (uncaught_count != boost::core::uncaught_exceptions())
                this_->objects.erase(it);
        }
        BOOST_SCOPE_EXIT_END;

        // Throws on error
        it->start(arg);
    }
};
template< typename Object >
class collection
{
    std::set< Object > objects;

public:
    template< typename T >
    void add_object(T&& arg)
    {
        auto it = objects.emplace();

        // Remove the object on failure
        auto cleanup = boost::scope::make_scope_fail([this, it]
        {
            objects.erase(it);
        });

        // Throws on error
        it->start(std::forward< T >(arg));
    }
};
template< typename Object >
class collection
{
    std::set< Object > objects;

public:
    template< typename T >
    void add_object(T&& arg)
    {
        auto it = objects.emplace();

        // Remove the object on failure
        boost::scope::scope_fail cleanup{[this, it]
        {
            objects.erase(it);
        }};

        // Throws on error
        it->start(std::forward< T >(arg));
    }
};

Detailed comparison between scope guards provided by Boost.Scope and Boost.ScopeExit is given in a separate section.

Unique resource wrapper provided by Boost.Scope is a generalization of smart pointers like std::unique_ptr and boost::scoped_ptr from Boost.SmartPtr. While smart pointers are suitable for managing resources represented by pointers (e.g. objects in dynamically allocated memory), unique resource wrapper can be used with many more kinds of resource types, such as integers (e.g. POSIX file descriptors) and user-defined types.

The library defines its components in namespace boost::scope. For brevity, the namespace qualification may be omitted in this documentation; readers should assume that unqualified names like scope_exit or unique_resource are defined in boost::scope.


Next