Template Class UniqueResource#
Defined in File UniqueResource.h
Nested Relationships#
Nested Types#
Class Documentation#
-
template<typename Resource, typename Deleter>
class UniqueResource# UniqueResource is a universal RAII wrapper for resource handles that owns and manages a resource through a handle and disposes of that resource when the UniqueResource is destroyed.
The resource is disposed of using the deleter of type Deleter when either of the following happens:
The managing UniqueResource object is destroyed,
The managing UniqueResource object is assigned from another resource via operator= or Reset(). Let type Resource be R if R is an object type, or std::reference_wrapper<std::remove_reference_t<R>> otherwise:
UniqueResource effectively holds a subobject of type Resource which is or wraps the resource handle, a deleter of type Deleter and a bool flag indicating whether the wrapper is owning the resource.
For explanatory purpose, the subobject of type Resource is called stored resource handle, and the stored (if R is an object type) or wrapped (if R is a reference type) R is called underlying resource handle.
Note
Resource handle types satisfying NullablePointer can also be managed by std::unique_ptr. Unlike std::unique_ptr, UniqueResource does not require NullablePointer.
- Template Parameters:
Resource – Resource handle type.
Deleter – Deleter type.
Public Functions
-
constexpr UniqueResource() = default#
Default constructor. Value-initializes the stored resource handle and the deleter. The constructed UniqueResource does not own the resource.
-
template<typename Resource2, typename Deleter2>
inline constexpr UniqueResource(Resource2 &&r, Deleter2 &&d) noexcept((std::is_nothrow_constructible_v<Resource1, Resource2> || std::is_nothrow_constructible_v<Resource1, Resource2&>) && (std::is_nothrow_constructible_v<Deleter, Deleter2> || std::is_nothrow_constructible_v<Deleter, Deleter2&>))# The stored resource handle is initialized with std::forward<Resource2>(r) if std::is_nothrow_constructible_v<Resource1, Resource2> is true, otherwise r. If initialization of the stored resource handle throws an exception, calls d(r). Then, the deleter is initialized with std::forward<Deleter2>(d) if std::is_nothrow_constructible_v<Deleter, Deleter2> is true, otherwise d. If initialization of deleter throws an exception, calls d(res). The constructed UniqueResource owns the resource.
- Parameters:
r – A resource handle.
d – A deleter to use to dispose the resource.
-
inline constexpr UniqueResource(UniqueResource &&rhs) noexcept#
Move constructor. The stored resource handle is initialized from the one of rhs, using std::move if std::is_nothrow_move_constructible_v<Resource1> is true. If initialization of the stored resource handle throws an exception, rhs is not modified. Then, the deleter is initialized with the one of rhs, using std::move if std::is_nothrow_move_constructible_v<Deleter> is true. If initialization of the deleter throws an exception and std::is_nothrow_move_constructible_v<Resource1> is true and rhs owns the resource, calls the deleter of rhs with res to dispose the resource, then calls rhs.Release(). After construction, the constructed UniqueResource owns its resource if and only if rhs owned the resource before the construction, and rhs is set to not own the resource.
- Parameters:
rhs – Another UniqueResource to acquire the ownership from.
-
inline constexpr UniqueResource(UniqueResource &&rhs)
Move constructor. The stored resource handle is initialized from the one of rhs, using std::move if std::is_nothrow_move_constructible_v<Resource1> is true. If initialization of the stored resource handle throws an exception, rhs is not modified. Then, the deleter is initialized with the one of rhs, using std::move if std::is_nothrow_move_constructible_v<Deleter> is true. If initialization of the deleter throws an exception and std::is_nothrow_move_constructible_v<Resource1> is true and rhs owns the resource, calls the deleter of rhs with res to dispose the resource, then calls rhs.Release(). After construction, the constructed UniqueResource owns its resource if and only if rhs owned the resource before the construction, and rhs is set to not own the resource.
- Parameters:
rhs – Another UniqueResource to acquire the ownership from.
-
inline constexpr UniqueResource(UniqueResource &&rhs)
Move constructor. The stored resource handle is initialized from the one of rhs, using std::move if std::is_nothrow_move_constructible_v<Resource1> is true. If initialization of the stored resource handle throws an exception, rhs is not modified. Then, the deleter is initialized with the one of rhs, using std::move if std::is_nothrow_move_constructible_v<Deleter> is true. If initialization of the deleter throws an exception and std::is_nothrow_move_constructible_v<Resource1> is true and rhs owns the resource, calls the deleter of rhs with res to dispose the resource, then calls rhs.Release(). After construction, the constructed UniqueResource owns its resource if and only if rhs owned the resource before the construction, and rhs is set to not own the resource.
- Parameters:
rhs – Another UniqueResource to acquire the ownership from.
-
inline constexpr ~UniqueResource()#
Disposes the resource by calling the deleter with the underlying resource handle if the UniqueResource owns it, equivalent to calling Reset(). Then destroys the stored resource handle and the deleter.
-
inline constexpr UniqueResource &operator=(UniqueResource &&rhs) noexcept(std::is_nothrow_move_assignable_v<Resource1> && std::is_nothrow_move_assignable_v<Deleter>)#
Move assignment operator. Replaces the managed resource and the deleter with rhs’s. Formally, let Resource1 be the type of stored resource handle.
First, calls Reset() to dispose the currently owned resource, if any.
Then assigns the stored resource handle and the deleter with rhs’s. std::move is applied to the stored resource handle or the deleter of rhs if std::is_nothrow_move_assignable_v<Resource1> or std::is_nothrow_move_assignable_v<Deleter> is true respectively. Assignment of the stored resource handle is executed first, unless std::is_nothrow_move_assignable_v<Deleter> is false and std::is_nothrow_move_assignable_v<Resource1> is true.
Finally, sets *this to own the resource if and only if rhs owned it before assignment, and rhs not to own the resource.
Note
If a copy of a member throws an exception, this mechanism leaves rhs intact and *this in the released state.
- Parameters:
rhs – Resource wrapper from which ownership will be transferred.
- Returns:
*this.
-
inline constexpr void Reset() noexcept#
Disposes the resource by calling the deleter with the underlying resource handle if the UniqueResource owns it. The UniqueResource does not own the resource after the call.
-
template<typename Resource2>
inline constexpr void Reset(Resource2 &&r)# Replaces the resource by calling Reset() and then assigns the stored resource handle with std::forward<Resource2>(r) if std::is_nothrow_assignable_v<Resource1, Resource2> is true, otherwise std::as_const(r), where Resource1 is the type of stored resource handle. The UniqueResource owns the resource after the call.
If copy-assignment of the store resource handle throws an exception, calls del(r), where del is the deleter object.
- Parameters:
r – Resource handle for a new resource to manage.
-
inline constexpr void Release() noexcept#
Releases the ownership of the managed resource if any. The destructor will not execute the deleter after the call, unless Reset() is called later for managing a new resource.
Note
Unlike std::unique_ptr::release(), this function is not required to modify the stored resource handle.
-
inline constexpr const Resource &Get() const noexcept#
Accesses the underlying resource handle.
- Returns:
The underlying resource handle.
-
inline constexpr std::add_lvalue_reference_t<std::remove_pointer_t<Resource>> operator*() const noexcept#
Access the object or function pointed by the underlying resource handle which is a pointer. If the resource handle is not pointing to an object or a function, the behavior is undefined.
- Returns:
The object or function pointed by the underlying resource handle.