[RFC] unique_val (handles, IDs, descriptors...)
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: https://github.com/ojeda/unique_val Below you have the introduction inlined [1]. 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 straightforward. 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! Miguel [1] """ 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.). """
On Wed, Feb 14, 2018 at 3:18 PM, Miguel Ojeda via Boost < boost@lists.boost.org> wrote:
IMO, such a class is definitely useful. Design concerns: - unique_val should be copyable if T is copyable. Whether or not a type which aggregates this is copyable is an orthogonal, separate concern from what the moved-from state should be. If you go this route, unique_val is the wrong name. - Instead of providing operator bool(), why not provide operator T&() and operator T const&()? - What about comparisons of the form: unique_val<T, a> op unique_val<T, b>? - What about comparisons of the form: unique_val<T> op T (as well as T op unique_val<T>)? - Propagate noexcept correctly, as it is dependent on the underlying operations. - Propagate constexpr correctly (for instance, your default constructor should be constexpr). -- Nevin ":-)" Liber <mailto:nevin@cplusplusguy.com <nevin@eviloverlord.com>> +1-847-691-1404 <(847)%20691-1404>
AMDG On 02/14/2018 02:48 PM, Nevin Liber via Boost wrote:
On Wed, Feb 14, 2018 at 3:18 PM, Miguel Ojeda via Boost < boost@lists.boost.org> wrote:
IMO, such a class is definitely useful.
Design concerns:
- unique_val should be copyable if T is copyable. Whether or not a type which aggregates this is copyable is an orthogonal, separate concern from what the moved-from state should be. If you go this route, unique_val is the wrong name.
That completely subverts the point of using unique_val in the first place, which is that you have some cleanup operation that needs to be applied exactly once, when your done with the object. This is most common when dealing with C API's where everything is copyable. In Christ, Steven Watanabe
On Wed, Feb 14, 2018 at 10:48 PM, Nevin Liber via Boost <boost@lists.boost.org> wrote:
On Wed, Feb 14, 2018 at 3:18 PM, Miguel Ojeda via Boost < boost@lists.boost.org> wrote:
IMO, such a class is definitely useful.
Thanks *a lot* for the almost instantaneous review! :)
Design concerns:
- unique_val should be copyable if T is copyable. Whether or not a type which aggregates this is copyable is an orthogonal, separate concern from what the moved-from state should be. If you go this route, unique_val is the wrong name.
As Steven mentions, it cannot be copyable since it is meant to hold values where you need to perform an action on deletion once per value, i.e. I meant "unique" here as the same as "unique_ptr" means: only one "owner" is supposed to hold a given value.
- Instead of providing operator bool(), why not provide operator T&() and operator T const&()?
Hum, that could be interesting, not sure of all the implications, though.
- What about comparisons of the form: unique_val<T, a> op unique_val<T, b>? - What about comparisons of the form: unique_val<T> op T (as well as T op unique_val<T>)?
Indeed, I suggest the second ones in the Rationale as possible extensions, I think they make quite a lot of sense. I thought about the first ones, but I don't think they are that useful in practise, since when you are using the unique_val, you already know what your "invalid" or "moved-from" or "default" value has to be, so you will not be using different ones (i.e. I don't think in practise unique_val<T, x> and unique_val<T, y> where x != y is a common case).
- Propagate noexcept correctly, as it is dependent on the underlying operations.
I thought that, given that T has to be a type suitable for the default (which itself is a non-type template parameter), it couldn't be anything throwing exceptions -- but I may be wrong here; please let me know!
- Propagate constexpr correctly (for instance, your default constructor should be constexpr).
Indeed, probably a few constexpr's are missing. I only added the obvious get_default() one since I am not sure what are the best practices for writing them for C++11, C++14 and C++17 at the same time without breaking something. Since it was optional, I left it at that for the moment. Thanks a lot again! Miguel
-- Nevin ":-)" Liber <mailto:nevin@cplusplusguy.com <nevin@eviloverlord.com>> +1-847-691-1404 <(847)%20691-1404>
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
On Feb 14, 2018, at 2:18 PM, Miguel Ojeda via Boost <boost@lists.boost.org> wrote:
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 straightforward.
A quick look suggests that this is useful. However, why not have the unique_val class _be_ the RAII class? Couldn't this be done with extra template arguments (or just one) giving construction/destruction policies? You have perfect forwarding so constructor arguments can be forwarded to the policy. Would this not give you the Foo class for free? Just wondering. Cheers, Brook
On Wed, Feb 14, 2018 at 11:06 PM, Brook Milligan <brook@nmsu.edu> wrote:
On Feb 14, 2018, at 2:18 PM, Miguel Ojeda via Boost <boost@lists.boost.org> wrote:
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 straightforward.
A quick look suggests that this is useful.
Thanks as well for the very quick review!
However, why not have the unique_val class _be_ the RAII class? Couldn't this be done with extra template arguments (or just one) giving construction/destruction policies? You have perfect forwarding so constructor arguments can be forwarded to the policy. Would this not give you the Foo class for free? Just wondering.
I thought about that as a possible extension, but since I typically need/want to write other things (operations, logging...) in the RAII class, I wrote that way. Also, for beginners, it may be easier to understand the ctor/dtor pair than playing with policies. Still, I agree with you, I think adding support for a custom deleter and the like is a good idea (as unique_ptr does) and allows for both styles -- I have it there as a possible extension at the end of Notes. Please let me know if I misunderstood you, though! Cheers, Miguel
Cheers, Brook
2018-02-14 23:48 GMT+01:00 Miguel Ojeda via Boost <boost@lists.boost.org>:
On Wed, Feb 14, 2018 at 11:06 PM, Brook Milligan <brook@nmsu.edu> wrote:
On Feb 14, 2018, at 2:18 PM, Miguel Ojeda via Boost <
boost@lists.boost.org> wrote:
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 straightforward.
A quick look suggests that this is useful.
Thanks as well for the very quick review!
However, why not have the unique_val class _be_ the RAII class?
Couldn't this be done with extra template arguments (or just one) giving construction/destruction policies? You have perfect forwarding so constructor arguments can be forwarded to the policy. Would this not give you the Foo class for free? Just wondering.
I thought about that as a possible extension, but since I typically need/want to write other things (operations, logging...) in the RAII class, I wrote that way.
I actually find it a convincing argument. Now I can see why you would want to have only `unique_value`. Regards, &rzej;
Hi all, On Thu, Feb 15, 2018 at 5:21 PM Andrzej Krzemienski via Boost <boost@lists.boost.org> wrote:
I actually find it a convincing argument. Now I can see why you would want to have only `unique_value`.
Thanks a lot Andrzej! Given the positive feedback I got here a few months ago about this from several people, I decided to make this into a C++ standard proposal (I missed the previous mailing deadline) but I submitted it for this one (pre-San Diego): http://open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1314r0.html Notwithstanding this, I am still up for implementing this separately to have it also in C++11 and up. I will probably keep an implementation in https://github.com/ojeda/unique_val, but also I don't mind putting another into Boost. Cheers, Miguel
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: 1. creation 2. destruction 3. testing for an invalid handle (not always zero) 4. move/move-construct 5. (possibly) handle duplication upon copy (some handles, e.g. FDs allow this) 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 conceptually compatible) 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: template<class HandleService> struct unique_handle; 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 -> native_handle_type; 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; Further: 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. Further Again: 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@lists.boost.org> wrote:
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:
https://github.com/ojeda/unique_val
Below you have the introduction inlined [1].
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 straightforward.
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! Miguel
[1]
""" 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/ mailman/listinfo.cgi/boost
On Thu, Feb 15, 2018 at 8:10 AM, Richard Hodges via Boost <boost@lists.boost.org> wrote:
The idea is correct, but the implementation is a little naiive IMHO.
Thanks for taking the time to check it out!
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:
1. creation 2. destruction 3. testing for an invalid handle (not always zero)
unique_val allows for a compile-time default value. Of course, this is of no use if testing for an invalid handle requires more complex logic. But please see below.
4. move/move-construct 5. (possibly) handle duplication upon copy (some handles, e.g. FDs allow this) 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 conceptually compatible)
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.
Agreed, an array version similar to the way std::unique_ptr does it is a good idea!
To me, a more expressive name might be:
template<class HandleService> struct unique_handle;
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 -> native_handle_type; 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;
I can see the value in having a class with all the required customization points to build a RAII class right out of it. However, shouldn't that be a separate class (indeed, possibly called unique_handle) that might use (or not) a unique_val internally to store the actual raw handle? In other words, the point of unique_val is isolating the concept of a unique value, rather than trying to be a completely generic RAII template with all the required hooks to build handle classes -- even if unique_handle can be made to reduce to unique_val with a default policy. In other words, I don't see many people using unique_handle to replace their custom RAII classes; while I can easily see people picking up unique_val here and there, given its simplicity. Also, there is the following argument that could be made: if you have to write such a complex HandleService, you are probably better off writing directly the RAII class instead; in the end, you are not gaining much by using unique_handle since all the actual work is actually in the HandlerService. While in this context, unique_val only takes care of ensuring the value is move-only (so your RAII class is already noncopyable), giving you move semantics with a proper default value (so the right thing already happens) and a nice name to mark your raw value with; while at the same time being extremely simple to understand and apply by anyone. Please, do not get me wrong, I am not trying to argue against other possibilities and I am no expert on writing generic libraries for other people to use! Actually the custom deleter, the array version and the shared idea are all very nice improvements in my opinion, given that they do not add complexity for their typical usage and it is already well-known from their parallel in std::unique_ptr (shared is not complex in the sense that it would be another class).
Further: 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.
Further Again:
unique_handle might have a method on it called share() which returns a shared_handle<HandleService>. Much like std::future::share.
This is also an interesting proposal. Being able to use the reference counting features of shared_ptr outside of pointers makes sense. Thanks! Miguel
On 14 February 2018 at 21:18, Miguel Ojeda via Boost <boost@lists.boost.org> wrote:
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:
https://github.com/ojeda/unique_val
Below you have the introduction inlined [1].
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 straightforward.
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! Miguel
[1]
""" 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/ mailman/listinfo.cgi/boost
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
2018-02-14 22:18 GMT+01:00 Miguel Ojeda via Boost <boost@lists.boost.org>:
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:
https://github.com/ojeda/unique_val
Below you have the introduction inlined [1].
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 straightforward.
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.
So, it is my understanding that the difference between an `int` and an `unique_val<int>` is that the latter is not copyable (and whoever keeps it as member is not copyable), and moving from it guarantees that a certain default value will be assigned to it. Right? If I got that right, I have two remarks. 1. In your example: ``` class Foo { unique_val<FooHandle> id_; public: Foo() : id_(CreateFoo(/* ... */)) { if (not id_) throw std::runtime_error("CreateFoo() failed"); } ~Foo() { if (id_) DestroyFoo(id_.get()); } Foo(Foo&&) = default; Foo& operator=(Foo&&) = default; }; ``` `id_` is private (should be of no interest to the users). `Foo` is indeed non-copyable, but it has not been explicitly declared to the users: it has only been inferred from the private member (implementation detail). I would still expect that the class has copy operations explicitly deleted so that I know it is by design rather than by the current choice of private members. Your type indeed prevents accidental copying. But at least the example encourages a bad practice of not declaring the interface of your class explicitly. 2. Next thing I have to do after defining my `unique_value<>` type is to write a RAII wrapper for the resource. So, as others mentioned` maybe I would prefer a tool for doing the latter rather than only a movable ID. There is a proposal for adding this into the Standard Library: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0052r6.pdf And also a reference implementation: https://github.com/PeterSommerlad/SC22WG21_Papers/tree/master/workspace/P005... Regards, &rzej;
On Thu, Feb 15, 2018 at 11:18 AM, Andrzej Krzemienski via Boost <boost@lists.boost.org> wrote:
2018-02-14 22:18 GMT+01:00 Miguel Ojeda via Boost <boost@lists.boost.org>:
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:
https://github.com/ojeda/unique_val
Below you have the introduction inlined [1].
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 straightforward.
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.
So, it is my understanding that the difference between an `int` and an `unique_val<int>` is that the latter is not copyable (and whoever keeps it as member is not copyable), and moving from it guarantees that a certain default value will be assigned to it. Right?
Right. Specially important is the fact that it enables those that keep it as a member movable (if they default it -- given the current rules) without effort, i.e. no need to implement move constructor/assignment (which for some people is non trivial or they have not yet learned them).
If I got that right, I have two remarks.
1. In your example:
``` class Foo { unique_val<FooHandle> id_;
public: Foo() : id_(CreateFoo(/* ... */)) { if (not id_) throw std::runtime_error("CreateFoo() failed"); }
~Foo() { if (id_) DestroyFoo(id_.get()); }
Foo(Foo&&) = default; Foo& operator=(Foo&&) = default; }; ```
`id_` is private (should be of no interest to the users). `Foo` is indeed non-copyable, but it has not been explicitly declared to the users: it has only been inferred from the private member (implementation detail). I would still expect that the class has copy operations explicitly deleted so that I know it is by design rather than by the current choice of private members.
Your type indeed prevents accidental copying. But at least the example encourages a bad practice of not declaring the interface of your class explicitly.
You are right! The example tries to be as minimal as possible and tries to make clear that we get the copy operations deleted by default, but probably a comment would be nice to explicitly say to (like the comment inside Widget), specially since it is meant for beginners. I partially agree with you, for some classes I typically delete/default/implement all the special functions (basically the RAII ones), but for the general case, it is a matter of taste: some people prefer to be as succinct as possible (and if you are using the Rule of Zero, that is the point).
2. Next thing I have to do after defining my `unique_value<>` type is to write a RAII wrapper for the resource. So, as others mentioned` maybe I would prefer a tool for doing the latter rather than only a movable ID. There is a proposal for adding this into the Standard Library: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0052r6.pdf
And also a reference implementation:
https://github.com/PeterSommerlad/SC22WG21_Papers/tree/master/workspace/P005...
Very nice! Indeed, this is something that is missing from the standard library and would be very useful. I just took a cursory look at the proposal/code; some comments w.r.t. unique_val (please correct me if I am wrong!) - it seems unique_resource is not without overhead since it has to keep a Deleter somehow and/or know whether it has to delete or not on the destructor. In the reference implementation a unique_resource<int> is the size of 2 ints when using an empty Deleter (i.e. one int plus 1 byte plus the padding). unique_val can be used to implement RAII classes without any overhead [*] - it does not provide for a default deleter, since it is not meant to just hold a movable value (fine though, since it is not meant to -- same discussion with unique_handle). Cheers, Miguel [*] #include <iostream> #include "scope_exit.h" #include "unique_resource.h" struct Deleter { const Deleter & operator()(int) const { return *this; } } }; int main() { std::experimental::unique_resource<int, Deleter> foo(1, Deleter()); std::cout << sizeof(foo) << '\n' << sizeof(int) << '\n'; return 0; }
Regards, &rzej;
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
On Wed, Feb 14, 2018 at 10:18 PM, Miguel Ojeda via Boost < boost@lists.boost.org> wrote:
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 straightforward.
Hi, I didn't look yet at the implementation but I can confirm I had to implement similar tools for different projects in different organisations. It seems useful, though it also seems to be similar (and conflict with goals of) p0052's unique_resource type. See: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0052r6.pdf Did you consider providing an implementation of this proposal instead? A. Joël Lamotte
On Thu, Feb 15, 2018 at 11:26 AM, Klaim - Joël Lamotte via Boost <boost@lists.boost.org> wrote:
On Wed, Feb 14, 2018 at 10:18 PM, Miguel Ojeda via Boost < boost@lists.boost.org> wrote:
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 straightforward.
Hi,
I didn't look yet at the implementation but I can confirm I had to implement similar tools for different projects in different organisations.
It seems useful, though it also seems to be similar (and conflict with goals of) p0052's unique_resource type. See: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0052r6.pdf
Thank you! Please see the answer above to Andrzej. It is indeed similar, although I am not sure if entirely overlapping. I would say unique_resource seems like a more specific tool, while unique_val is a low-level primitive.
Did you consider providing an implementation of this proposal instead?
I didn't know about the proposal -- but indeed it is interesting to have an implementation for pre-C++20 users (assuming it will be in C++20). Cheers, Miguel
A. Joël Lamotte
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (7)
-
Andrzej Krzemienski
-
Brook Milligan
-
Klaim - Joël Lamotte
-
Miguel Ojeda
-
Nevin Liber
-
Richard Hodges
-
Steven Watanabe