blob: 2f52826bc4f1721a3b20082b06eb1ffd624ae9af [file] [log] [blame]
// EXTRA_CPP_SOURCES: cpp7925.cpp
/*
Exclude -O due to a codegen bug on OSX:
https://issues.dlang.org/show_bug.cgi?id=22556
PERMUTE_ARGS(osx): -inline -release -g
*/
import core.vararg;
extern(C++) class C1
{
public:
~this();
int i;
final int f0();
final int f1(int a);
final int f2(int a, int b);
int f3(int a, int b);
final int f4(int a, ...);
};
extern(C++) C1 createC1();
extern(C++) class C2
{
public:
~this()
{
}
int i;
final int f0()
{
return i;
}
final int f1(int a)
{
return i + a;
}
final int f2(int a, int b)
{
return i + a + b;
}
int f3(int a, int b)
{
return i + a + b;
}
final int f4(int a, ...)
{
int r = i + a;
int last = a;
va_list argp;
va_start(argp, a);
while (last)
{
last = va_arg!int(argp);
r += last;
}
va_end(argp);
return r;
}
};
extern(C++) C2 createC2()
{
return new C2;
}
auto callMember(alias F, Params...)(__traits(parent, F) obj, Params params)
{
static if(__traits(getFunctionVariadicStyle, F) == "stdarg")
enum varargSuffix = ", ...";
else
enum varargSuffix = "";
static if(is(typeof(&F) R == return) && is(typeof(F) P == __parameters))
mixin("extern(" ~ __traits(getLinkage, F) ~ ") R delegate(P" ~ varargSuffix ~ ") dg;");
dg.funcptr = &F;
dg.ptr = cast(void*)obj;
return dg(params);
}
extern(C++) void runCPPTests();
void main()
{
C1 c1 = createC1();
c1.i = 100;
assert(c1.f0() == 100);
assert(c1.f1(1) == 101);
assert(c1.f2(20, 3) == 123);
assert(c1.f3(20, 3) == 123);
assert(c1.f4(20, 3, 0) == 123);
auto dg0 = &c1.f0;
auto dg1 = &c1.f1;
auto dg2 = &c1.f2;
auto dg3 = &c1.f3;
auto dg4 = &c1.f4;
assert(dg0() == 100);
assert(dg1(1) == 101);
assert(dg2(20, 3) == 123);
assert(dg3(20, 3) == 123);
assert(dg4(20, 3, 0) == 123);
assert(callMember!(C1.f0)(c1) == 100);
assert(callMember!(C1.f1)(c1, 1) == 101);
assert(callMember!(C1.f2)(c1, 20, 3) == 123);
assert(callMember!(C1.f3)(c1, 20, 3) == 123);
assert(callMember!(C1.f4)(c1, 20, 3, 0) == 123);
int i;
extern(C++) void delegate() lamdba1 = () {
i = 5;
};
lamdba1();
assert(i == 5);
extern(C++) int function(int, int) lamdba2 = (int a, int b) {
return a + b;
};
assert(lamdba2(3, 4) == 7);
extern(C++) void delegate(int, ...) lamdba3 = (int a, ...) {
i = a;
int last = a;
va_list argp;
va_start(argp, a);
while (last)
{
last = va_arg!int(argp);
i += last;
}
va_end(argp);
};
lamdba3(1000, 200, 30, 4, 0);
assert(i == 1234);
runCPPTests();
}