digitalmars.D - Implicit castable structs
- Frank Benoit (20/20) Jan 08 2008 In GTK programming, there are struct that act like a object hierarchy.
- Sean Kelly (3/7) Jan 08 2008 That's a pretty cool idea. It would certainly work.
- Kris (11/32) Jan 08 2008 Yeah, that's old-school inheritance. But I think it's probably a bit dod...
- Dan (15/59) Jan 09 2008 Multiple opCast is the #2 requested feature on that "vote for D changes"...
- Frank Benoit (2/2) Jan 09 2008 opCast is also not really good.
- Frank Benoit (7/13) Jan 09 2008 hm yes, this is certainly true.
- Steven Schveighoffer (8/28) Jan 14 2008 I always thought it would be cool to have inheritance for structs, not f...
In GTK programming, there are struct that act like a object hierarchy.
struct GtkWidget{ /* data member */ }
struct GtkContainer{
GtkWidget widget; // parent is always first member
// more data members
}
struct GtkBin{
GtkContainer container; // parent is always first member
// more data members
}
extern(C) void gtk_widget_foo( GtkWidget* widget );
// in user code ...
GtkBin* bin;
gtk_widget_foo( bin ); // Error: cannot implicit cast
Can the D compiler be enhanced to allow this? More precisely:
"A pointer to a struct is implicitly convertable to all types, that map
to the first position in the struct"
In the case above, a GtkBin* would be convertable to GtkContainer* and
GtkWidget*. A GtkContainer* would /not/ be convertable to GtkBin*
because it does not contain it.
Jan 08 2008
Frank Benoit wrote:Can the D compiler be enhanced to allow this? More precisely: "A pointer to a struct is implicitly convertable to all types, that map to the first position in the struct"That's a pretty cool idea. It would certainly work. Sean
Jan 08 2008
Yeah, that's old-school inheritance. But I think it's probably a bit dodgy
to sidestep type-safety to do what you want. Besides, it's not hard to write
this instead (the old school way):
# gtk_widget_foo (&bin->container.widget);
the codegen will be the same as just using 'bin' by itself, yet the
type-safety is fully retained.
On the other hand, if there were an opCast() in the struct to support what
you're suggesting ....
- Kris
"Frank Benoit" <keinfarbton googlemail.com> wrote in message
news:fm0vht$1tv7$1 digitalmars.com...
In GTK programming, there are struct that act like a object hierarchy.
struct GtkWidget{ /* data member */ }
struct GtkContainer{
GtkWidget widget; // parent is always first member
// more data members
}
struct GtkBin{
GtkContainer container; // parent is always first member
// more data members
}
extern(C) void gtk_widget_foo( GtkWidget* widget );
// in user code ...
GtkBin* bin;
gtk_widget_foo( bin ); // Error: cannot implicit cast
Can the D compiler be enhanced to allow this? More precisely:
"A pointer to a struct is implicitly convertable to all types, that map to
the first position in the struct"
In the case above, a GtkBin* would be convertable to GtkContainer* and
GtkWidget*. A GtkContainer* would /not/ be convertable to GtkBin* because
it does not contain it.
Jan 08 2008
Kris Wrote:Yeah, that's old-school inheritance. But I think it's probably a bit dodgy to sidestep type-safety to do what you want. Besides, it's not hard to write this instead (the old school way): # gtk_widget_foo (&bin->container.widget); the codegen will be the same as just using 'bin' by itself, yet the type-safety is fully retained. On the other hand, if there were an opCast() in the struct to support what you're suggesting .... - Kris "Frank Benoit" <keinfarbton googlemail.com> wrote in message news:fm0vht$1tv7$1 digitalmars.com...Multiple opCast is the #2 requested feature on that "vote for D changes" website, and IMHO the most desireable one for my project. My code would be dramatically more attractive... *gorgeous* if you could do the following: struct Value { const(char)[] opCast() { bla bla bla } int opCast() { bla bla bla } and: Value myfunc() { return 4; // performs opAssign() } Regards, Dan.In GTK programming, there are struct that act like a object hierarchy. struct GtkWidget{ /* data member */ } struct GtkContainer{ GtkWidget widget; // parent is always first member // more data members } struct GtkBin{ GtkContainer container; // parent is always first member // more data members } extern(C) void gtk_widget_foo( GtkWidget* widget ); // in user code ... GtkBin* bin; gtk_widget_foo( bin ); // Error: cannot implicit cast Can the D compiler be enhanced to allow this? More precisely: "A pointer to a struct is implicitly convertable to all types, that map to the first position in the struct" In the case above, a GtkBin* would be convertable to GtkContainer* and GtkWidget*. A GtkContainer* would /not/ be convertable to GtkBin* because it does not contain it.
Jan 09 2008
opCast is also not really good. passing a null pointer would crash then. (or not?)
Jan 09 2008
Frank Benoit wrote:opCast is also not really good. passing a null pointer would crash then. (or not?)Yes, IIRC there was some obnoxious "assert(this !is null);" in all non-static member functions... regards, frank
Jan 09 2008
0ffh Wrote:Frank Benoit wrote:I *need* to be able to go: Value myValue = 4; int bob = myValue; At the moment I'm accomplishing that by doing: Value myValue = 4; int bob = Value.toInteger(); Which is essentially identical to opCast(), except it gets ugly. It's pretty clear to me that Value is performing implicit opAssign/opCall when something goes in, and likewise it would be clear with opCast. The other major place I'd like it to handle this is with functions. I can't do this: Value myFunc() { return 4; } or this: Value myFunc(Value self, Value cc) { bla bla bla } myFunc(3,5); If I got all this opCall/opAssign/opCast sorted out, my source would be about 15% smaller because a fair chunk of it is type conversions to handle ECMAScript's var. Regards, DanopCast is also not really good. passing a null pointer would crash then. (or not?)Yes, IIRC there was some obnoxious "assert(this !is null);" in all non-static member functions... regards, frank
Jan 09 2008
Perhaps, to clarify;
What I've got:
static Value Global_parseFloat(Value self, Value cc, Value[] a ...) {
if(a.length)
return cast(Value) a[0].toReal();
return NAN;
}
static Value Global_isNaN(Value self, Value cc, Value[] a ...) {
return cast(Value) ( (!a.length || a[0].toReal() == real.nan?) true :
false);
}
~~
What I want:
extern(Walnut):
Value Global_parseFloat(Value[] a ...) {
if(a.length)
return cast(real) a[0];
return real.nan;
}
Value Global_isNaN(Value[] a ...) {
return (!a.length || cast(real) a[0] == real.nan);
}
Jan 09 2008
Kris schrieb:Yeah, that's old-school inheritance. But I think it's probably a bit dodgy to sidestep type-safety to do what you want. Besides, it's not hard to write this instead (the old school way): # gtk_widget_foo (&bin->container.widget);hm yes, this is certainly true. GtkMessageDialog* msgdlg; gtk_widget_foo (&msgdlg.dialog.window.bin.container.widget); gtk_widget_foo (cast(GtkWidget*)msgdlg); Both are bad, the second can be shorter. Even if i hate explicit upcast, in this case I prefer it :)
Jan 09 2008
"Frank Benoit" wrote
In GTK programming, there are struct that act like a object hierarchy.
struct GtkWidget{ /* data member */ }
struct GtkContainer{
GtkWidget widget; // parent is always first member
// more data members
}
struct GtkBin{
GtkContainer container; // parent is always first member
// more data members
}
extern(C) void gtk_widget_foo( GtkWidget* widget );
// in user code ...
GtkBin* bin;
gtk_widget_foo( bin ); // Error: cannot implicit cast
Can the D compiler be enhanced to allow this? More precisely:
"A pointer to a struct is implicitly convertable to all types, that map to
the first position in the struct"
In the case above, a GtkBin* would be convertable to GtkContainer* and
GtkWidget*. A GtkContainer* would /not/ be convertable to GtkBin* because
it does not contain it.
I always thought it would be cool to have inheritance for structs, not for
virtual function overloads, but just for this implicit casting purposes, and
inheriting final functions:
struct GtkWidget {}
struct GtkContainer : GtkWidget {}
struct GtkBin : GtkContainer {}
-Steve
Jan 14 2008









Sean Kelly <sean f4.ca> 