1
module ut.vector;
2

3

4
import ut;
5
import automem.vector;
6
import std.experimental.allocator.mallocator: Mallocator;
7
import test_allocator;
8

9

10
@("length")
11
@safe unittest {
12 4
    vector("foo", "bar", "baz").length.should == 3;
13 4
    vector("quux", "toto").length.should == 2;
14
}
15

16
@("vector.int")
17
@safe unittest {
18 4
    vector(1, 2, 3, 4, 5).range.should == [1, 2, 3, 4, 5];
19 4
    vector(2, 3, 4).range.should == [2, 3, 4];
20 4
    vector(2, 3, 4).range.should == [2, 3, 4];
21
}
22

23
@("vector.double")
24
@safe unittest {
25 4
    vector(33.3).range.should == [33.3];
26 4
    vector(22.2, 77.7).range.should == [22.2, 77.7];
27
}
28

29
@("copying")
30
@safe unittest {
31 4
    auto vec1 = vector(1, 2, 3);
32 4
    () @trusted { vec1.reserve(10); }();
33 4
    auto vec2 = vec1;
34 4
    vec1[1] = 7;
35

36 4
    vec1.range.should == [1, 7, 3];
37 4
    vec2.range.should == [1, 2, 3];
38
}
39

40
@("bounds check")
41
@safe unittest {
42

43 4
    auto vec = vector(1, 2, 3);
44 4
    () @trusted { vec.reserve(10); }();
45 4
    vec[3].shouldThrow!BoundsException;
46 4
    vec[-1].shouldThrow!BoundsException;
47 4
    () @trusted { vec[0 .. 4].shouldThrow!BoundsException; }();
48 4
    () @trusted { vec[0.. 3]; }(); // shouldn't throw (see #45)
49
}
50

51
@("extend")
52
@system unittest {
53
    import std.algorithm: map;
54

55 4
    auto vec = vector(0, 1, 2, 3);
56

57 4
    vec ~= 4;
58 4
    vec.range.should == [0, 1, 2, 3, 4];
59

60 4
    vec ~= [5, 6];
61 4
    vec.range.should == [0, 1, 2, 3, 4, 5, 6];
62

63 4
    vec ~= [1, 2].map!(a => a + 10);
64 4
    vec.range.should == [0, 1, 2, 3, 4, 5, 6, 11, 12];
65
}
66

67

68
@("put")
69
@system unittest {
70
    import std.range: iota;
71

72 4
    auto vec = vector(0, 1, 2, 3);
73 4
    vec.put(4);
74 4
    vec.range.should == [0, 1, 2, 3, 4];
75 4
    vec.put(2.iota);
76 4
    vec.range.should == [0, 1, 2, 3, 4, 0, 1];
77
}
78

79
@("append")
80
@system unittest {
81 4
    auto vec1 = vector(0, 1, 2);
82 4
    auto vec2 = vector(3, 4);
83

84 4
    auto vec3 =  vec1 ~ vec2;
85 4
    vec3.range.should == [0, 1, 2, 3, 4];
86

87 4
    vec1[0] = 7;
88 4
    vec2[0] = 9;
89 4
    vec3.range.should == [0, 1, 2, 3, 4];
90

91

92
    // make sure capacity is larger
93 4
    vec1 ~= 100;
94 4
    vec1.capacity.shouldBeGreaterThan(vec1.length);
95 4
    vec1.range.should == [7, 1, 2, 100];
96

97 4
    vec2 ~= 200;
98 4
    vec2.capacity.shouldBeGreaterThan(vec2.length);
99 4
    vec2.range.should == [9, 4, 200];
100

101 4
    (vec1 ~ vec2).range.should == [7, 1, 2, 100, 9, 4, 200];
102 4
    (vec1 ~ vector(11, 12, 13, 14, 15)).range.should == [7, 1, 2, 100, 11, 12, 13, 14, 15];
103
}
104

