1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 module tanya.container.tests.array;
5 
6 import std.algorithm.comparison;
7 import tanya.container.array;
8 import tanya.memory.allocator;
9 import tanya.test.stub;
10 
11 // const arrays return usable ranges
12 @nogc nothrow pure @safe unittest
13 {
14     auto v = const Array!int([1, 2, 4]);
15     auto r1 = v[];
16 
17     assert(r1.back == 4);
18     r1.popBack();
19     assert(r1.back == 2);
20     r1.popBack();
21     assert(r1.back == 1);
22     r1.popBack();
23     assert(r1.length == 0);
24 
25     static assert(!is(typeof(r1[0] = 5)));
26     static assert(!is(typeof(v[0] = 5)));
27 
28     const r2 = r1[];
29     static assert(is(typeof(r2[])));
30 }
31 
32 @nogc nothrow pure @safe unittest
33 {
34     Array!int v1;
35     const Array!int v2;
36 
37     auto r1 = v1[];
38     auto r2 = v1[];
39 
40     assert(r1.length == 0);
41     assert(r2.empty);
42     assert(r1 == r2);
43 
44     v1.insertBack([1, 2, 4]);
45     assert(v1[] == v1);
46     assert(v2[] == v2);
47     assert(v2[] != v1);
48     assert(v1[] != v2);
49     assert(v1[].equal(v1[]));
50     assert(v2[].equal(v2[]));
51     assert(!v1[].equal(v2[]));
52 }
53 
54 @nogc nothrow pure @safe unittest
55 {
56     struct MutableEqualsStruct
57     {
58         bool opEquals(typeof(this) that) @nogc nothrow pure @safe
59         {
60             return true;
61         }
62     }
63     struct ConstEqualsStruct
64     {
65         bool opEquals(const typeof(this) that) const @nogc nothrow pure @safe
66         {
67             return true;
68         }
69     }
70     auto v1 = Array!ConstEqualsStruct();
71     auto v2 = Array!ConstEqualsStruct();
72     assert(v1 == v2);
73     assert(v1[] == v2);
74     assert(v1 == v2[]);
75     assert(v1[].equal(v2[]));
76 
77     auto v3 = const Array!ConstEqualsStruct();
78     auto v4 = const Array!ConstEqualsStruct();
79     assert(v3 == v4);
80     assert(v3[] == v4);
81     assert(v3 == v4[]);
82     assert(v3[].equal(v4[]));
83 
84     auto v7 = Array!MutableEqualsStruct(1, MutableEqualsStruct());
85     auto v8 = Array!MutableEqualsStruct(1, MutableEqualsStruct());
86     assert(v7 == v8);
87     assert(v7[] == v8);
88     assert(v7 == v8[]);
89     assert(v7[].equal(v8[]));
90 }
91 
92 // Destructor can destroy empty arrays
93 @nogc nothrow pure @safe unittest
94 {
95     auto v = Array!WithDtor();
96 }
97 
98 @nogc nothrow pure @safe unittest
99 {
100     class A
101     {
102     }
103     A a1, a2;
104     auto v1 = Array!A([a1, a2]);
105 
106     static assert(is(Array!(A*)));
107 }
108 
109 @nogc nothrow pure @safe unittest
110 {
111     auto v = Array!int([5, 15, 8]);
112     {
113         size_t i;
114 
115         foreach (e; v)
116         {
117             assert(i != 0 || e == 5);
118             assert(i != 1 || e == 15);
119             assert(i != 2 || e == 8);
120             ++i;
121         }
122         assert(i == 3);
123     }
124     {
125         size_t i = 3;
126 
127         foreach_reverse (e; v)
128         {
129             --i;
130             assert(i != 2 || e == 8);
131             assert(i != 1 || e == 15);
132             assert(i != 0 || e == 5);
133         }
134         assert(i == 0);
135     }
136 }
137 
138 // const constructor tests
139 @nogc nothrow pure @system unittest
140 {
141     auto v1 = const Array!int([1, 2, 3]);
142     auto v2 = Array!int(v1);
143     assert(v1.get !is v2.get);
144     assert(v1 == v2);
145 
146     auto v3 = const Array!int(Array!int([1, 2, 3]));
147     assert(v1 == v3);
148     assert(v3.length == 3);
149     assert(v3.capacity == 3);
150 }
151 
152 @nogc nothrow pure @safe unittest
153 {
154     auto v1 = Array!int(defaultAllocator);
155 }
156 
157 @nogc nothrow pure @safe unittest
158 {
159     Array!int v;
160     auto r = v[];
161     assert(r.length == 0);
162     assert(r.empty);
163 }
164 
165 @nogc nothrow pure @safe unittest
166 {
167     auto v1 = const Array!int([5, 15, 8]);
168     Array!int v2;
169     v2 = v1[0 .. 2];
170     assert(equal(v1[0 .. 2], v2[]));
171 }
172 
173 // Move assignment
174 @nogc nothrow pure @safe unittest
175 {
176     Array!int v1;
177     v1 = Array!int([5, 15, 8]);
178 }
179 
180 // Postblit is safe
181 @nogc nothrow pure @safe unittest
182 {
183     auto array = Array!int(3);
184     void func(Array!int arg)
185     {
186         assert(arg.capacity == 3);
187     }
188     func(array);
189 }