www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - struct Unique(T)

reply "ChrisG" <christopher.gassib gmail.com> writes:
Hi, I've been following the D language off and on for several 
years, have read Andrei's D book, but haven't ever posted here 

was playing with D using the derelict bindings for the SDL 
library.

The SDL library uses handles in the form of struct pointers for 
resource management. In C++ I like using unique and shared 
pointers to manage C handles. Additionally, I like being able to 
specify custom clean up functions for specific resources. For 
example:

typedef std::unique_ptr<HandleType, HandleDeleter> handle_ptr;

My question is: what's the status of D's struct Unique? It looks 
like struct RefCounted is current, but I can't tell with Unique. 
There's several comments in the source that say: doesn't work 
yet. It seems like some of it could be made to work as intended. 
For example, the commented out code to disallow construction via 
an lvalue:

// this(U)(ref Unique!(U) u) = null; // commented out
// this(this) = null;

Couldn't this be written:

 disable this(U)(ref Unique!(U) u);
 disable this(this);

Seems to work when I try it. It stopped the copy from working, 
but I can still do a move. Like this:

Unique!(int) i1 = new int;
Unique!(int) i2 = move(i1); // works!

Next, I'd like to be able to use a custom deleter. For example, a 
naive implementation I could write would be something like:

struct Unique2(T, string D = "delete")
{
...
     ~this()
     {
         debug(Unique2) writeln("Unique destructor of ", (_p is 
null)? null: _p);
         if (_p !is null)
         {
             mixin(""~D~" (_p);"); // delete _p;
             _p = null;
         }
     }
...

So, I could do things like:

Unique2!(int, "free") i1 = cast(int*)malloc(int.sizeof); // lame 
example

A real implementation would allow more interesting deleters in 
the form of delegates, but I'm already stretching my D skillz.

Anyway, am I missing something here? Is there a better D language 
feature I'm not thinking about that provides the same 
functionality as C++'s std::unique_ptr<> with custom deleters; 
besides putting scope (exit) everywhere?

-Chris
Nov 06 2013
next sibling parent reply "Chris Cain" <clcain uncg.edu> writes:
On Thursday, 7 November 2013 at 00:07:25 UTC, ChrisG wrote:
 My question is: what's the status of D's struct Unique? It 
 looks like struct RefCounted is current, but I can't tell with 
 Unique. There's several comments in the source that say: 
 doesn't work yet. It seems like some of it could be made to 
 work as intended. For example, the commented out code to 
 disallow construction via an lvalue:
I'm pretty sure things like Unique have been neglected for awhile. Probably for a decent reason, but a lot of language features have been landing that could help polish it up a bit more.
 Next, I'd like to be able to use a custom deleter. For example, 
 a naive implementation I could write would be something like:

 ... snip ...

 So, I could do things like:

 Unique2!(int, "free") i1 = cast(int*)malloc(int.sizeof); // 
 lame example

 A real implementation would allow more interesting deleters in 
 the form of delegates, but I'm already stretching my D skillz.
I think Unique will probably be getting something along those lines reasonably shortly, but std.allocator will have to be fully completed first. http://forum.dlang.org/thread/l4btsk$5u8$1 digitalmars.com Once that's done we'll see some memory management schemes like what you're suggesting be implemented. But it's probably not a good idea to add that stuff before we figure out a good way to use it with the new std.allocator effectively.
Nov 06 2013
parent "ChrisG" <christopher.gassib gmail.com> writes:
On Thursday, 7 November 2013 at 01:09:45 UTC, Chris Cain wrote:
 On Thursday, 7 November 2013 at 00:07:25 UTC, ChrisG wrote:
 My question is: what's the status of D's struct Unique? It 
 looks like struct RefCounted is current, but I can't tell with 
 Unique. There's several comments in the source that say: 
 doesn't work yet. It seems like some of it could be made to 
 work as intended. For example, the commented out code to 
 disallow construction via an lvalue:
I'm pretty sure things like Unique have been neglected for awhile. Probably for a decent reason, but a lot of language features have been landing that could help polish it up a bit more.
 Next, I'd like to be able to use a custom deleter. For 
 example, a naive implementation I could write would be 
 something like:

 ... snip ...

 So, I could do things like:

 Unique2!(int, "free") i1 = cast(int*)malloc(int.sizeof); // 
 lame example

