Thread overview
struct Unique(T)
Nov 07, 2013
ChrisG
Nov 07, 2013
Chris Cain
Nov 07, 2013
ChrisG
Nov 07, 2013
Namespace
Nov 07, 2013
ChrisG
Nov 07, 2013
Namespace
November 07, 2013
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 before. Mostly, I come from a C++ and C# background. Recently, 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
November 07, 2013
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.
November 07, 2013
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 before. Mostly, I come from a C++ and C# background. Recently, 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
November 07, 2013
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.
November 07, 2013
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?
November 07, 2013
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. :)