Thread overview
How would You make abstract HANDLE?
Jan 19, 2011
Mariusz Gliwiński
Jan 19, 2011
Simon
Jan 20, 2011
Mariusz Gliwiński
Jan 20, 2011
Simon
January 19, 2011
How to make a HANDLE in D without casting and stuff:
<code>
interface iface{
    void doSomething(HANDLE h);
}
class A : iface {
    override void doSomething(HANDLE h) {
        assert(validPointer(h));
        h.foo = bar;
    }
}
class B : iface {
    someVar table[];
    override void doSomething(HANDLE h) {
        assert(table.isInBounds(h));
        table[h].foo = bar;
}
</code>

Module/class -scoped alias would be great like:
<code>
#a.d
private alias uintptr_t HANDLE;

#b.d
private alias someVar HANDLE;
</code>

but alias is resolved too early for that. How to make it properly then? Union or something else?

Thanks,
Mariusz Gliwiński
January 19, 2011
On 19/01/2011 12:27, Mariusz Gliwiński wrote:
> How to make a HANDLE in D without casting and stuff:
> <code>
> interface iface{
> void doSomething(HANDLE h);
> }
> class A : iface {
> override void doSomething(HANDLE h) {
> assert(validPointer(h));
> h.foo = bar;
> }
> }
> class B : iface {
> someVar table[];
> override void doSomething(HANDLE h) {
> assert(table.isInBounds(h));
> table[h].foo = bar;
> }
> </code>
>
> Module/class -scoped alias would be great like:
> <code>
> #a.d
> private alias uintptr_t HANDLE;
>
> #b.d
> private alias someVar HANDLE;
> </code>
>
> but alias is resolved too early for that. How to make it properly then?
> Union or something else?
>
> Thanks,
> Mariusz Gliwiński

Traditionally:

struct dummy;

alias dummy* HANDLE;

void doSomething(HANDLE h) {
}

Just don't provide a body for dummy to keep it abstract.

-- 
My enormous talent is exceeded only by my outrageous laziness.
http://www.ssTk.co.uk
January 20, 2011
2011-01-19 19:23, Simon wrote:
> Traditionally:
>
> struct dummy;
>
> alias dummy* HANDLE;
>
> void doSomething(HANDLE h) {
> }
>
> Just don't provide a body for dummy to keep it abstract.
So, if I understood  correctly I can't transparently swap pointer with integer of the same size? Fair enough, but:
#iface.d
struct _handle;
alias _handle* HANDLE;

#a.d
struct _handle {
    uintptr_t val;
}
class A : iface {
    void doSomething(HANDLE h) {
        assert(node.val < _t.length);    //HERE
    }
}

states:
a.d (HERE): Error: struct _handle is forward referenced

Which means that he doesn't really see _handle defined, even if it's defined few lines above. Am i doing something wrong?

Thanks,
Mariusz Gliwiński
January 20, 2011
On 20/01/2011 02:20, Mariusz Gliwiński wrote:
> 2011-01-19 19:23, Simon wrote:
>> Traditionally:
>>
>> struct dummy;
>>
>> alias dummy* HANDLE;
>>
>> void doSomething(HANDLE h) {
>> }
>>
>> Just don't provide a body for dummy to keep it abstract.
> So, if I understood correctly I can't transparently swap pointer with
> integer of the same size?

You could use a uintptr_t but you shouldn't.
Using a pointer keeps your interface type safe.

>
Fair enough, but:
> #iface.d
> struct _handle;
> alias _handle* HANDLE;
>
> #a.d
> struct _handle {
> uintptr_t val;
> }
> class A : iface {
> void doSomething(HANDLE h) {
> assert(node.val < _t.length); //HERE
> }
> }
>
> states:
> a.d (HERE): Error: struct _handle is forward referenced
>
> Which means that he doesn't really see _handle defined, even if it's
> defined few lines above. Am i doing something wrong?
>
> Thanks,
> Mariusz Gliwiński

You'll have to use casts in the implementation of your lib.

so:

#iface.d

struct _handle;
alias _handle* HANDLE;

#a.d

struct actualData {
	uintptr_t val;
}

class A : iface {
  void doSomething(HANDLE h) {
     auto ad = cast(actualData*)h;
  }
}

I don't know of any more elegant way of doing it.

D's module system has some draw backs when it comes to trying to fully encapsulate a library.

-- 
My enormous talent is exceeded only by my outrageous laziness.
http://www.ssTk.co.uk