1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
|
// 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();
}
|