Open blm768 opened 11 years ago
I found a hilariously old thread about this: http://forum.dlang.org/thread/fv7r3g$3ub$1@digitalmars.com
Seems the problem is this: http://dlang.org/struct.html#StructLiteral
If a struct has a member function named opCall, then struct literals for that struct are not possible.
... Actually, after reading a bit more I came across this: http://dlang.org/operatoroverloading.html#FunctionCall
To avoid the limitation, you need to also declare constructor so that it takes priority over opCall in Type(...) syntax.
Which you seem to do. Huh, weird.
Anyway, changing the test.d to not use struct literals makes at least btVector3 work. btQuaternion still complains:
Error: struct btQuaternion does not overload ()
quaternion.d's mixin(joinOverloads!.. doesn't actually mixin anything?
I had replaced all of the constructors with static opCall because I was having issues overloading them, so currently there shouldn't be any true constructors for those structs. As for joinOverloads, you're right about it not mixing anything in; I never finished implementing it.
At this point, I think that D might not be ready to create a binding like this using only compile-time code generation. The bindings may need to move to using an external generator. I've started working on an interface description language using the Pegged parser generator; I can generate the C++ and D sides of the bindings from that, which means that I won't need to use any mixins. That should sidestep the overloading issues with the constructors.
On 09/23/13 05:24, vuaru wrote:
I found a hilariously old thread about this: http://forum.dlang.org/thread/fv7r3g$3ub$1@digitalmars.com http://forum.dlang.org/thread/fv7r3g%243ub%241@digitalmars.com
Seems the problem is this: http://dlang.org/struct.html#StructLiteral
If a struct has a member function named opCall, then struct literals for that struct are not possible.
... Actually, after reading a bit more I came across this: http://dlang.org/operatoroverloading.html#FunctionCall
To avoid the limitation, you need to also declare constructor so that it takes priority over opCall in Type(...) syntax.
Which you seem to do. Huh, weird.
Anyway, changing the test.d to not use struct literals makes at least btVector3 work. btQuaternion still complains:
Error: struct btQuaternion does not overload ()
quaternion.d's mixin(joinOverloads!.. doesn't actually mixin anything?
— Reply to this email directly or view it on GitHub https://github.com/blm768/BulletD/issues/2#issuecomment-24915947.
I had replaced all of the constructors with static opCall because I was having issues overloading them, so currently there shouldn't be any true constructors for those structs.
Oh so you do have only opCalls defined, and no constructors. Then it makes sense that they cannot be used as struct literals in test.d, since that's what the link explicitly states.
It's a limitation, sure, but if that's the only problem left..
On 09/23/13 12:35, vuaru wrote:
Oh so you do have only opCalls defined, and no constructors. Then it makes sense that they cannot be used as struct literals in test.d, since that's what the link explicitly states.
It's a limitation, sure, but if that's the only problem left..
— Reply to this email directly or view it on GitHub https://github.com/blm768/BulletD/issues/2#issuecomment-24947626.
The problem is that I'm not sure how to get around that particular issue. If I define constructors, it looks like they'll be used instead of static opCall, but trying to overload the constructors has just given me issues so far. If I throw in dummy constructors, the compiler starts complaining that the static method cppNew is not accessible. I'll play with it a bit more, but I'm not optimistic that I can actually get a stable solution.
trying to overload the constructors has just given me issues so far.
What were these issues specifically?
On 09/24/13 08:03, vuaru wrote:
trying to overload the constructors has just given me issues so far.
What were these issues specifically?
I can't remember exactly what error messages DMD gave me, but I remember that DMD choked on this particular style of code:
struct SomeBindingClass { //...
mixin constructor!() _c0;
alias _c0.__ctor __ctor;
mixin constructor!(int) _c1;
alias _c1.__ctor __ctor;
}
The constructors have to be aliased together for overloading to work on them, but there seems to be no way to refer to the constructor other than through the __ctor identifier. However, DMD doesn't seem to accept that as a callable constructor because it wasn't defined using the "this() {}" syntax outside of the mixin. As far as I can tell, the only way around the issue is to convert the constructor mixin to a string mixin, but then it doesn't have access to typeof(this) unless I pass it as an explicit parameter, which I'm trying to avoid if at all possible.
If I understand correctly, then you're saying you can't use the template mixins to insert multiple overloading contructors?
Either that is no longer the case or I'm misunderstanding, because I just tried the following simplified example which compiles:
import std.stdio;
void main()
{
writeln(Tree(4).apple);
writeln(Tree(4,3).apple);
writeln(Tree(4,3,2).apple);
}
struct Tree
{
int apple;
mixin test;
}
mixin template test()
{
this(int i) { apple = i; }
this(int i, int j) { apple = i+j; }
this(int i, int j, int k) { apple = i+j+k; }
}
(Note: I'm interested in making a simplified version of the wished-for functionality so I can ask the newsgroups for help.)
It works when all of the overloaded constructors are in the same template instance. However, this shouldn't compile:
|import std.stdio;
void main() { writeln(Tree(4).apple); writeln(Tree(4,3).apple); writeln(Tree(4,3,2).apple); }
struct Tree { int apple;
mixin constructor!(int);
mixin constructor!(int, int);
mixin constructor!(int, int, int);
}
mixin template constructor(Args) { this(Args) {/* some code here*/} } |
That example is much closer to the actual structure of the binding code.
On 09/24/13 11:56, vuaru wrote:
If I understand correctly, then you're saying you can't use the template mixins to insert multiple overloading contructors?
Either that is no longer the case or I'm misunderstanding, because I just tried the following simplified example which compiles:
|import std.stdio;
void main() { writeln(Tree(4).apple); writeln(Tree(4,3).apple); writeln(Tree(4,3,2).apple); }
struct Tree { int apple;
mixin test;
}
mixin template test() { this(int i) { apple = i; } this(int i, int j) { apple = i+j; } this(int i, int j, int k) { apple = i+j+k; } } |
— Reply to this email directly or view it on GitHub https://github.com/blm768/BulletD/issues/2#issuecomment-25032582.
It does compile, assuming you meant
mixin template constructor(Args ...)
(Where does one find documentation about these kind of language features anyway?)
With the current DMD release, the code just chokes with an assertion error. Have you tested it with a development build?
You're right it does (in fact it gives an abnormal program termination) with DMD 2.063.2.
But it does compile with a fairly recent git HEAD (which I was using because that was required for bulletD anyway).
So to me it seems that the problem has been solved in DMD, just not yet released officially.
Interesting... Based on DMD's behavior when normal methods are mixed in, I didn't expect DMD to allow constructors from different mixins to automatically overload with each other. I suppose that it makes sense because constructors have much more specific semantics than arbitrary methods do, so overloading is less likely to cause issues.
Mixing in multiple constructors and aliasing them together makes DMD complain that the constructors are not accessible.