PStack
2.0
Stack trace printer for MSVC and GCC binaries
|
Uniquely manage a single "handle". More...
#include <unique_handle.hpp>
Type Declarations | |
using | base = unique_handle_impl< T, D, kInvalidHandle > |
A convenient name for the base-class type. | |
using | safe_address_container = psystem::internal::managed_handle_proxy< handle_type, unique_handle< handle_type, deleter_type, kInvalidHandle > > |
A safe container for altering the handle by the address-of operator. | |
using | deleter_type = D |
The data-type of the clean-up facility. | |
using | handle_type = T |
The data-type of the handle being managed. | |
Construction / Destruction | |
unique_handle (handle_type hndl=kInvalidHandle) noexcept | |
Construct an instance to manage a handle. More... | |
template<typename D2 > | |
unique_handle (handle_type hndl, D2 &&deleter) noexcept | |
Construct an instance to manage a handle with a custom "deleter.". More... | |
unique_handle (unique_handle &&other) noexcept | |
Transfer ownership of a handle from another unique_handle. More... | |
~unique_handle () noexcept | |
Destroy this container, freeing the handle managed within. More... | |
Operator Overloads | |
unique_handle & | operator= (unique_handle &&o) noexcept |
Transfer ownership of a handle into this instance. More... | |
safe_address_container | operator& () noexcept |
Allow safe alteration of the handle by routines that return data by C-style output parameters. More... | |
Public Interface | |
deleter_type & | get_deleter () noexcept |
Access the deleter instance within this class. More... | |
deleter_type const & | get_deleter () const noexcept |
Access the const deleter instance within this class. More... | |
void | reset (handle_type hndl=kInvalidHandle) noexcept |
Assign a new handle to be managed by this instance. More... | |
void | swap (unique_handle &o) noexcept |
Swap ownership of two unique_handle instances. More... | |
Member Data | |
deleter_type | m_deleter |
The instance that will be used to clean up the handle's resources. | |
Additional Inherited Members | |
Public Types inherited from psystem::unique_handle_impl< T, D, kInvalidHandle > | |
using | deleter_type = D |
The data-type of the clean-up facility. | |
using | handle_type = T |
The data-type of the handle being managed. | |
Public Member Functions inherited from psystem::unique_handle_impl< T, D, kInvalidHandle > | |
unique_handle_impl (unique_handle_impl const &)=delete | |
Disable copying because it will likely be deleted twice. | |
unique_handle_impl & | operator= (unique_handle_impl &)=delete |
Disable copy-assignment to prevent double-frees. | |
handle_type | get () const noexcept |
Access the handle contained in this object. More... | |
handle_type | release () noexcept |
Release the handle from being managed by this class. More... | |
operator bool () const noexcept | |
Determines the validity of this instance. More... | |
Static Public Member Functions inherited from psystem::stack_allocated | |
static void | operator delete (void *)=delete |
Individual object deletion. | |
static void | operator delete[] (void *)=delete |
Array of type object deletion. | |
static void * | operator new (size_t)=delete |
Individual object allocation. | |
static void * | operator new[] (size_t)=delete |
Array of type allocation. | |
Uniquely manage a single "handle".
A handle in this context is any opaque item of data that is used (non-opaquely) by an API. Typically handles are received from some API invocation, and will need to be "closed" by a separate API to free any resources associated with that handle.
When we say that the handle is "uniquely" managed by this instance, we simply mean that no other references to that handle exist (or if they exist, they are guaranteed not to outlive this container), and that it is this container's sole responsibility to free all resources for that handle when the container's lifetime ends.
While it is possible to use std::unique_ptr
with handles, it becomes somewhat ugly (the handle type must be void*
, the handle must use nullptr
as its "invalid value (Windows' INVALID_HANDLE_VALUE
actually maps to 0xFFFFFFFF
), and so on). Frankly, it's more fun to see what we can do by creating our own implementation, so here we are.
std::unique_ptr
, but it is not identical. Be aware of interface and behavioral differences by carefully reading documentation for individual methods.T | The type of the handle that is managed by this class. |
D | The type of the "deleter" that must clean up the resources consumed by the handle that is managed by this class. The clean-up routine must match the function signature, "void(handle_type)" , and it must not throw. |
kInvalidHandle | For a handle to be used by this class, it must have the concept of an "invalid" handle value. This concept is analogous to nullptr for pointer types. The value passed to this template paraameter represents the invalid value marker for the handle type managed by this class. |
|
inlineexplicitnoexcept |
Construct an instance to manage a handle.
Construction always succeeds, as exceptions are not allowed. If no parameter is specified, this constructs an instance that does not (initially) own an handle.
deleter_type
must be default-constructable, and its constructor must not throw.[in] | hndl | The handle (or invalid handle value) that this instance will manage. |
|
inlinenoexcept |
Construct an instance to manage a handle with a custom "deleter.".
Construction always succeeds, as exceptions are not allowed.
deleter_type
must be copy-constructable or move-constructable, depending on how this constructor is invoked (see deleter
parameter documentation), and that constructor may not throw.[in] | hndl | The handle (or invalid handle value) that this instance will manage. |
[in] | deleter | The instance of an object used to clean up the handle that it managed by this instance. This is a "universal reference" (as Scott Meyers termed it), which means:
|
|
inlinenoexcept |
Transfer ownership of a handle from another unique_handle.
std::unique_ptr
in that it does not allow the transfer of related handle types. Often, handles are convertable types (void*
to void*
or long
to long
) that are merely obscured via a typedef. Transferring ownership of different handle types would also require changing the type of the deleter_type
and the value of invalid_handle_value
.deleter_type
must be move-constructable, and it must not throw.[in,out] | other | The unique_handle from which we're moving data. |
|
inlinenoexcept |
Destroy this container, freeing the handle managed within.
If the handle is invalid_handle_value
, this method does not call the deleter. The deleter contained within this instance will also be destroyed.
deleter_type::operator()
may throw.
|
inlinenoexcept |
Access the deleter instance within this class.
|
inlinenoexcept |
Access the const
deleter instance within this class.
|
inlinenoexcept |
Allow safe alteration of the handle by routines that return data by C-style output parameters.
|
inlinenoexcept |
Transfer ownership of a handle into this instance.
std::unique_ptr
in that it does not allow the transfer of related handle types. Often, handles are convertable types (void*
to void*
or long
to long
) that are merely obscured via a typedef. Transferring ownership of different handle types would also require changing the type of the deleter_type
and the value of invalid_handle_value
.[in,out] | o | The unique_handle from which we're moving data. |
this
, after the assignment.
|
inlinenoexcept |
Assign a new handle to be managed by this instance.
If there was a valid handle managed previously by this unique_handle instance, its resources will be cleaned up prior to assigning the new handle. If the new handle equals (==
) the old handle, this method does nothing.
If no parameters are specified, this resets the unique_handle to the "invalid" state.
[in] | hndl | The new handle to manage. It need not be "valid." |
|
inlinenoexcept |
Swap ownership of two unique_handle instances.
deleter_type
must be move-assignable, and that assignment must not throw.[in,out] | o | The unique_handle instance that will swap handle data and deleters with this instance. |