105
@("slice")
106
@system unittest {
107 4
    const vec = vector(0, 1, 2, 3, 4, 5);
108 4
    vec[].should == [0, 1, 2, 3, 4, 5];
109 4
    vec[1 .. 3].should == [1, 2];
110 4
    vec[1 .. 4].should == [1, 2, 3];
111 4
    vec[2 .. 5].should == [2, 3, 4];
112 4
    vec[1 .. $ - 1].should == [1, 2, 3, 4];
113 4
    vec[0 .. 6].should == [0, 1, 2, 3, 4, 5];
114
}
115

116
@("opDollar")
117
@system unittest {
118 4
    auto vec = vector(0, 1, 2, 3, 4);
119 4
    vec ~= 5;
120 4
    vec ~= 6;
121 4
    vec.capacity.shouldBeGreaterThan(vec.length);
122

123 4
    vec[1 .. $ - 1].should == [1, 2, 3, 4, 5];
124
}
125

126
@("assign")
127
@system unittest {
128
    import std.range: iota;
129 4
    auto vec = vector(10, 11, 12);
130 4
    vec = 5.iota;
131 4
    vec.range.should == [0, 1, 2, 3, 4];
132
}
133

134
@("construct from range")
135
@safe unittest {
136
    import std.range: iota;
137 4
    vector(5.iota).range.should == [0, 1, 2, 3, 4];
138
}
139

140

141
@("popBack")
142
@safe unittest {
143 4
    auto vec = vector(0, 1, 2);
144 4
    vec.popBack;
145 4
    vec.range.should == [0, 1];
146
}
147

148
@("popFront")
149
@safe unittest {
150 4
    auto vec = vector(0, 1, 2, 3, 4);
151 4
    vec.popFront;
152 4
    vec.range.should == [1, 2, 3, 4];
153 4
    vec.empty.shouldBeFalse;
154

155 4
    foreach(i; 0 ..  vec.length) vec.popFront;
156 4
    vec.empty.shouldBeTrue;
157
}
158

159

160
@("opSliceAssign")
161
@safe unittest {
162 4
    auto vec = vector("foo", "bar", "quux", "toto");
163

164 4
    vec[] = "haha";
165 4
    vec.range.should == ["haha", "haha", "haha", "haha"];
166

167 4
    vec[1..3] = "oops";
168 4
    vec.range.should == ["haha", "oops", "oops", "haha"];
169
}
170

171
@("opSliceOpAssign")
172
@safe unittest {
173 4
    auto vec = vector("foo", "bar", "quux", "toto");
174 4
    vec[] ~= "oops";
175 4
    vec.range.should == ["foooops", "baroops", "quuxoops", "totooops"];
176
}
177

178
@("opSliceOpAssign range")
179
@safe unittest {
180 4
    auto vec = vector("foo", "bar", "quux", "toto");
181 4
    vec[1..3] ~= "oops";
182 4
    vec.range.should == ["foo", "baroops", "quuxoops", "toto"];
183
}
184

185
@("clear")
186
@safe unittest {
187 4
    auto vec = vector(0, 1, 2, 3);
188 4
    vec.clear;
189 4
    int[] empty;
190 4
    vec.range.should ==(empty);
191
}
192

193

194
@("Mallocator elements")
195
@safe @nogc unittest {
196
    import std.algorithm: equal;
197 4
    auto vec = vector!Mallocator(0, 1, 2, 3);
198 4
    int[4] exp = [0, 1, 2, 3];
199 4
    assert(equal(vec.range, exp[]));
200
}
201

202
@("Mallocator range")
203
@safe @nogc unittest {
204
    import std.algorithm: equal;
205
    import std.range: iota;
206 4
    auto vec = vector!Mallocator(iota(5));
207 4
    int[5] exp = [0, 1, 2, 3, 4];
208 4
    assert(equal(vec.range, exp[]));
209
}
210

211

212
@("theAllocator null")
213
@safe unittest {
214 4
    Vector!int vec;
215
}
216

217

218
@("Mallocator null")
219
@safe @nogc unittest {
220 4
    Vector!(int, Mallocator) vec;
221
}
222

223

224
@("escape.range")
225
@safe @nogc unittest {
226

227
    alias Ints = typeof(Vector!(int, Mallocator).init.range());
228

229 4
    Ints ints1;
230 4
    scope vec = vector!Mallocator(0, 1, 2, 3);
231 4
    Ints ints2;
232

233
    static assert(!__traits(compiles, ints1 = vec.range));
234 4
    ints2 = vec.range;  // should compile
235
}
236

