1 /** 2 C++ tests that must run 3 */ 4 module it.cpp.run; 5 6 import it; 7 8 @Tags("run") 9 @("ctor") 10 @safe unittest { 11 shouldCompileAndRun( 12 Cpp( 13 q{ 14 struct Struct { 15 void *data; 16 17 Struct(int i); 18 Struct(const Struct&); 19 Struct(Struct&&); 20 21 int number() const; 22 }; 23 } 24 ), 25 Cpp( 26 ` 27 #include <stdio.h> 28 Struct::Struct(int i) { 29 printf("C++: int ctor\n"); 30 data = reinterpret_cast<int*>(new int(i)); 31 } 32 Struct::Struct(const Struct& other) { 33 printf("C++: copy ctor\n"); 34 data = new int(*reinterpret_cast<int*>(other.data)); 35 } 36 Struct::Struct(Struct&& other) { 37 printf("C++: move ctor\n"); 38 printf("other data: %p\n", other.data); 39 printf("as int: %d\n", *((int*)other.data)); 40 data = new int(*reinterpret_cast<int*>(other.data)); 41 } 42 int Struct::number() const { return *reinterpret_cast<int*>(data); } 43 ` 44 ), 45 D( 46 q{ 47 import std.stdio; 48 49 writeln("D: Testing int ctor"); 50 auto s1 = const Struct(42); 51 assert(s1.number() == 42); 52 assert(*(cast(int*)s1.data) == 42); 53 54 writeln("D: Testing copy ctor"); 55 auto s2 = Struct(s1); 56 assert(s2.number() == 42); 57 assert(s1.data !is s2.data); 58 59 // can't test the move ctor since translating it 60 // as taking by value would cause `Struct(s1)` above 61 // to actually move! 62 // writeln("D: Testing move ctor"); 63 // auto s3 = Struct(Struct(33)); 64 // assert(s3.number() == 33); 65 } 66 ), 67 ); 68 } 69 70 71 @Tags("run") 72 @("dtor") 73 @safe unittest { 74 shouldCompileAndRun( 75 Cpp( 76 q{ 77 struct Struct { 78 static int numStructs; 79 Struct(int i); 80 ~Struct(); 81 }; 82 } 83 ), 84 Cpp( 85 q{ 86 int Struct::numStructs; 87 // the i parameter is to force D to call a constructor, 88 // since Struct() just blasts it with Struct.init 89 Struct::Struct(int i) { numStructs += i; } 90 Struct::~Struct() { --numStructs; } 91 } 92 ), 93 D( 94 q{ 95 import std.conv: text; 96 assert(Struct.numStructs == 0, Struct.numStructs.text); 97 { 98 auto s1 = Struct(3); 99 assert(Struct.numStructs == 3, Struct.numStructs.text); 100 101 { 102 auto s2 = Struct(2); 103 assert(Struct.numStructs == 5, Struct.numStructs.text); 104 } 105 106 assert(Struct.numStructs == 4, Struct.numStructs.text); 107 } 108 109 assert(Struct.numStructs == 3, Struct.numStructs.text); 110 } 111 ), 112 ); 113 } 114 115 116 @Tags("run") 117 @("function") 118 @safe unittest { 119 shouldCompileAndRun( 120 Cpp( 121 q{ 122 int add(int i, int j); 123 124 struct Adder { 125 int i; 126 Adder(int i); 127 int add(int j); 128 }; 129 } 130 ), 131 Cpp( 132 q{ 133 int add(int i, int j) { return i + j; } 134 Adder::Adder(int i):i(i + 10) {} 135 int Adder::add(int j) { return i + j; } 136 } 137 ), 138 D( 139 q{ 140 import std.conv: text; 141 import std.exception: assertThrown; 142 import core.exception: AssertError; 143 144 assert(add(2, 3) == 5, "add(2, 3) should be 5"); 145 146 void func() { 147 assert(add(2, 3) == 7); 148 } 149 assertThrown!AssertError(func(), "add(2, 3) should not be 7"); 150 151 auto adder = Adder(3); 152 assert(adder.add(4) == 17, "Adder(3).add(4) should be 17 not " ~ text(adder.add(4))); 153 } 154 ), 155 ); 156 } 157 158 @Tags("run", "collision") 159 @("collisions") 160 @safe unittest { 161 shouldRun( 162 Cpp( 163 q{ 164 struct foo { 165 int i; 166 }; 167 int foo(int i, int j); 168 struct foo add_foo_ptrs(const struct foo* f1, const struct foo* f2); 169 170 union bar { 171 int i; 172 double d; 173 }; 174 int bar(int i); 175 176 enum baz { one, two, three }; 177 int baz(); 178 179 enum other { four, five }; 180 int other; 181 } 182 ), 183 Cpp( 184 q{ 185 int foo(int i, int j) { return i + j + 1; } 186 struct foo add_foo_ptrs(const struct foo* f1, const struct foo* f2) { 187 struct foo ret; 188 ret.i = f1->i + f2->i; 189 return ret; 190 } 191 int bar(int i) { return i * 2; } 192 int baz() { return 42; } 193 } 194 ), 195 D( 196 q{ 197 assert(foo_(2, 3) == 6); 198 assert(bar_(4) == 8); 199 assert(baz_ == 42); 200 201 auto f1 = foo(2); 202 auto f2 = foo(3); 203 assert(add_foo_ptrs(&f1, &f2) == foo(5)); 204 205 bar b; 206 b.i = 42; 207 b.d = 33.3; 208 209 baz z1 = two; 210 baz z2 = baz.one; 211 212 other_ = 77; 213 other o1 = other.four; 214 other o2 = five; 215 216 import std.exception: assertThrown; 217 import core.exception: AssertError; 218 void func() { 219 assert(foo_(2, 3) == 7); 220 } 221 assertThrown!AssertError(func()); 222 } 223 ), 224 ); 225 226 }