1 /// Test value semantics
2 module ut.value;
3 
4 
5 import unit_threaded;
6 import tardy;
7 
8 
9 // verify that copying obeys value semantics
10 @("copy")
11 // not pure because the copy constructor isn't (and can't)
12 @safe unittest {
13     import std.algorithm.iteration: map;
14 
15     static interface IPrintable {
16         void inc() @safe;
17         string stringify() @safe const;
18     }
19 
20     alias Printable = Polymorphic!IPrintable;
21 
22     import std.conv: text;
23     static struct Foo {
24         int i;
25         void inc() @safe { ++i; }
26         string stringify() @safe const { return text("Foo(", i, ")"); }
27     }
28     static struct Bar {
29         int i;
30         void inc() @safe { ++i; }
31         string stringify() @safe const { return text("Bar(", i, ")"); }
32     }
33     static struct Baz {
34         int i;
35         void inc() @safe { ++i; }
36         string stringify() @safe const { return text("Baz(", i, ")"); }
37     }
38 
39     auto printables = [
40         Printable(Foo(0)),
41         Printable(Foo(1)),
42         Printable(Bar(2)),
43         Printable(Baz(3)),
44     ];
45 
46     string call(Printable p) { return p.stringify; }
47     auto strings = printables.map!call;
48     () @trusted {
49         strings.should == ["Foo(0)", "Foo(1)", "Bar(2)", "Baz(3)"];
50     }();
51 
52     auto bar = printables[2];
53     bar.stringify.should == "Bar(2)";
54     bar.inc;
55     bar.inc;
56     bar.inc;
57     bar.stringify.should == "Bar(5)";
58 
59     strings = printables.map!call;
60     () @trusted {
61         strings.should == ["Foo(0)", "Foo(1)", "Bar(2)", "Baz(3)"];
62     }();
63 }
64 
65 
66 @("uncopiable")
67 @safe unittest {
68     static interface IPrintable {
69         void inc() @safe;
70         string stringify() @safe const;
71     }
72 
73     alias Printable = Polymorphic!IPrintable;
74 
75     static struct Foo {
76         @disable this(this);
77         int i;
78         void inc() @safe { ++i; }
79         string stringify() @safe const { import std.conv: text; return text("Foo(", i, ")"); }
80     }
81 
82     static assert(!__traits(compiles, Printable(Foo(42))));
83     auto p = Printable.create!Foo(42);
84     p.stringify.should == "Foo(42)";
85     p.inc;
86     p.stringify.should == "Foo(43)";
87 }