237

238
@("escape.element")
239
@safe unittest {
240

241 4
    int i = 1;
242 4
    int j = 2;
243

244 4
    int* oops;
245 4
    scope vec = vector(&i, &j);
246 4
    int* ok;
247

248
    static assert(!__traits(compiles, oops = vec[0]));
249 4
    ok = vec[0];
250
}
251

252

253
@("TestAllocator elements capacity")
254
@system unittest {
255
    static TestAllocator allocator;
256

257 4
    auto vec = vector(&allocator, 0, 1, 2);
258 4
    vec.range.should == [0, 1, 2];
259

260 4
    vec ~= 3;
261 4
    vec ~= 4;
262 4
    vec ~= 5;
263 4
    vec ~= 6;
264 4
    vec ~= 7;
265 4
    vec ~= 8;
266

267 4
    vec.range.should == [0, 1, 2, 3, 4, 5, 6, 7, 8];
268 4
    allocator.numAllocations.shouldBeSmallerThan(4);
269
}
270

271
@("TestAllocator reserve")
272
@system unittest {
273
    static TestAllocator allocator;
274

275 4
    auto vec = vector!(TestAllocator*, int)(&allocator);
276

277 4
    vec.reserve(5);
278 4
    () @trusted { vec.empty.should == true; }();
279

280 4
    vec ~= 0;
281 4
    vec ~= 1;
282 4
    vec ~= 2;
283 4
    vec ~= 3;
284 4
    vec ~= 4;
285

286 4
    vec.range.should == [0, 1, 2, 3, 4];
287 4
    allocator.numAllocations.should == 1;
288

289 4
    vec ~= 5;
290 4
    vec.range.should == [0, 1, 2, 3, 4, 5];
291 4
    allocator.numAllocations.should == 2;
292
}
293

294
@("TestAllocator shrink no length")
295
@system unittest {
296
    static TestAllocator allocator;
297

298 4
    auto vec = vector!(TestAllocator*, int)(&allocator);
299 4
    vec.reserve(10);
300

301 4
    vec ~= 0;
302 4
    vec ~= 1;
303 4
    vec ~= 2;
304 4
    vec ~= 3;
305

306 4
    vec.length.should == 4;
307 4
    vec.capacity.should == 10;
308

309 4
    vec.shrink;
310 4
    vec.length.should == 4;
311 4
    vec.capacity.should == 4;
312
}
313

314
@("TestAllocator shrink negative number")
315
@system unittest {
316
    static TestAllocator allocator;
317

318 4
    auto vec = vector(&allocator, 0);
319 4
    vec ~= 1;
320 4
    vec ~= 2;
321 4
    vec ~= 3;
322 4
    vec.capacity.shouldBeGreaterThan(vec.length);
323 4
    const oldCapacity = vec.capacity;
324

325 4
    vec.shrink(-1).shouldBeFalse;
326 4
    vec.capacity.should == oldCapacity;
327
}
328

329
@("TestAllocator shrink larger than capacity")
330
@system unittest {
331
    static TestAllocator allocator;
332

333 4
    auto vec = vector(&allocator, 0);
334 4
    vec ~= 1;
335 4
    vec ~= 2;
336 4
    vec ~= 3;
337 4
    vec.capacity.shouldBeGreaterThan(vec.length);
338 4
    const oldCapacity = vec.capacity;
339

340 4
    vec.shrink(oldCapacity * 2).shouldBeFalse;
341 4
    vec.capacity.should == oldCapacity;
342
}
343

344

