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 }