1 module ut.memory.structs; 2 3 4 import ut; 5 import std.experimental.allocator.mallocator: Mallocator; 6 7 8 private interface ITransformer { 9 import std.traits: FA = FunctionAttribute; 10 11 enum CopyConstructorAttrs = FA.pure_ | FA.nogc; 12 enum DestructorAttrs = FA.pure_ | FA.nogc; 13 14 int transform(int) @safe @nogc pure const; 15 } 16 17 18 private interface ITransformerGC { 19 import std.traits: FA = FunctionAttribute; 20 21 enum CopyConstructorAttrs = FA.system; 22 enum DestructorAttrs = FA.system; 23 24 int transform(int) @system pure const; 25 } 26 27 28 private alias TransformerMalloc = Polymorphic!(ITransformer, Mallocator); 29 30 // @system because the copy constructor can't be @safe 31 private int xform(in TransformerMalloc t, int i) @system @nogc pure { 32 return t.transform(i); 33 } 34 35 private struct Multiplier { 36 int i; 37 int transform(int j) @safe @nogc pure nothrow const { return i * j; } 38 } 39 40 41 @("mallocator.create") 42 @system pure unittest { 43 const multiplier = TransformerMalloc.create!Multiplier(3); 44 xform(multiplier, 2).should == 6; 45 xform(multiplier, 3).should == 9; 46 } 47 48 49 @("mallocator.copy") 50 @system pure unittest { 51 const multiplier = TransformerMalloc(Multiplier(3)); 52 xform(multiplier, 2).should == 6; 53 xform(multiplier, 3).should == 9; 54 } 55 56 57 @("mallocator.nogc") 58 @system @nogc pure unittest { 59 const multiplier = TransformerMalloc(Multiplier(3)); 60 xform(multiplier, 2); 61 } 62 63 64 @("sbo.copy") 65 @system pure unittest { 66 const multiplier = Polymorphic!(ITransformer, SBOAllocator!16)(Multiplier(3)); 67 multiplier.transform(2).should == 6; 68 multiplier.transform(3).should == 9; 69 } 70 71 72 @("insitu.copy") 73 @system pure unittest { 74 const multiplier = Polymorphic!(ITransformer, InSitu!16)(Multiplier(3)); 75 multiplier.transform(2).should == 6; 76 multiplier.transform(3).should == 9; 77 } 78 79 80 @("theAllocator.copy") 81 @system unittest { 82 import std.experimental.allocator: theAllocator; 83 84 const multiplier = Polymorphic!(ITransformerGC, typeof(theAllocator))(Multiplier(3)); 85 multiplier.transform(2).should == 6; 86 multiplier.transform(3).should == 9; 87 }