Subject: Re: [boost] [RFC] unique_val (handles, IDs, descriptors...)
From: Richard Hodges (hodges.r_at_[hidden])
Date: 2018-02-15 07:10:06
The idea is correct, but the implementation is a little naiive IMHO.
I recently wrote a very similar thing for abstracting OpenGL object handles
and file handles. Brook's comment is correct. You'll need some kind of
policy class to handle:
3. testing for an invalid handle (not always zero)
5. (possibly) handle duplication upon copy (some handles, e.g. FDs allow
6. preventing the moving of one kind of handle into another (e.g. an OpenGL
VertexArray is a GLuint and so is a ShaderProgram, but they are not
Also, some resources can be created in groups (see glGenVertexArrays). This
argues for the idea of an array/vector version, or at least a method on the
policy class for vector-like construction.
To me, a more expressive name might be:
Where HandleService defines the service/policy class with services such as:
using native_handle_type = <e.g. GLuint>;
auto construct(...args) -> native_handle_type;
void destroy(native_handle_type&) noexcept;
bool empty(native_handle_type const&) noexcept;
auto move_construct(native_handle_type&& from) noexcept ->
auto move_assign(native_handle_type&& from, native_handle_type& to)
noexcept -> void;
// with option dup/copy methods if the underlying handle supports them
auto copy_or_duplicate(native_handle const&) -> native_handle;
It is possible that handles exist within an outer context, such as a
resource cache with automatic lifetime management. In this case the
HandleService would need to be a value carried in the unique_handle, so it
can track the state of the outer container.
Therefore the HandleService class in most cases will be an empty functor,
but could also hold a reference to container state.
unique_handle might have a method on it called share() which returns a
shared_handle<HandleService>. Much like std::future::share.
On 14 February 2018 at 21:18, Miguel Ojeda via Boost <boost_at_[hidden]>
> Hi all,
> While working on a medium-sized project, I had to wrap quite some
> handles, IDs, descriptors, etc. into RAII classes. Somehow, writing
> those and making them movable seemed more verbose than needed. I
> searched in the STL and Boost for something already implemented, but
> nothing seemed to come up. I decided to write my own prototype to see
> whether I was missing something important; but actually using it in my
> project felt quite natural and simple.
> At this point, I asked for a second opinion from a well-known expert
> (thanks Scott!) and he agreed that it seemed like a reasonable idea
> but, of course, he would also be surprised if others haven't come up
> with something similar. So I polished it up a bit and uploaded it to:
> Below you have the introduction inlined .
> If you have the time, please take a look (specially to the Rationale)
> and let me know your comments. The code itself is very short and
> If you already have this class/template in Boost somewhere that I
> missed, please let me know! Otherwise, if you think this could be
> interesting to put into Boost in some existing library (not sure
> which) or as a new tiny library, I would be glad to make the effort to
> expand it, clean it up, etc.
> Thank you!
> A single-header header-only library for representing unique values
> (handles, IDs, descriptors...) that default to a value on move for
> C++11, C++14 and C++17.
> It simplifies writing resource-owning classes (RAII) with move
> semantics support for resources with handles, IDs or descriptors that
> are supposed to be used as unique values, not as unique pointers. For
> instance, it can be used with non-pointer handlers (like the `int`
> file/socket descriptors in POSIX) and with opaque pointer handlers
> (like the `HWND` handles in the Win32 API).
> As such, it can be used as an alternative to `std::unique_ptr` with or
> without custom deleter, specially for resources that use a non-pointer
> type or resources that are not simply heap-allocated.
> It does not have any overhead compared to using the original type. It
> supports booleans, integers, pointers and enumerations. The default
> value can be different than the default-constructed value (i.e.
> different than 0, nullptr, etc.).
> Unsubscribe & other changes: http://lists.boost.org/
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk