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.set;
5 
6 import tanya.container.set;
7 import tanya.memory.allocator;
8 import tanya.test.stub;
9 
10 // Basic insertion logic.
11 @nogc nothrow pure @safe unittest
12 {
13     Set!int set;
14 
15     assert(set.insert(5) == 1);
16     assert(5 in set);
17     assert(set.capacity == 3);
18 
19     assert(set.insert(5) == 0);
20     assert(5 in set);
21     assert(set.capacity == 3);
22 
23     assert(set.insert(9) == 1);
24     assert(9 in set);
25     assert(5 in set);
26     assert(set.capacity == 3);
27 
28     assert(set.insert(7) == 1);
29     assert(set.insert(8) == 1);
30     assert(8 in set);
31     assert(5 in set);
32     assert(9 in set);
33     assert(7 in set);
34     assert(set.capacity == 7);
35 
36     assert(set.insert(16) == 1);
37     assert(16 in set);
38     assert(set.capacity == 7);
39 }
40 
41 // Static checks.
42 @nogc nothrow pure @safe unittest
43 {
44     import tanya.range.primitive;
45 
46     static assert(isBidirectionalRange!(Set!int.ConstRange));
47     static assert(isBidirectionalRange!(Set!int.Range));
48 
49     static assert(!isInfinite!(Set!int.Range));
50     static assert(!hasLength!(Set!int.Range));
51 
52     static assert(is(Set!uint));
53     static assert(is(Set!long));
54     static assert(is(Set!ulong));
55     static assert(is(Set!short));
56     static assert(is(Set!ushort));
57     static assert(is(Set!bool));
58 }
59 
60 @nogc nothrow pure @safe unittest
61 {
62     const Set!int set;
63     assert(set[].empty);
64 }
65 
66 @nogc nothrow pure @safe unittest
67 {
68     Set!int set;
69     set.insert(8);
70 
71     auto r1 = set[];
72     auto r2 = r1.save();
73 
74     r1.popFront();
75     assert(r1.empty);
76 
77     r2.popBack();
78     assert(r2.empty);
79 }
80 
81 // Initial capacity is 0.
82 @nogc nothrow pure @safe unittest
83 {
84     auto set = Set!int(defaultAllocator);
85     assert(set.capacity == 0);
86 }
87 
88 // Capacity is set to a prime.
89 @nogc nothrow pure @safe unittest
90 {
91     auto set = Set!int(8);
92     assert(set.capacity == 13);
93 }
94 
95 // Constructs by reference
96 @nogc nothrow pure @safe unittest
97 {
98     auto set1 = Set!int(7);
99     auto set2 = Set!int(set1);
100     assert(set1.length == set2.length);
101     assert(set1.capacity == set2.capacity);
102 }
103 
104 // Constructs by value
105 @nogc nothrow pure @safe unittest
106 {
107     auto set = Set!int(Set!int(7));
108     assert(set.capacity == 7);
109 }
110 
111 // Assigns by reference
112 @nogc nothrow pure @safe unittest
113 {
114     auto set1 = Set!int(7);
115     Set!int set2;
116     set1 = set2;
117     assert(set1.length == set2.length);
118     assert(set1.capacity == set2.capacity);
119 }
120 
121 // Assigns by value
122 @nogc nothrow pure @safe unittest
123 {
124     Set!int set;
125     set = Set!int(7);
126     assert(set.capacity == 7);
127 }
128 
129 // Postblit copies
130 @nogc nothrow pure @safe unittest
131 {
132     auto set = Set!int(7);
133     void testFunc(Set!int set)
134     {
135         assert(set.capacity == 7);
136     }
137     testFunc(set);
138 }
139 
140 // Hasher can take argument by ref
141 @nogc nothrow pure @safe unittest
142 {
143     static assert(is(Set!(int, (const ref x) => cast(size_t) x)));
144 }
145 
146 // Can have non-copyable elements
147 @nogc nothrow pure @safe unittest
148 {
149     @NonCopyable @Hashable
150     static struct S
151     {
152         mixin StructStub;
153     }
154     static assert(is(Set!S));
155 }