1 module ut.memory.classes; 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.safe | FA.pure_; 12 enum DestructorAttrs = FA.pure_ | FA.nogc; 13 14 int transform(int) @safe @nogc pure const; 15 } 16 17 private alias Transformer = Polymorphic!(ITransformer, Mallocator); 18 19 // @system because the copy constructor can't be safe 20 private int xform(in Transformer t, int i) @system @nogc pure { 21 return t.transform(i); 22 } 23 24 private class Multiplier { 25 int i; 26 this(int i) @safe @nogc pure nothrow inout { this.i = i; } 27 this(const Multiplier other) @safe @nogc pure nothrow inout { this.i = other.i; } 28 int transform(int j) @safe @nogc pure nothrow const { return i * j; } 29 override string toString() @safe pure nothrow const { 30 import std.conv: text; 31 return text(`Multiplier(`, i, `)`); 32 } 33 } 34 35 private class Thrice { 36 int transform(int i) @safe @nogc pure const { return i * 3; } 37 } 38 39 40 @("mallocator.stateful.create") 41 @system pure unittest { 42 const multiplier = Transformer.create!Multiplier(3); 43 xform(multiplier, 2).should == 6; 44 xform(multiplier, 3).should == 9; 45 } 46 47 48 @("mallocator.stateful.copy") 49 @system pure unittest { 50 const multiplier = Transformer(new Multiplier(3)); 51 xform(multiplier, 2).should == 6; 52 xform(multiplier, 3).should == 9; 53 } 54 55 56 @("mallocator.stateless.create") 57 @system pure unittest { 58 const multiplier = Transformer.create!Thrice(3); 59 xform(multiplier, 2).should == 6; 60 xform(multiplier, 3).should == 9; 61 }