1 1.1 mrg void main() 2 1.1 mrg { 3 1.1 mrg testKeysValues1(); 4 1.1 mrg testKeysValues2(); 5 1.1 mrg testGet1(); 6 1.1 mrg testGet2(); 7 1.1 mrg testRequire1(); 8 1.1 mrg testRequire2(); 9 1.1 mrg testRequire3(); 10 1.1 mrg testUpdate1(); 11 1.1 mrg testUpdate2(); 12 1.1 mrg testByKey1(); 13 1.1 mrg testByKey2(); 14 1.1 mrg testByKey3(); 15 1.1 mrg testByKey4(); 16 1.1 mrg issue5842(); 17 1.1 mrg issue5842Expanded(); 18 1.1 mrg issue5925(); 19 1.1 mrg issue8583(); 20 1.1 mrg issue9052(); 21 1.1 mrg issue9119(); 22 1.1 mrg issue9852(); 23 1.1 mrg issue10381(); 24 1.1 mrg issue10720(); 25 1.1 mrg issue11761(); 26 1.1 mrg issue13078(); 27 1.1 mrg issue14104(); 28 1.1 mrg issue14626(); 29 1.1 mrg issue15290(); 30 1.1 mrg issue15367(); 31 1.1 mrg issue16974(); 32 1.1 mrg issue18071(); 33 1.1.1.2 mrg issue20440(); 34 1.1.1.2 mrg issue21442(); 35 1.1 mrg testIterationWithConst(); 36 1.1 mrg testStructArrayKey(); 37 1.1 mrg miscTests1(); 38 1.1 mrg miscTests2(); 39 1.1 mrg testRemove(); 40 1.1 mrg testZeroSizedValue(); 41 1.1 mrg testTombstonePurging(); 42 1.1 mrg testClear(); 43 1.1 mrg } 44 1.1 mrg 45 1.1 mrg void testKeysValues1() 46 1.1 mrg { 47 1.1 mrg static struct T 48 1.1 mrg { 49 1.1 mrg byte b; 50 1.1 mrg static size_t count; 51 1.1 mrg this(this) { ++count; } 52 1.1 mrg } 53 1.1 mrg T[int] aa; 54 1.1 mrg T t; 55 1.1 mrg aa[0] = t; 56 1.1 mrg aa[1] = t; 57 1.1 mrg assert(T.count == 2); 58 1.1 mrg auto vals = aa.values; 59 1.1 mrg assert(vals.length == 2); 60 1.1 mrg assert(T.count == 4); 61 1.1 mrg 62 1.1 mrg T.count = 0; 63 1.1 mrg int[T] aa2; 64 1.1 mrg aa2[t] = 0; 65 1.1 mrg assert(T.count == 1); 66 1.1 mrg aa2[t] = 1; 67 1.1 mrg assert(T.count == 1); 68 1.1 mrg auto keys = aa2.keys; 69 1.1 mrg assert(keys.length == 1); 70 1.1 mrg assert(T.count == 2); 71 1.1 mrg } 72 1.1 mrg 73 1.1 mrg void testKeysValues2() nothrow pure 74 1.1 mrg { 75 1.1 mrg int[string] aa; 76 1.1 mrg 77 1.1 mrg assert(aa.keys.length == 0); 78 1.1 mrg assert(aa.values.length == 0); 79 1.1 mrg 80 1.1 mrg aa["hello"] = 3; 81 1.1 mrg assert(aa["hello"] == 3); 82 1.1 mrg aa["hello"]++; 83 1.1 mrg assert(aa["hello"] == 4); 84 1.1 mrg 85 1.1 mrg assert(aa.length == 1); 86 1.1 mrg 87 1.1 mrg string[] keys = aa.keys; 88 1.1 mrg assert(keys.length == 1); 89 1.1 mrg assert(keys[0] == "hello"); 90 1.1 mrg 91 1.1 mrg int[] values = aa.values; 92 1.1 mrg assert(values.length == 1); 93 1.1 mrg assert(values[0] == 4); 94 1.1 mrg 95 1.1 mrg aa.rehash; 96 1.1 mrg assert(aa.length == 1); 97 1.1 mrg assert(aa["hello"] == 4); 98 1.1 mrg 99 1.1 mrg aa["foo"] = 1; 100 1.1 mrg aa["bar"] = 2; 101 1.1 mrg aa["batz"] = 3; 102 1.1 mrg 103 1.1 mrg assert(aa.keys.length == 4); 104 1.1 mrg assert(aa.values.length == 4); 105 1.1 mrg 106 1.1 mrg foreach (a; aa.keys) 107 1.1 mrg { 108 1.1 mrg assert(a.length != 0); 109 1.1 mrg assert(a.ptr != null); 110 1.1 mrg } 111 1.1 mrg 112 1.1 mrg foreach (v; aa.values) 113 1.1 mrg { 114 1.1 mrg assert(v != 0); 115 1.1 mrg } 116 1.1 mrg } 117 1.1 mrg 118 1.1 mrg void testGet1() @safe 119 1.1 mrg { 120 1.1 mrg int[string] aa; 121 1.1 mrg int a; 122 1.1 mrg foreach (val; aa.byKeyValue) 123 1.1 mrg { 124 1.1 mrg ++aa[val.key]; 125 1.1 mrg a = val.value; 126 1.1 mrg } 127 1.1 mrg } 128 1.1 mrg 129 1.1 mrg void testGet2() 130 1.1 mrg { 131 1.1 mrg static class T 132 1.1 mrg { 133 1.1 mrg static size_t count; 134 1.1 mrg this() { ++count; } 135 1.1 mrg } 136 1.1 mrg 137 1.1 mrg T[string] aa; 138 1.1 mrg 139 1.1 mrg auto a = new T; 140 1.1 mrg aa["foo"] = a; 141 1.1 mrg assert(T.count == 1); 142 1.1 mrg auto b = aa.get("foo", new T); 143 1.1 mrg assert(T.count == 1); 144 1.1 mrg assert(b is a); 145 1.1 mrg auto c = aa.get("bar", new T); 146 1.1 mrg assert(T.count == 2); 147 1.1 mrg assert(c !is a); 148 1.1 mrg 149 1.1 mrg //Obviously get doesn't add. 150 1.1 mrg assert("bar" !in aa); 151 1.1 mrg } 152 1.1 mrg 153 1.1 mrg void testRequire1() 154 1.1 mrg { 155 1.1 mrg static class T 156 1.1 mrg { 157 1.1 mrg static size_t count; 158 1.1 mrg this() { ++count; } 159 1.1 mrg } 160 1.1 mrg 161 1.1 mrg T[string] aa; 162 1.1 mrg 163 1.1 mrg auto a = new T; 164 1.1 mrg aa["foo"] = a; 165 1.1 mrg assert(T.count == 1); 166 1.1 mrg auto b = aa.require("foo", new T); 167 1.1 mrg assert(T.count == 1); 168 1.1 mrg assert(b is a); 169 1.1 mrg auto c = aa.require("bar", null); 170 1.1 mrg assert(T.count == 1); 171 1.1 mrg assert(c is null); 172 1.1 mrg assert("bar" in aa); 173 1.1 mrg auto d = aa.require("bar", new T); 174 1.1 mrg assert(d is null); 175 1.1 mrg auto e = aa.require("baz", new T); 176 1.1 mrg assert(T.count == 2); 177 1.1 mrg assert(e !is a); 178 1.1 mrg 179 1.1 mrg assert("baz" in aa); 180 1.1 mrg 181 1.1 mrg bool created = false; 182 1.1 mrg auto f = aa.require("qux", { created = true; return new T; }()); 183 1.1 mrg assert(created == true); 184 1.1 mrg 185 1.1 mrg T g; 186 1.1 mrg auto h = aa.require("qux", { g = new T; return g; }()); 187 1.1 mrg assert(g !is h); 188 1.1 mrg } 189 1.1 mrg 190 1.1 mrg void testRequire2() 191 1.1 mrg { 192 1.1 mrg static struct S 193 1.1 mrg { 194 1.1 mrg int value; 195 1.1 mrg } 196 1.1 mrg 197 1.1 mrg S[string] aa; 198 1.1 mrg 199 1.1 mrg aa.require("foo").value = 1; 200 1.1 mrg assert(aa == ["foo" : S(1)]); 201 1.1 mrg 202 1.1 mrg aa["bar"] = S(2); 203 1.1 mrg auto a = aa.require("bar", S(3)); 204 1.1 mrg assert(a == S(2)); 205 1.1 mrg 206 1.1 mrg auto b = aa["bar"]; 207 1.1 mrg assert(b == S(2)); 208 1.1 mrg 209 1.1 mrg S* c = &aa.require("baz", S(4)); 210 1.1 mrg assert(c is &aa["baz"]); 211 1.1 mrg assert(*c == S(4)); 212 1.1 mrg 213 1.1 mrg assert("baz" in aa); 214 1.1 mrg 215 1.1 mrg auto d = aa["baz"]; 216 1.1 mrg assert(d == S(4)); 217 1.1 mrg } 218 1.1 mrg 219 1.1 mrg void testRequire3() pure 220 1.1 mrg { 221 1.1 mrg string[string] aa; 222 1.1 mrg 223 1.1 mrg auto a = aa.require("foo", "bar"); 224 1.1 mrg assert("foo" in aa); 225 1.1 mrg } 226 1.1 mrg 227 1.1 mrg 228 1.1 mrg void testUpdate1() 229 1.1 mrg { 230 1.1 mrg static class C {} 231 1.1 mrg C[string] aa; 232 1.1 mrg 233 1.1 mrg C orig = new C; 234 1.1 mrg aa["foo"] = orig; 235 1.1 mrg 236 1.1 mrg C newer; 237 1.1 mrg C older; 238 1.1 mrg 239 1.1 mrg void test(string key) 240 1.1 mrg { 241 1.1 mrg aa.update(key, { 242 1.1 mrg newer = new C; 243 1.1 mrg return newer; 244 1.1 mrg }, (ref C c) { 245 1.1 mrg older = c; 246 1.1 mrg newer = new C; 247 1.1 mrg return newer; 248 1.1 mrg }); 249 1.1 mrg } 250 1.1 mrg 251 1.1 mrg test("foo"); 252 1.1 mrg assert(older is orig); 253 1.1 mrg assert(newer is aa["foo"]); 254 1.1 mrg 255 1.1 mrg test("bar"); 256 1.1 mrg assert(newer is aa["bar"]); 257 1.1 mrg } 258 1.1 mrg 259 1.1 mrg void testUpdate2() 260 1.1 mrg { 261 1.1 mrg static class C {} 262 1.1 mrg C[string] aa; 263 1.1 mrg 264 1.1 mrg auto created = false; 265 1.1 mrg auto updated = false; 266 1.1 mrg 267 1.1 mrg class Creator 268 1.1 mrg { 269 1.1 mrg C opCall() 270 1.1 mrg { 271 1.1 mrg created = true; 272 1.1 mrg return new C(); 273 1.1 mrg } 274 1.1 mrg } 275 1.1 mrg 276 1.1 mrg class Updater 277 1.1 mrg { 278 1.1 mrg C opCall(ref C) 279 1.1 mrg { 280 1.1 mrg updated = true; 281 1.1 mrg return new C(); 282 1.1 mrg } 283 1.1 mrg } 284 1.1 mrg 285 1.1 mrg aa.update("foo", new Creator, new Updater); 286 1.1 mrg assert(created); 287 1.1 mrg aa.update("foo", new Creator, new Updater); 288 1.1 mrg assert(updated); 289 1.1 mrg } 290 1.1 mrg 291 1.1.1.2 mrg void testByKey1() @safe 292 1.1 mrg { 293 1.1.1.2 mrg static struct BadValue 294 1.1.1.2 mrg { 295 1.1.1.2 mrg int x; 296 1.1.1.2 mrg this(this) @system { *(cast(ubyte*)(null) + 100000) = 5; } // not @safe 297 1.1.1.2 mrg alias x this; 298 1.1.1.2 mrg } 299 1.1 mrg 300 1.1.1.2 mrg BadValue[int] aa; 301 1.1.1.2 mrg 302 1.1.1.2 mrg // FIXME: Should be @system because of the postblit 303 1.1.1.2 mrg if (false) 304 1.1.1.2 mrg auto x = aa.byKey.front; 305 1.1 mrg } 306 1.1 mrg 307 1.1 mrg void testByKey2() nothrow pure 308 1.1 mrg { 309 1.1 mrg int[int] a; 310 1.1 mrg foreach (i; a.byKey) 311 1.1 mrg { 312 1.1 mrg assert(false); 313 1.1 mrg } 314 1.1 mrg foreach (i; a.byValue) 315 1.1 mrg { 316 1.1 mrg assert(false); 317 1.1 mrg } 318 1.1 mrg } 319 1.1 mrg 320 1.1 mrg void testByKey3() /*nothrow*/ pure 321 1.1 mrg { 322 1.1 mrg auto a = [ 1:"one", 2:"two", 3:"three" ]; 323 1.1 mrg auto b = a.dup; 324 1.1 mrg assert(b == [ 1:"one", 2:"two", 3:"three" ]); 325 1.1 mrg 326 1.1 mrg int[] c; 327 1.1 mrg foreach (k; a.byKey) 328 1.1 mrg { 329 1.1 mrg c ~= k; 330 1.1 mrg } 331 1.1 mrg 332 1.1 mrg assert(c.length == 3); 333 1.1 mrg assert(c[0] == 1 || c[1] == 1 || c[2] == 1); 334 1.1 mrg assert(c[0] == 2 || c[1] == 2 || c[2] == 2); 335 1.1 mrg assert(c[0] == 3 || c[1] == 3 || c[2] == 3); 336 1.1 mrg } 337 1.1 mrg 338 1.1 mrg void testByKey4() nothrow pure 339 1.1 mrg { 340 1.1 mrg string[] keys = ["a", "b", "c", "d", "e", "f"]; 341 1.1 mrg 342 1.1 mrg // Test forward range capabilities of byKey 343 1.1 mrg { 344 1.1 mrg int[string] aa; 345 1.1 mrg foreach (key; keys) 346 1.1 mrg aa[key] = 0; 347 1.1 mrg 348 1.1 mrg auto keyRange = aa.byKey(); 349 1.1 mrg auto savedKeyRange = keyRange.save; 350 1.1 mrg 351 1.1 mrg // Consume key range once 352 1.1 mrg size_t keyCount = 0; 353 1.1 mrg while (!keyRange.empty) 354 1.1 mrg { 355 1.1 mrg aa[keyRange.front]++; 356 1.1 mrg keyCount++; 357 1.1 mrg keyRange.popFront(); 358 1.1 mrg } 359 1.1 mrg 360 1.1 mrg foreach (key; keys) 361 1.1 mrg { 362 1.1 mrg assert(aa[key] == 1); 363 1.1 mrg } 364 1.1 mrg assert(keyCount == keys.length); 365 1.1 mrg 366 1.1 mrg // Verify it's possible to iterate the range the second time 367 1.1 mrg keyCount = 0; 368 1.1 mrg while (!savedKeyRange.empty) 369 1.1 mrg { 370 1.1 mrg aa[savedKeyRange.front]++; 371 1.1 mrg keyCount++; 372 1.1 mrg savedKeyRange.popFront(); 373 1.1 mrg } 374 1.1 mrg 375 1.1 mrg foreach (key; keys) 376 1.1 mrg { 377 1.1 mrg assert(aa[key] == 2); 378 1.1 mrg } 379 1.1 mrg assert(keyCount == keys.length); 380 1.1 mrg } 381 1.1 mrg 382 1.1 mrg // Test forward range capabilities of byValue 383 1.1 mrg { 384 1.1 mrg size_t[string] aa; 385 1.1 mrg foreach (i; 0 .. keys.length) 386 1.1 mrg { 387 1.1 mrg aa[keys[i]] = i; 388 1.1 mrg } 389 1.1 mrg 390 1.1 mrg auto valRange = aa.byValue(); 391 1.1 mrg auto savedValRange = valRange.save; 392 1.1 mrg 393 1.1 mrg // Consume value range once 394 1.1 mrg int[] hasSeen; 395 1.1 mrg hasSeen.length = keys.length; 396 1.1 mrg while (!valRange.empty) 397 1.1 mrg { 398 1.1 mrg assert(hasSeen[valRange.front] == 0); 399 1.1 mrg hasSeen[valRange.front]++; 400 1.1 mrg valRange.popFront(); 401 1.1 mrg } 402 1.1 mrg 403 1.1 mrg foreach (sawValue; hasSeen) { assert(sawValue == 1); } 404 1.1 mrg 405 1.1 mrg // Verify it's possible to iterate the range the second time 406 1.1 mrg hasSeen = null; 407 1.1 mrg hasSeen.length = keys.length; 408 1.1 mrg while (!savedValRange.empty) 409 1.1 mrg { 410 1.1 mrg assert(!hasSeen[savedValRange.front]); 411 1.1 mrg hasSeen[savedValRange.front] = true; 412 1.1 mrg savedValRange.popFront(); 413 1.1 mrg } 414 1.1 mrg 415 1.1 mrg foreach (sawValue; hasSeen) { assert(sawValue); } 416 1.1 mrg } 417 1.1 mrg } 418 1.1 mrg 419 1.1 mrg void issue5842() pure nothrow 420 1.1 mrg { 421 1.1 mrg string[string] test = null; 422 1.1 mrg test["test1"] = "test1"; 423 1.1 mrg test.remove("test1"); 424 1.1 mrg test.rehash; 425 1.1 mrg test["test3"] = "test3"; // causes divide by zero if rehash broke the AA 426 1.1 mrg } 427 1.1 mrg 428 1.1 mrg /// expanded test for 5842: increase AA size past the point where the AA 429 1.1 mrg /// stops using binit, in order to test another code path in rehash. 430 1.1 mrg void issue5842Expanded() pure nothrow 431 1.1 mrg { 432 1.1 mrg int[int] aa; 433 1.1 mrg foreach (int i; 0 .. 32) 434 1.1 mrg aa[i] = i; 435 1.1 mrg foreach (int i; 0 .. 32) 436 1.1 mrg aa.remove(i); 437 1.1 mrg aa.rehash; 438 1.1 mrg aa[1] = 1; 439 1.1 mrg } 440 1.1 mrg 441 1.1 mrg void issue5925() nothrow pure 442 1.1 mrg { 443 1.1 mrg const a = [4:0]; 444 1.1 mrg const b = [4:0]; 445 1.1 mrg assert(a == b); 446 1.1 mrg } 447 1.1 mrg 448 1.1 mrg /// test for bug 8583: ensure Slot and aaA are on the same page wrt value alignment 449 1.1 mrg void issue8583() nothrow pure 450 1.1 mrg { 451 1.1 mrg string[byte] aa0 = [0: "zero"]; 452 1.1 mrg string[uint[3]] aa1 = [[1,2,3]: "onetwothree"]; 453 1.1 mrg ushort[uint[3]] aa2 = [[9,8,7]: 987]; 454 1.1 mrg ushort[uint[4]] aa3 = [[1,2,3,4]: 1234]; 455 1.1 mrg string[uint[5]] aa4 = [[1,2,3,4,5]: "onetwothreefourfive"]; 456 1.1 mrg 457 1.1 mrg assert(aa0.byValue.front == "zero"); 458 1.1 mrg assert(aa1.byValue.front == "onetwothree"); 459 1.1 mrg assert(aa2.byValue.front == 987); 460 1.1 mrg assert(aa3.byValue.front == 1234); 461 1.1 mrg assert(aa4.byValue.front == "onetwothreefourfive"); 462 1.1 mrg } 463 1.1 mrg 464 1.1 mrg void issue9052() nothrow pure 465 1.1 mrg { 466 1.1 mrg static struct Json { 467 1.1 mrg Json[string] aa; 468 1.1 mrg void opAssign(Json) {} 469 1.1 mrg size_t length() const { return aa.length; } 470 1.1 mrg // This length() instantiates AssociativeArray!(string, const(Json)) to call AA.length(), and 471 1.1 mrg // inside ref Slot opAssign(Slot p); (which is automatically generated by compiler in Slot), 472 1.1 mrg // this.value = p.value would actually fail, because both side types of the assignment 473 1.1 mrg // are const(Json). 474 1.1 mrg } 475 1.1 mrg } 476 1.1 mrg 477 1.1 mrg void issue9119() 478 1.1 mrg { 479 1.1 mrg int[string] aa; 480 1.1 mrg assert(aa.byKeyValue.empty); 481 1.1 mrg 482 1.1 mrg aa["a"] = 1; 483 1.1 mrg aa["b"] = 2; 484 1.1 mrg aa["c"] = 3; 485 1.1 mrg 486 1.1 mrg auto pairs = aa.byKeyValue; 487 1.1 mrg 488 1.1 mrg auto savedPairs = pairs.save; 489 1.1 mrg size_t count = 0; 490 1.1 mrg while (!pairs.empty) 491 1.1 mrg { 492 1.1 mrg assert(pairs.front.key in aa); 493 1.1 mrg assert(pairs.front.value == aa[pairs.front.key]); 494 1.1 mrg count++; 495 1.1 mrg pairs.popFront(); 496 1.1 mrg } 497 1.1 mrg assert(count == aa.length); 498 1.1 mrg 499 1.1 mrg // Verify that saved range can iterate over the AA again 500 1.1 mrg count = 0; 501 1.1 mrg while (!savedPairs.empty) 502 1.1 mrg { 503 1.1 mrg assert(savedPairs.front.key in aa); 504 1.1 mrg assert(savedPairs.front.value == aa[savedPairs.front.key]); 505 1.1 mrg count++; 506 1.1 mrg savedPairs.popFront(); 507 1.1 mrg } 508 1.1 mrg assert(count == aa.length); 509 1.1 mrg } 510 1.1 mrg 511 1.1 mrg void issue9852() nothrow pure 512 1.1 mrg { 513 1.1 mrg // Original test case (revised, original assert was wrong) 514 1.1 mrg int[string] a; 515 1.1 mrg a["foo"] = 0; 516 1.1 mrg a.remove("foo"); 517 1.1 mrg assert(a == null); // should not crash 518 1.1 mrg 519 1.1 mrg int[string] b; 520 1.1 mrg assert(b is null); 521 1.1 mrg assert(a == b); // should not deref null 522 1.1 mrg assert(b == a); // ditto 523 1.1 mrg 524 1.1 mrg int[string] c; 525 1.1 mrg c["a"] = 1; 526 1.1 mrg assert(a != c); // comparison with empty non-null AA 527 1.1 mrg assert(c != a); 528 1.1 mrg assert(b != c); // comparison with null AA 529 1.1 mrg assert(c != b); 530 1.1 mrg } 531 1.1 mrg 532 1.1 mrg void issue10381() 533 1.1 mrg { 534 1.1 mrg alias II = int[int]; 535 1.1 mrg II aa1 = [0 : 1]; 536 1.1 mrg II aa2 = [0 : 1]; 537 1.1 mrg II aa3 = [0 : 2]; 538 1.1 mrg assert(aa1 == aa2); // Passes 539 1.1 mrg assert(typeid(II).equals(&aa1, &aa2)); 540 1.1 mrg assert(!typeid(II).equals(&aa1, &aa3)); 541 1.1 mrg } 542 1.1 mrg 543 1.1 mrg void issue10720() nothrow pure 544 1.1 mrg { 545 1.1 mrg static struct NC 546 1.1 mrg { 547 1.1 mrg @disable this(this) { } 548 1.1 mrg } 549 1.1 mrg 550 1.1 mrg NC[string] aa; 551 1.1 mrg static assert(!is(aa.nonExistingField)); 552 1.1 mrg } 553 1.1 mrg 554 1.1 mrg /// bug 11761: test forward range functionality 555 1.1 mrg void issue11761() pure nothrow 556 1.1 mrg { 557 1.1 mrg auto aa = ["a": 1]; 558 1.1 mrg 559 1.1 mrg void testFwdRange(R, T)(R fwdRange, T testValue) 560 1.1 mrg { 561 1.1 mrg assert(!fwdRange.empty); 562 1.1 mrg assert(fwdRange.front == testValue); 563 1.1 mrg static assert(is(typeof(fwdRange.save) == typeof(fwdRange))); 564 1.1 mrg 565 1.1 mrg auto saved = fwdRange.save; 566 1.1 mrg fwdRange.popFront(); 567 1.1 mrg assert(fwdRange.empty); 568 1.1 mrg 569 1.1 mrg assert(!saved.empty); 570 1.1 mrg assert(saved.front == testValue); 571 1.1 mrg saved.popFront(); 572 1.1 mrg assert(saved.empty); 573 1.1 mrg } 574 1.1 mrg 575 1.1 mrg testFwdRange(aa.byKey, "a"); 576 1.1 mrg testFwdRange(aa.byValue, 1); 577 1.1 mrg //testFwdRange(aa.byPair, tuple("a", 1)); 578 1.1 mrg } 579 1.1 mrg 580 1.1 mrg void issue13078() nothrow pure 581 1.1 mrg { 582 1.1 mrg shared string[][string] map; 583 1.1 mrg map.rehash; 584 1.1 mrg } 585 1.1 mrg 586 1.1 mrg void issue14104() 587 1.1 mrg { 588 1.1 mrg import core.stdc.stdio; 589 1.1 mrg 590 1.1 mrg alias K = const(ubyte)*; 591 1.1 mrg size_t[K] aa; 592 1.1 mrg immutable key = cast(K)(cast(size_t) uint.max + 1); 593 1.1 mrg aa[key] = 12; 594 1.1 mrg assert(key in aa); 595 1.1 mrg } 596 1.1 mrg 597 1.1 mrg void issue14626() 598 1.1 mrg { 599 1.1 mrg static struct S 600 1.1 mrg { 601 1.1 mrg string[string] aa; 602 1.1 mrg inout(string) key() inout { return aa.byKey().front; } 603 1.1 mrg inout(string) val() inout { return aa.byValue().front; } 604 1.1 mrg auto keyval() inout { return aa.byKeyValue().front; } 605 1.1 mrg } 606 1.1 mrg 607 1.1 mrg S s = S(["a":"b"]); 608 1.1 mrg assert(s.key() == "a"); 609 1.1 mrg assert(s.val() == "b"); 610 1.1 mrg assert(s.keyval().key == "a"); 611 1.1 mrg assert(s.keyval().value == "b"); 612 1.1 mrg 613 1.1 mrg void testInoutKeyVal(inout(string) key) 614 1.1 mrg { 615 1.1 mrg inout(string)[typeof(key)] aa; 616 1.1 mrg 617 1.1 mrg foreach (i; aa.byKey()) {} 618 1.1 mrg foreach (i; aa.byValue()) {} 619 1.1 mrg foreach (i; aa.byKeyValue()) {} 620 1.1 mrg } 621 1.1 mrg 622 1.1 mrg const int[int] caa; 623 1.1 mrg static assert(is(typeof(caa.byValue().front) == const int)); 624 1.1 mrg } 625 1.1 mrg 626 1.1 mrg /// test duplicated keys in AA literal 627 1.1 mrg /// https://issues.dlang.org/show_bug.cgi?id=15290 628 1.1 mrg void issue15290() 629 1.1 mrg { 630 1.1 mrg string[int] aa = [ 0: "a", 0: "b" ]; 631 1.1 mrg assert(aa.length == 1); 632 1.1 mrg assert(aa.keys == [ 0 ]); 633 1.1 mrg } 634 1.1 mrg 635 1.1 mrg void issue15367() 636 1.1 mrg { 637 1.1 mrg void f1() {} 638 1.1 mrg void f2() {} 639 1.1 mrg 640 1.1 mrg // TypeInfo_Delegate.getHash 641 1.1 mrg int[void delegate()] aa; 642 1.1 mrg assert(aa.length == 0); 643 1.1 mrg aa[&f1] = 1; 644 1.1 mrg assert(aa.length == 1); 645 1.1 mrg aa[&f1] = 1; 646 1.1 mrg assert(aa.length == 1); 647 1.1 mrg 648 1.1 mrg auto a1 = [&f2, &f1]; 649 1.1 mrg auto a2 = [&f2, &f1]; 650 1.1 mrg 651 1.1 mrg // TypeInfo_Delegate.equals 652 1.1 mrg for (auto i = 0; i < 2; i++) 653 1.1 mrg assert(a1[i] == a2[i]); 654 1.1 mrg assert(a1 == a2); 655 1.1 mrg 656 1.1 mrg // TypeInfo_Delegate.compare 657 1.1 mrg for (auto i = 0; i < 2; i++) 658 1.1 mrg assert(a1[i] <= a2[i]); 659 1.1 mrg assert(a1 <= a2); 660 1.1 mrg } 661 1.1 mrg 662 1.1 mrg /// test AA as key 663 1.1 mrg /// https://issues.dlang.org/show_bug.cgi?id=16974 664 1.1 mrg void issue16974() 665 1.1 mrg { 666 1.1 mrg int[int] a = [1 : 2], a2 = [1 : 2]; 667 1.1 mrg 668 1.1 mrg assert([a : 3] == [a : 3]); 669 1.1 mrg assert([a : 3] == [a2 : 3]); 670 1.1 mrg 671 1.1 mrg assert(typeid(a).getHash(&a) == typeid(a).getHash(&a)); 672 1.1 mrg assert(typeid(a).getHash(&a) == typeid(a).getHash(&a2)); 673 1.1 mrg } 674 1.1 mrg 675 1.1 mrg /// test safety for alias-this'd AA that have unsafe opCast 676 1.1 mrg /// https://issues.dlang.org/show_bug.cgi?id=18071 677 1.1 mrg void issue18071() 678 1.1 mrg { 679 1.1 mrg static struct Foo 680 1.1 mrg { 681 1.1 mrg int[int] aa; 682 1.1 mrg auto opCast() pure nothrow @nogc 683 1.1 mrg { 684 1.1 mrg *cast(uint*)0xdeadbeef = 0xcafebabe;// unsafe 685 1.1 mrg return null; 686 1.1 mrg } 687 1.1 mrg alias aa this; 688 1.1 mrg } 689 1.1 mrg 690 1.1 mrg Foo f; 691 1.1 mrg () @safe { assert(f.byKey.empty); }(); 692 1.1 mrg } 693 1.1 mrg 694 1.1.1.2 mrg /// Test that `require` works even with types whose opAssign 695 1.1.1.2 mrg /// doesn't return a reference to the receiver. 696 1.1.1.2 mrg /// https://issues.dlang.org/show_bug.cgi?id=20440 697 1.1.1.2 mrg void issue20440() @safe 698 1.1.1.2 mrg { 699 1.1.1.2 mrg static struct S 700 1.1.1.2 mrg { 701 1.1.1.2 mrg int value; 702 1.1.1.2 mrg auto opAssign(S s) { 703 1.1.1.2 mrg this.value = s.value; 704 1.1.1.2 mrg return this; 705 1.1.1.2 mrg } 706 1.1.1.2 mrg } 707 1.1.1.2 mrg S[S] aa; 708 1.1.1.2 mrg assert(aa.require(S(1), S(2)) == S(2)); 709 1.1.1.2 mrg assert(aa[S(1)] == S(2)); 710 1.1.1.2 mrg } 711 1.1.1.2 mrg 712 1.1.1.2 mrg /// 713 1.1.1.2 mrg void issue21442() 714 1.1.1.2 mrg { 715 1.1.1.2 mrg import core.memory; 716 1.1.1.2 mrg 717 1.1.1.2 mrg size_t[size_t] glob; 718 1.1.1.2 mrg 719 1.1.1.2 mrg class Foo 720 1.1.1.2 mrg { 721 1.1.1.2 mrg size_t count; 722 1.1.1.2 mrg 723 1.1.1.2 mrg this (size_t entries) @safe 724 1.1.1.2 mrg { 725 1.1.1.2 mrg this.count = entries; 726 1.1.1.2 mrg foreach (idx; 0 .. entries) 727 1.1.1.2 mrg glob[idx] = idx; 728 1.1.1.2 mrg } 729 1.1.1.2 mrg 730 1.1.1.2 mrg ~this () @safe 731 1.1.1.2 mrg { 732 1.1.1.2 mrg foreach (idx; 0 .. this.count) 733 1.1.1.2 mrg glob.remove(idx); 734 1.1.1.2 mrg } 735 1.1.1.2 mrg } 736 1.1.1.2 mrg 737 1.1.1.2 mrg void bar () @safe 738 1.1.1.2 mrg { 739 1.1.1.2 mrg Foo f = new Foo(16); 740 1.1.1.2 mrg } 741 1.1.1.2 mrg 742 1.1.1.2 mrg bar(); 743 1.1.1.2 mrg GC.collect(); // Needs to happen from a GC collection 744 1.1.1.2 mrg } 745 1.1.1.2 mrg 746 1.1 mrg /// Verify iteration with const. 747 1.1 mrg void testIterationWithConst() 748 1.1 mrg { 749 1.1 mrg auto aa = [1:2, 3:4]; 750 1.1 mrg foreach (const t; aa.byKeyValue) 751 1.1 mrg { 752 1.1 mrg auto k = t.key; 753 1.1 mrg auto v = t.value; 754 1.1 mrg } 755 1.1 mrg } 756 1.1 mrg 757 1.1 mrg void testStructArrayKey() @safe 758 1.1 mrg { 759 1.1 mrg struct S 760 1.1 mrg { 761 1.1 mrg int i; 762 1.1 mrg const @safe nothrow: 763 1.1 mrg hash_t toHash() { return 0; } 764 1.1 mrg bool opEquals(const S) { return true; } 765 1.1 mrg int opCmp(const S) { return 0; } 766 1.1 mrg } 767 1.1 mrg 768 1.1 mrg int[S[]] aa = [[S(11)] : 13]; 769 1.1 mrg assert(aa[[S(12)]] == 13); 770 1.1 mrg } 771 1.1 mrg 772 1.1 mrg void miscTests1() pure nothrow 773 1.1 mrg { 774 1.1 mrg string[int] key1 = [1 : "true", 2 : "false"]; 775 1.1 mrg string[int] key2 = [1 : "false", 2 : "true"]; 776 1.1 mrg string[int] key3; 777 1.1 mrg 778 1.1 mrg // AA lits create a larger hashtable 779 1.1 mrg int[string[int]] aa1 = [key1 : 100, key2 : 200, key3 : 300]; 780 1.1 mrg 781 1.1 mrg // Ensure consistent hash values are computed for key1 782 1.1 mrg assert((key1 in aa1) !is null); 783 1.1 mrg 784 1.1 mrg // Manually assigning to an empty AA creates a smaller hashtable 785 1.1 mrg int[string[int]] aa2; 786 1.1 mrg aa2[key1] = 100; 787 1.1 mrg aa2[key2] = 200; 788 1.1 mrg aa2[key3] = 300; 789 1.1 mrg 790 1.1 mrg assert(aa1 == aa2); 791 1.1 mrg 792 1.1 mrg // Ensure binary-independence of equal hash keys 793 1.1 mrg string[int] key2a; 794 1.1 mrg key2a[1] = "false"; 795 1.1 mrg key2a[2] = "true"; 796 1.1 mrg 797 1.1 mrg assert(aa1[key2a] == 200); 798 1.1 mrg } 799 1.1 mrg 800 1.1 mrg void miscTests2() 801 1.1 mrg { 802 1.1 mrg int[int] aa; 803 1.1 mrg foreach (k, v; aa) 804 1.1 mrg assert(false); 805 1.1 mrg foreach (v; aa) 806 1.1 mrg assert(false); 807 1.1 mrg assert(aa.byKey.empty); 808 1.1 mrg assert(aa.byValue.empty); 809 1.1 mrg assert(aa.byKeyValue.empty); 810 1.1 mrg 811 1.1 mrg size_t n; 812 1.1 mrg aa = [0 : 3, 1 : 4, 2 : 5]; 813 1.1 mrg foreach (k, v; aa) 814 1.1 mrg { 815 1.1 mrg n += k; 816 1.1 mrg assert(k >= 0 && k < 3); 817 1.1 mrg assert(v >= 3 && v < 6); 818 1.1 mrg } 819 1.1 mrg assert(n == 3); 820 1.1 mrg n = 0; 821 1.1 mrg 822 1.1 mrg foreach (v; aa) 823 1.1 mrg { 824 1.1 mrg n += v; 825 1.1 mrg assert(v >= 3 && v < 6); 826 1.1 mrg } 827 1.1 mrg assert(n == 12); 828 1.1 mrg 829 1.1 mrg n = 0; 830 1.1 mrg foreach (k, v; aa) 831 1.1 mrg { 832 1.1 mrg ++n; 833 1.1 mrg break; 834 1.1 mrg } 835 1.1 mrg assert(n == 1); 836 1.1 mrg 837 1.1 mrg n = 0; 838 1.1 mrg foreach (v; aa) 839 1.1 mrg { 840 1.1 mrg ++n; 841 1.1 mrg break; 842 1.1 mrg } 843 1.1 mrg assert(n == 1); 844 1.1 mrg } 845 1.1 mrg 846 1.1 mrg void testRemove() 847 1.1 mrg { 848 1.1 mrg int[int] aa; 849 1.1 mrg assert(!aa.remove(0)); 850 1.1 mrg aa = [0 : 1]; 851 1.1 mrg assert(aa.remove(0)); 852 1.1 mrg assert(!aa.remove(0)); 853 1.1 mrg aa[1] = 2; 854 1.1 mrg assert(!aa.remove(0)); 855 1.1 mrg assert(aa.remove(1)); 856 1.1 mrg 857 1.1 mrg assert(aa.length == 0); 858 1.1 mrg assert(aa.byKey.empty); 859 1.1 mrg } 860 1.1 mrg 861 1.1 mrg /// test zero sized value (hashset) 862 1.1 mrg void testZeroSizedValue() 863 1.1 mrg { 864 1.1 mrg alias V = void[0]; 865 1.1 mrg auto aa = [0 : V.init]; 866 1.1 mrg assert(aa.length == 1); 867 1.1 mrg assert(aa.byKey.front == 0); 868 1.1 mrg assert(aa.byValue.front == V.init); 869 1.1 mrg aa[1] = V.init; 870 1.1 mrg assert(aa.length == 2); 871 1.1 mrg aa[0] = V.init; 872 1.1 mrg assert(aa.length == 2); 873 1.1 mrg assert(aa.remove(0)); 874 1.1 mrg aa[0] = V.init; 875 1.1 mrg assert(aa.length == 2); 876 1.1 mrg assert(aa == [0 : V.init, 1 : V.init]); 877 1.1 mrg } 878 1.1 mrg 879 1.1 mrg void testTombstonePurging() 880 1.1 mrg { 881 1.1 mrg int[int] aa; 882 1.1 mrg foreach (i; 0 .. 6) 883 1.1 mrg aa[i] = i; 884 1.1 mrg foreach (i; 0 .. 6) 885 1.1 mrg assert(aa.remove(i)); 886 1.1 mrg foreach (i; 6 .. 10) 887 1.1 mrg aa[i] = i; 888 1.1 mrg assert(aa.length == 4); 889 1.1 mrg foreach (i; 6 .. 10) 890 1.1 mrg assert(i in aa); 891 1.1 mrg } 892 1.1 mrg 893 1.1 mrg void testClear() 894 1.1 mrg { 895 1.1 mrg int[int] aa; 896 1.1 mrg assert(aa.length == 0); 897 1.1 mrg foreach (i; 0 .. 100) 898 1.1 mrg aa[i] = i * 2; 899 1.1 mrg assert(aa.length == 100); 900 1.1 mrg auto aa2 = aa; 901 1.1 mrg assert(aa2.length == 100); 902 1.1 mrg aa.clear(); 903 1.1 mrg assert(aa.length == 0); 904 1.1 mrg assert(aa2.length == 0); 905 1.1 mrg 906 1.1 mrg aa2[5] = 6; 907 1.1 mrg assert(aa.length == 1); 908 1.1 mrg assert(aa[5] == 6); 909 1.1 mrg } 910