My Project
|
Class to guarantee deallocation of arbitrary resources. More...
#include <unity/util/ResourcePtr.h>
Public Types | |
typedef R | element_type |
typedef D | deleter_type |
Public Member Functions | |
ResourcePtr (ResourcePtr const &)=delete | |
ResourcePtr & | operator= (ResourcePtr const &)=delete |
ResourcePtr (D d) | |
ResourcePtr (R r, D d) | |
ResourcePtr (ResourcePtr &&r) | |
ResourcePtr & | operator= (ResourcePtr &&r) |
~ResourcePtr () noexcept | |
void | swap (ResourcePtr &other) |
void | reset (R r) |
R | release () |
void | dealloc () |
R | get () const |
bool | has_resource () const noexcept |
operator bool () const noexcept | |
D & | get_deleter () noexcept |
D const & | get_deleter () const noexcept |
bool | operator== (ResourcePtr const &rhs) const |
Compares two instances for equality. More... | |
bool | operator!= (ResourcePtr const &rhs) const |
Compares two instances for inequality. More... | |
bool | operator< (ResourcePtr const &rhs) const |
Returns true if this is less than rhs . More... | |
bool | operator<= (ResourcePtr const &rhs) const |
Returns true if this is less than or equal to rhs . More... | |
bool | operator> (ResourcePtr const &rhs) const |
Returns true if this is greater than rhs . More... | |
bool | operator>= (ResourcePtr const &rhs) const |
Returns true if this is greater than or equal to rhs . More... | |
Class to guarantee deallocation of arbitrary resources.
ResourcePtr is a generalized resource pointer that guarantees deallocation. It is intended for arbitrary pairs of allocate/deallocate functions, such as XCreateDisplay
/XDestroyDisplay
.
The resource managed by this class must be default-constructible, copy-constructible, and assignable.
ResourcePtr essentially does what std::unique_ptr
does, but it works with opaque types and resource allocation functions that do not return a pointer type, such as open()
.
ResourcePtr is thread-safe.
XFree()
must not be called with a nullptr
argument.std::logic_error
.Here is an example that shows how to use this for a glXCreateContext
/GLXDestroyContext
pair. The returned GLXContext
is a pointer to an opaque type; std::unique_ptr
cannot be used for this, even with a custom deleter, because the signatures of the allocator and deallocator do not match unique_ptr
's expectations.
display_ is declared as
in this case.
The deleter for the resource can return any type (including int, such as returned by XDestroyWindow()
), and it must accept a single argument of the resource type (GLXContext
in this example).
glXDestroyContext()
expects the display pointer as the first argument so, for this example, std::bind
converts the binary glXDestroyContext()
function into a unary function suitable as the deleter.
Rather than mucking around with std::bind
, it is often easier to use a lambda. For example:
This calls a member function dealloc_GLXContext()
that, in turn calls glXDestroyContext()
and supplies the display parameter.
std::unique_ptr
instead, which is better suited to the task. unity::util::ResourcePtr< R, D >::deleter_type |
A function object or lvalue reference to a function or function object. The ResourcePtr calls this to deallocate the resource.
unity::util::ResourcePtr< R, D >::element_type |
The type of resource managed by this ResourcePtr.
|
delete |
Deleted
|
explicit |
Constructs a ResourcePtr with the specified deleter. No resource is held, so a call to has_resource() after constructing a ResourcePtr this way returns false
.
unity::util::ResourcePtr< R, D >::ResourcePtr | ( | R | r, |
D | d | ||
) |
Constructs a ResourcePtr with the specified resource and deleter. has_resource() returns true
after calling this constructor.
-1
to close()
if the call to open()
fails: When the ResourcePtr goes out of scope, this results in a call to close(-1)
. In this case, the call with an invalid file descriptor is harmless (but causes noise from diagnostic tools, such as valgrind
). However, depending on the specific deleter, passing an invalid value to the deleter may have more serious consequences.
To avoid the problem, you can delay initialization of the ResourcePtr until you know that the resource was successfully allocated, for example:
Alternatively, you can use a deleter function that tests the resource value for validity and avoids calling the deleter with an invalid value:
Note that, with the second approach, a call to get() will succeed and return -1 rather than throwing an exception, so the first approach is the recommended one.
unity::util::ResourcePtr< R, D >::ResourcePtr | ( | ResourcePtr< R, D > && | r | ) |
Constructs a ResourcePtr by transferring ownership from r
to this
.
If the resource's move or copy constructor throws, the exception is propagated to the caller. The strong exception guarantee is preserved if it is provided by the resource.
|
noexcept |
Destroys the ResourcePtr. If a resource is held, it calls the deleter for the current resource (if any).
void unity::util::ResourcePtr< R, D >::dealloc | ( | ) |
Calls the deleter for the current resource.
If the deleter throws, the resource is considered in the "not allocated" state, that is, no attempt is made to call the deleter again for this resource.
|
inline |
Returns the current resource. If no resource is currently held, get() throws std::logic_error
.
If the resource's copy constructor throws an exception, that exception is propagated to the caller.
std::logic_error | if has_resource() is false. |
|
inlinenoexcept |
|
inlinenoexcept |
|
inlinenoexcept |
true
if this
currently manages a resource; false
, otherwise.
|
inlineexplicitnoexcept |
Synonym for has_resource().
|
inline |
Compares two instances for inequality.
If the underlying operator==
throws an exception, that exception is propagated to the caller.
operator==
. bool unity::util::ResourcePtr< R, D >::operator< | ( | ResourcePtr< R, D > const & | rhs | ) | const |
Returns true
if this
is less than rhs
.
An instance that does not hold a resource is less than any instance that holds a resource.
If the underlying operator<
throws an exception, that exception is propagated to the caller.
operator<
. bool unity::util::ResourcePtr< R, D >::operator<= | ( | ResourcePtr< R, D > const & | rhs | ) | const |
Returns true
if this
is less than or equal to rhs
.
An instance that does not hold a resource is less than any instance that holds a resource. Two instances that do not hold a resource are equal.
If the underlying operator<
or operator==
throws an exception, that exception is propagated to the caller.
operator<
and operator==
.
|
delete |
Deleted
ResourcePtr< R, D > & unity::util::ResourcePtr< R, D >::operator= | ( | ResourcePtr< R, D > && | r | ) |
Assigns the resource held by r
, transferring ownership. After the transfer, r.has_resource()
returns false
, and this.has_resource()
returns the value of r.has_resource()
prior to the assignment.
bool unity::util::ResourcePtr< R, D >::operator== | ( | ResourcePtr< R, D > const & | rhs | ) | const |
Compares two instances for equality.
Two instances that do not hold a resource are equal. An instance that does not hold a resource is not equal to any instance that holds a resource.
If the underlying operator==
throws an exception, that exception is propagated to the caller.
operator==
.
|
inline |
Returns true
if this
is greater than rhs
.
An instance that holds a resource is greater than any instance that does not hold a resource.
If the underlying operator<
or operator==
throws an exception, that exception is propagated to the caller.
operator<
and operator==
.
|
inline |
Returns true
if this
is greater than or equal to rhs
.
An instance that holds a resource is greater than any instance that does not hold a resource. Two instances that do not hold a resource are equal.
If the underlying operator<
throws an exception, that exception is propagated to the caller.
operator<
.
|
inline |
Releases ownership of the current resource without calling the deleter.
std::logic_error | if has_resource() is false. |
void unity::util::ResourcePtr< R, D >::reset | ( | R | r | ) |
Assigns a new resource to this
, first deallocating the current resource (if any).
If the deleter for the current resource throws an exception, the exception is propagated to the caller. In this case, the transfer of r
to this
is still carried out so, after the call to reset(), this
manages r
, whether the deleter throws or not. (If the deleter does throw, no attempt is made to call the deleter again for the same resource.)
void unity::util::ResourcePtr< R, D >::swap | ( | ResourcePtr< R, D > & | other | ) |
Swaps the resource and deleter of this
with the resource and deleter of other
using argument dependent lookup (ADL).
If the underlying swap throws an exception, that exception is propagated to the caller, and the resource held by the ResourcePtr is unchanged.