1 module automem; 2 3 public import automem.unique; 4 public import automem.unique_array; 5 public import automem.ref_counted; 6 7 import automem.test_utils: TestUtils; 8 9 mixin TestUtils; 10 11 // can be @safe if the allocator has @safe functions 12 @system @nogc unittest { 13 14 import std.experimental.allocator.mallocator: Mallocator; 15 import std.algorithm: move; 16 17 struct Point { 18 int x; 19 int y; 20 } 21 22 { 23 // must pass arguments to initialise the contained object 24 auto u1 = Unique!(Point, Mallocator)(2, 3); 25 assert(*u1 == Point(2, 3)); 26 assert(u1.y == 3); 27 28 // auto u2 = u1; // won't compile, can only move 29 typeof(u1) u2 = u1.move; 30 assert(cast(bool)u1 == false); // u1 is now empty 31 } 32 // memory freed for the Point structure created in the block 33 34 { 35 auto s1 = RefCounted!(Point, Mallocator)(4, 5); 36 assert(*s1 == Point(4, 5)); 37 assert(s1.x == 4); 38 { 39 auto s2 = s1; // can be copied 40 } // ref count goes to 1 here 41 42 } // ref count goes to 0 here, memory released 43 44 { 45 // the constructor can also take (size, init) or (size, range) values 46 auto arr = UniqueArray!(Point, Mallocator)(3); 47 48 const Point[3] expected1 = [Point(), Point(), Point()]; // because array literals aren't @nogc 49 assert(arr[] == expected1); 50 51 const Point[1] expected2 = [Point()]; 52 arr.length = 1; 53 assert(*arr == expected2); //deferencing is the same as slicing all of it 54 55 arr ~= UniqueArray!(Point, Mallocator)(1, Point(6, 7)); 56 const Point[2] expected3 = [Point(), Point(6, 7)]; 57 assert(arr[] == expected3); 58 59 } // memory for the array released here 60 } 61 62 63 @("theAllocator") 64 @system unittest { 65 with(theTestAllocator) { 66 auto ptr = Unique!int(42); 67 assert(*ptr == 42); 68 } 69 } // TestAllocator will throw here if any memory leaks