...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
boost::scope::unique_resource — RAII wrapper for automatically reclaiming arbitrary resources.
// In header: <boost/scope/unique_resource.hpp> template<typename Resource, typename Deleter, typename Traits = void> class unique_resource { public: // types typedef Resource resource_type; // Resource type. typedef Deleter deleter_type; // Deleter type. typedef Traits traits_type; // Resource traits. // construct/copy/destruct unique_resource() noexcept(...); template<typename D> unique_resource(default_resource_t, D &&) noexcept(...); template<typename R> explicit unique_resource(R &&) noexcept(...); template<typename R, typename D> unique_resource(R &&, D &&) noexcept(...); unique_resource(unique_resource const &) = delete; unique_resource(unique_resource &&) noexcept(...); unique_resource & operator=(unique_resource const &) = delete; unique_resource & operator=(unique_resource &&) noexcept(...); ~unique_resource() noexcept(...); // public member functions explicit operator bool() const noexcept; bool allocated() const noexcept; resource_type const & get() const noexcept; deleter_type const & get_deleter() const noexcept; void release() noexcept; void reset() noexcept(...); template<typename R> void reset(R &&) noexcept(...); resource_type const & operator->() const noexcept; auto operator*() const noexcept(...); void swap(unique_resource &) noexcept(...); // friend functions void swap(unique_resource &, unique_resource &) noexcept(...); };
A unique_resource
object exclusively owns wrapped resource and invokes the deleter function object on it on destruction. The wrapped resource can have any type that is:
Move-constructible, where the move constructor is marked as noexcept
, or
Copy-constructible, or
An lvalue reference to an object type.
The deleter must be a function object type that is callable on an lvalue of the resource type. The deleter must be copy-constructible.
An optional resource traits template parameter may be specified. Resource traits can be used to optimize unique_resource
implementation when the following conditions are met:
There is at least one value of the resource type that is considered unallocated (that is, no allocated resource shall be equal to one of the unallocated resource values). The unallocated resource values need not be deallocated using the deleter.
One of the unallocated resource values can be considered the default. Constructing the default resource value and assigning it to a resource object (whether allocated or not) shall not throw exceptions.
Resource objects can be tested for being unallocated. Such a test shall not throw exceptions.
If specified, the resource traits must be a class type that has the following public static members:
R make_default() noexcept
- must return the default resource value such that std::is_constructible< Resource, R >::value && std::is_nothrow_assignable< Resource&, R >::value
is true
.
bool is_allocated(Resource const& res) noexcept
- must return true
if res
is not one of the unallocated resource values and false
otherwise.
Note that is_allocated(make_default())
must always return false
.
When resource traits satisfying the above requirements are specified, unique_resource
will be able to avoid storing additional indication of whether the owned resource object needs to be deallocated with the deleter on destruction. It will use the default resource value to initialize the owned resource object when unique_resource
is not in the allocated state. Additionally, it will be possible to construct unique_resource
with unallocated resource values, which will create unique_resource
objects in unallocated state (the deleter will not be called on unallocated resource values).
typename Resource
Resource type.
typename Deleter
Resource deleter function object type.
typename Traits = void
Optional resource traits type.
unique_resource
public
construct/copy/destructunique_resource() noexcept(...);Constructs an unallocated unique resource guard.
Requires: Default Resource
value can be constructed. Deleter
is default-constructible and is not a pointer to function.
Effects: Initializes the Resource
object with the default resource value. Default-constructs the Deleter
object.
Throws: Nothing, unless construction of Resource
or Deleter
throws.
Postconditions: |
|
template<typename D> unique_resource(default_resource_t res, D && del) noexcept(...);Constructs an unallocated unique resource guard with the given deleter.
Requires: Default Resource
value can be constructed and Deleter
is constructible from del.
Effects: Initializes the Resource
value with the default resource value. If Deleter
is nothrow constructible from D&&
then constructs Deleter
from std::forward< D >(del)
, otherwise constructs from del
.
Throws: Nothing, unless construction of Resource
or Deleter
throws.
Parameters: |
|
||||
Postconditions: |
|
template<typename R> explicit unique_resource(R && res) noexcept(...);Constructs a unique resource guard with the given resource and a default-constructed deleter.
Requires: Resource
is constructible from res. Deleter
is default-constructible and is not a pointer to function.
Effects: Constructs the unique resource object as if by calling
.unique_resource
(std::forward< R >(res), Deleter())
Throws: Nothing, unless construction of Resource
or Deleter
throws.
Parameters: |
|
template<typename R, typename D> unique_resource(R && res, D && del) noexcept(...);Constructs a unique resource guard with the given resource and deleter.
Requires: Resource
is constructible from res and Deleter
is constructible from del.
Effects: If Resource
is nothrow constructible from R&&
then constructs Resource
from std::forward< R >(res)
, otherwise constructs from res
. If Deleter
is nothrow constructible from D&&
then constructs Deleter
from std::forward< D >(del)
, otherwise constructs from del
.
If construction of Resource
or Deleter
throws and res is not an unallocated resource value, invokes del on res (if Resource
construction failed) or the constructed Resource
object (if Deleter
construction failed).
Throws: Nothing, unless construction of Resource
or Deleter
throws.
Parameters: |
|
||||
Postconditions: |
If res is an unallocated resource value then |
unique_resource(unique_resource const &) = delete;
unique_resource(unique_resource && that) noexcept(...);Move-constructs a unique resource guard.
Requires: Resource
and Deleter
are move-constructible.
Effects: If Resource
is nothrow move-constructible then move-constructs Resource
, otherwise copy-constructs. If Deleter
is nothrow move-constructible then move-constructs Deleter
, otherwise copy-constructs. Deactivates the moved-from unique resource object.
If an exception is thrown during construction, that is left in its original state.
Note | |
---|---|
This logic ensures that in case of exception the resource is not leaked and remains owned by the move source. |
Throws: Nothing, unless construction of Resource
or Deleter
throws.
Parameters: |
|
||
Postconditions: |
Let |
unique_resource & operator=(unique_resource const &) = delete;
unique_resource & operator=(unique_resource && that) noexcept(...);Move-assigns a unique resource guard.
Requires: Resource
and Deleter
are move-assignable.
Effects: Calls this->reset()
. Then, if Deleter
is nothrow move-assignable, move-assigns the Deleter
object first and the Resource
object next. Otherwise, move-assigns the objects in reverse order. Lastly, deactivates the moved-from unique resource object.
If an exception is thrown, that is left in its original state.
Note | |
---|---|
The different orders of assignment ensure that in case of exception the resource is not leaked and remains owned by the move source. |
Throws: Nothing, unless assignment of Resource
or Deleter
throws.
Parameters: |
|
||
Postconditions: |
Let |
~unique_resource() noexcept(...);If the resource is allocated, calls the deleter function on it. Destroys the resource and the deleter.
Throws: Nothing, unless invoking the deleter throws.
unique_resource
public member functionsexplicit operator bool() const noexcept;Returns
true
if the resource is allocated and to be reclaimed by the deleter, otherwise false
. Note | |
---|---|
This method does not test the value of the resource. |
Throws: Nothing.
bool allocated() const noexcept;Returns
true
if the resource is allocated and to be reclaimed by the deleter, otherwise false
. Throws: Nothing.
resource_type const & get() const noexcept;Returns a reference to the resource object.
Throws: Nothing.
deleter_type const & get_deleter() const noexcept;Returns a reference to the deleter object.
Throws: Nothing.
void release() noexcept;Marks the resource as unallocated. Does not call the deleter if the resource was previously allocated.
Throws: Nothing.
Postconditions: |
|
void reset() noexcept(...);If the resource is allocated, calls the deleter function on it and marks the resource as unallocated.
Throws: Nothing, unless invoking the deleter throws.
Postconditions: |
|
template<typename R> void reset(R && res) noexcept(...);Assigns a new resource object to the unique resource wrapper.
Effects: Calls this->reset()
. Then, if Resource
is nothrow assignable from R&&
, assigns std::forward< R >(res)
to the stored resource object, otherwise assigns res
.
If res is not an unallocated resource value and an exception is thrown during the operation, invokes the stored deleter on res before returning with the exception.
Throws: Nothing, unless invoking the deleter throws.
Parameters: |
|
||
Postconditions: |
|
resource_type const & operator->() const noexcept;Invokes indirection on the resource object.
Requires: Resource
is dereferenceable.
Effects: Returns a reference to the resource object as if by calling get()
.
Note | |
---|---|
If |
Throws: Nothing. Note that any implicit subsequent calls to other operator->
functions that are caused by this call may have different throw conditions.
auto operator*() const noexcept(...);Dereferences the resource object.
Requires: Resource
is dereferenceable.
Effects: Returns the result of dereferencing the resource object as if by calling *get()
.
Throws: Nothing, unless dereferencing the resource object throws.
void swap(unique_resource & that) noexcept(...);Swaps two unique resource wrappers.
Requires: Resource
and Deleter
are swappable. At least one of Resource
and Deleter
is nothrow swappable.
Effects: Swaps the resource objects and deleter objects stored in *this
and that as if by calling unqualified swap
in a context where std::swap
is found by overload resolution.
If an exception is thrown, and the failed swap operation supports strong exception guarantee, both *this
and that are left in their original states.
Throws: Nothing, unless swapping the resource objects or deleters throw.
Parameters: |
|
unique_resource
friend functionsvoid swap(unique_resource & left, unique_resource & right) noexcept(...);Swaps two unique resource wrappers.
Effects: As if left.swap(right)
.