www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How would You make abstract HANDLE?

reply =?UTF-8?B?TWFyaXVzeiBHbGl3acWEc2tp?= <alienballance gmail.com> writes:
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
Jan 19 2011
parent reply Simon <s.d.hammett gmail.com> writes:
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
Jan 19 2011
parent reply =?UTF-8?B?TWFyaXVzeiBHbGl3acWEc2tp?= <alienballance gmail.com> writes:
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
Jan 19 2011
parent Simon <s.d.hammett gmail.com> writes:
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
Jan 20 2011