 A real implementation would allow more interesting deleters in 
 the form of delegates, but I'm already stretching my D skillz.
I think Unique will probably be getting something along those lines reasonably shortly, but std.allocator will have to be fully completed first. http://forum.dlang.org/thread/l4btsk$5u8$1 digitalmars.com Once that's done we'll see some memory management schemes like what you're suggesting be implemented. But it's probably not a good idea to add that stuff before we figure out a good way to use it with the new std.allocator effectively.
Ok, thanks. That does make some sense to me. I read some of the std.allocator thread. I'll take a look at that code and see what I can make of it.
Nov 07 2013
prev sibling parent reply "Namespace" <rswhite4 googlemail.com> writes:
On Thursday, 7 November 2013 at 00:07:25 UTC, ChrisG wrote:
 Hi, I've been following the D language off and on for several 
 years, have read Andrei's D book, but haven't ever posted here 

 I was playing with D using the derelict bindings for the SDL 
 library.

 The SDL library uses handles in the form of struct pointers for 
 resource management. In C++ I like using unique and shared 
 pointers to manage C handles. Additionally, I like being able 
 to specify custom clean up functions for specific resources. 
 For example:

 typedef std::unique_ptr<HandleType, HandleDeleter> handle_ptr;

 My question is: what's the status of D's struct Unique? It 
 looks like struct RefCounted is current, but I can't tell with 
 Unique. There's several comments in the source that say: 
 doesn't work yet. It seems like some of it could be made to 
 work as intended. For example, the commented out code to 
 disallow construction via an lvalue:

 // this(U)(ref Unique!(U) u) = null; // commented out
 // this(this) = null;

 Couldn't this be written:

  disable this(U)(ref Unique!(U) u);
  disable this(this);

 Seems to work when I try it. It stopped the copy from working, 
 but I can still do a move. Like this:

 Unique!(int) i1 = new int;
 Unique!(int) i2 = move(i1); // works!

 Next, I'd like to be able to use a custom deleter. For example, 
 a naive implementation I could write would be something like:

 struct Unique2(T, string D = "delete")
 {
 ...
     ~this()
     {
         debug(Unique2) writeln("Unique destructor of ", (_p is 
 null)? null: _p);
         if (_p !is null)
         {
             mixin(""~D~" (_p);"); // delete _p;
             _p = null;
         }
     }
 ...

 So, I could do things like:

 Unique2!(int, "free") i1 = cast(int*)malloc(int.sizeof); // 
 lame example

 A real implementation would allow more interesting deleters in 
 the form of delegates, but I'm already stretching my D skillz.

 Anyway, am I missing something here? Is there a better D 
 language feature I'm not thinking about that provides the same 
 functionality as C++'s std::unique_ptr<> with custom deleters; 
 besides putting scope (exit) everywhere?

 -Chris
Dgame use the SDL also and needed therefore (as you do) shared and unique pointers (mostly shared). So I wrote my own versions and like to share them with you, maybe it helps you. Surface with shared SDL_Surface: https://github.com/Dgame/Dgame/blob/master/Graphics/Surface.d#L67 Creation of the shared_ptr: https://github.com/Dgame/Dgame/blob/master/Graphics/Surface.d#L100 And the shared_ptr struct: https://github.com/Dgame/Dgame/blob/master/Internal/Shared.d
Nov 07 2013
parent reply "ChrisG" <christopher.gassib gmail.com> writes:
On Thursday, 7 November 2013 at 09:51:38 UTC, Namespace wrote:
 Dgame use the SDL also and needed therefore (as you do) shared 
 and unique pointers (mostly shared). So I wrote my own versions 
 and like to share them with you, maybe it helps you.

 Surface with shared SDL_Surface: 
 https://github.com/Dgame/Dgame/blob/master/Graphics/Surface.d#L67
 Creation of the shared_ptr: 
 https://github.com/Dgame/Dgame/blob/master/Graphics/Surface.d#L100
 And the shared_ptr struct: 
 https://github.com/Dgame/Dgame/blob/master/Internal/Shared.d
Thanks. I've been looking through your website and github. Very cool stuff. What license is your code released under?
Nov 07 2013
parent "Namespace" <rswhite4 googlemail.com> writes:
On Thursday, 7 November 2013 at 18:19:35 UTC, ChrisG wrote:
 On Thursday, 7 November 2013 at 09:51:38 UTC, Namespace wrote:
 Dgame use the SDL also and needed therefore (as you do) shared 
 and unique pointers (mostly shared). So I wrote my own 
 versions and like to share them with you, maybe it helps you.

 Surface with shared SDL_Surface: 
 https://github.com/Dgame/Dgame/blob/master/Graphics/Surface.d#L67
 Creation of the shared_ptr: 
 https://github.com/Dgame/Dgame/blob/master/Graphics/Surface.d#L100
 And the shared_ptr struct: 
 https://github.com/Dgame/Dgame/blob/master/Internal/Shared.d
Thanks. I've been looking through your website and github. Very cool stuff. What license is your code released under?
Under zlib/png. I should add this on my site and in my code. Thanks for remembering. :)
Nov 07 2013