345
@("TestAllocator shrink with length")
346
@system unittest {
347
    static TestAllocator allocator;
348

349 4
    auto vec = vector(&allocator, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
350 4
    vec.capacity.should == 10;
351

352 4
    vec.shrink(5);
353 4
    vec.range.should == [0, 1, 2, 3, 4];
354 4
    vec.capacity.should == 5;
355

356 4
    vec ~= 5;
357 4
    vec.range.should == [0, 1, 2, 3, 4, 5];
358 4
    allocator.numAllocations.should == 3;
359

360 4
    vec.reserve(10);
361 4
    vec.length.should == 6;
362 4
    vec.capacity.shouldBeGreaterThan(6);
363
}
364

365
@("TestAllocator copy")
366
@safe unittest {
367
    static TestAllocator allocator;
368

369 4
    auto vec1 = vector(&allocator, "foo", "bar", "baz");
370 4
    allocator.numAllocations.should == 1;
371

372 4
    auto vec2 = vec1;
373 4
    allocator.numAllocations.should == 2;
374
}
375

376
@("TestAllocator move")
377
@safe unittest {
378
    static TestAllocator allocator;
379

380 4
    auto vec = vector(&allocator, "foo", "bar", "baz");
381 4
    allocator.numAllocations.should == 1;
382

383 4
    consumeVec(vec);
384 4
    allocator.numAllocations.should == 1;
385
}
386

387

388
private void consumeVec(T)(auto ref T vec) {
389

390
}
391

392

393
@("set length")
394
@system unittest {
395 4
    Vector!int vec;
396 4
    vec.length = 3;
397 4
    vec.range.should == [0, 0, 0];
398
}
399

400

401
@("foreach")
402
@safe unittest {
403 4
    foreach(e; vector(7, 7, 7).range) {
404 0
        e.should == 7;
405
    }
406
}
407

408

409
@("equal")
410
@safe unittest {
411
    import std.range: iota;
412
    import std.algorithm: equal;
413

414 4
    auto v = vector(0, 1, 2, 3);
415 4
    assert(equal(v.range, 4.iota));
416
}
417

418

419
@("bool")
420
@safe unittest {
421 4
    vector(0, 1, 2).shouldBeTrue;
422 4
    Vector!int v;
423 4
    if(v) {
424 0
        assert(0);
425
    }
426
}
427

428
@("char")
429
@system unittest {
430
    {
431 4
        auto vec = vector('f', 'o', 'o');
432 4
        vec.range.should ==("foo");
433 4
        vec ~= 'b';
434 4
        vec ~= ['a', 'r'];
435 4
        vec.range.should ==("foobar");
436 4
        vec ~= "quux";
437 4
        vec.range.should ==("foobarquux");
438
    }
439

440
    {
441 4
        auto vec = vector("foo");
442 4
        vec.range.should ==("foo");
443 4
        vec.popBack;
444 4
        vec.range.should ==("fo");
445
    }
446

447
    {
448 4
        auto vec = vector("foo");
449 4
        vec ~= "bar";
450 4
        vec.range.should ==("foobar");
451
    }
452
}
453

454

455
@("immutable.append")
456
@system unittest {
457 4
    Vector!(immutable int) vec;
458 4
    vec ~= 42;
459 4
    vec.range.should == [42];
460
}
461

462

463
@("String")
464
@safe unittest {
465 4
    foreach(c; String("oooooo").range)
466 0
        c.should == 'o';
467
}
468

469
@("stringz")
470
@safe unittest {
471
    import std.string: fromStringz;
472 4
    auto str = vector("foobar");
473 4
    const strz = () @trusted { return str.stringz; }();
474 4
    const back = () @trusted { return fromStringz(strz); }();
475 4
    back.should == "foobar";
476 4
    str.range.should ==("foobar");
477
}
478

479

480
@("ptr")
481
@safe unittest {
482 4
    const vec = vector(0, 1, 2, 3);
483 4
    takesScopePtr(vec.ptr);
484 4
    () @trusted { vec.ptr[1].should == 1; }();
485
}
486

487
private void takesScopePtr(T)(scope const(T)* ptr) {
488

489
}
490

491

492
@("StackFront")
493
@safe @nogc unittest {
494
    import std.algorithm: equal;
495
    import std.experimental.allocator.showcase: StackFront;
496
    import std.experimental.allocator.mallocator: Mallocator;
497

498
    alias Allocator = StackFront!(1024, Mallocator);
499

500
    {
501 4
        Vector!(int, Allocator) v;
502 4
        () @trusted { v ~= 1; }();
503
        {
504 4
            int[1] expected = [1];
505 4
            assert(equal(v.range, expected[]));
506
        }
507
    }
508

509
    {
510
        static void fun(Allocator)(ref Allocator allocator) {
511
            Vector!(int, Allocator) v;
512
        }
513
    }
514
}
515

516

517
version(Windows) {}
518
else {
519
    @("mmapRegionList")
520
        @system unittest {
521
        import std.experimental.allocator.showcase: mmapRegionList;
522
        import std.experimental.allocator.mallocator: Mallocator;
523
        import automem.vector: isAllocator;
524

525 4
        auto v = vector(mmapRegionList(1024), 0, 1, 2);
526 4
        v ~= 3;
527
    }
528
}
529

530

531

532
@("2d")
533
@safe unittest {
534 4
    auto v = vector(vector(0, 0, 0), vector(1, 1, 1, 1));
535 4
    v[0].range.should == [0, 0, 0];
536 4
    v[1].range.should == [1, 1, 1, 1];
537
}
538

539

540
@("toString")
541
@safe unittest {
542
    import std.conv: text;
543 4
    auto v = vector(1, 2, 3);
544 4
    v.range.text.should == `[1, 2, 3]`;
545
}
546

547

548
@("return")
549
@system unittest {
550

551
    static auto fun() {
552 4
        auto v = vector(1, 2, 3);
553 4
        v ~= 4;
554 4
        return v;
555
    }
556

557 4
    auto v = fun;
558 4
    v ~= 5;
559 4
    v.range.should == [1, 2, 3, 4, 5];
560
}
561

562

563
@("noconsume.range")
564
@safe unittest {
565
    import std.algorithm: equal;
566

567 4
    scope v = vector(1, 2, 3);
568

569
    static void fun(R)(R range) {
570
        import std.array: array;
571 4
        assert(equal(range, [1, 2, 3]));
572
    }
573

574 4
    fun(v.range);
575 4
    assert(equal(v.range, [1, 2, 3]));
576
}
577

578

579
@("noconsume.foreach")
580
@safe unittest {
581 4
    scope v = vector(1, 2, 3);
582 4
    foreach(e; v.range) {}
583 4
    v.range.should == [1, 2, 3];
584
}
585

586

587
@("noconsume.map")
588
@safe unittest {
589
    import std.algorithm: map;
590

591 4
    scope v = vector(1, 2, 3);
592 4
    v.range.map!(a => a * 2).should == [2, 4, 6];
593 4
    v.range.should == [1, 2, 3];
594
}
595

596

597
@("reserve")
598
@safe unittest {
599 4
    scope vec = vector(1, 2, 3);
600 4
    vec.range.should == [1, 2, 3];
601 4
    () @trusted { vec.reserve(10); }();
602 4
    vec.range.should == [1, 2, 3];
603
}
604

605

606
@("range.reserve")
607
@safe unittest {
608 4
    scope vec = vector(1, 2, 3);
609 4
    scope range = vec.range;
610

611 4
    range.save.should == [1, 2, 3];
612 4
    () @trusted { vec.reserve(10); }();
613

614 4
    range.should == [1, 2, 3];
615
}
616

617

618
@("range.const")
619
@safe unittest {
620 4
    const vec = vector(1, 2, 3);
621 4
    vec.range.should == [1, 2, 3];
622
}
623

624

625
@("range.bounds")
626
@safe unittest {
627 4
    const vec = vector(1, 2, 3, 4, 5);
628 4
    vec.range(1, 4).should == [2, 3, 4];
629 4
    vec.range(2, vec.length).should == [3, 4, 5];
630 4
    vec.range(2, -1).should == [3, 4, 5];
631 4
    vec.range(2, -2).should == [3, 4];
632
}
633

634

635
@("equals")
636
@safe unittest {
637
    import std.range: iota, only;
638

639 4
    const vec = vector(0, 1, 2);
640

641 4
    (vec == 3.iota).should == true;
642 4
    (vec == 2.iota).should == false;
643 4
    (vec == 4.iota).should == false;
644 4
    (vec == only(0)).should == false;
645
}

Read our documentation on viewing source code .

Loading