Blender V4.3
BLI_stack_cxx_test.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#include "testing/testing.h"
6
8#include "BLI_stack.hh"
9#include "BLI_vector.hh"
10
11#include "BLI_strict_flags.h" /* Keep last. */
12
13namespace blender::tests {
14
15TEST(stack, DefaultConstructor)
16{
17 Stack<int> stack;
18 EXPECT_EQ(stack.size(), 0);
19 EXPECT_TRUE(stack.is_empty());
20}
21
22TEST(stack, SpanConstructor)
23{
24 std::array<int, 3> array = {4, 7, 2};
25 Stack<int> stack(array);
26 EXPECT_EQ(stack.size(), 3);
27 EXPECT_EQ(stack.pop(), 2);
28 EXPECT_EQ(stack.pop(), 7);
29 EXPECT_EQ(stack.pop(), 4);
30 EXPECT_TRUE(stack.is_empty());
31}
32
33TEST(stack, CopyConstructor)
34{
35 Stack<int> stack1 = {1, 2, 3, 4, 5, 6, 7};
36 Stack<int> stack2 = stack1;
37 EXPECT_EQ(stack1.size(), 7);
38 EXPECT_EQ(stack2.size(), 7);
39 for (int i = 7; i >= 1; i--) {
40 EXPECT_FALSE(stack1.is_empty());
41 EXPECT_FALSE(stack2.is_empty());
42 EXPECT_EQ(stack1.pop(), i);
43 EXPECT_EQ(stack2.pop(), i);
44 }
45 EXPECT_TRUE(stack1.is_empty());
46 EXPECT_TRUE(stack2.is_empty());
47}
48
49TEST(stack, MoveConstructor)
50{
51 Stack<int> stack1 = {1, 2, 3, 4, 5, 6, 7};
52 Stack<int> stack2 = std::move(stack1);
53 EXPECT_EQ(stack1.size(), 0); /* NOLINT: bugprone-use-after-move */
54 EXPECT_EQ(stack2.size(), 7);
55 for (int i = 7; i >= 1; i--) {
56 EXPECT_EQ(stack2.pop(), i);
57 }
58}
59
60TEST(stack, CopyAssignment)
61{
62 Stack<int> stack1 = {1, 2, 3, 4, 5, 6, 7};
63 Stack<int> stack2 = {2, 3, 4, 5, 6, 7};
64 stack2 = stack1;
65
66 EXPECT_EQ(stack1.size(), 7);
67 EXPECT_EQ(stack2.size(), 7);
68 for (int i = 7; i >= 1; i--) {
69 EXPECT_FALSE(stack1.is_empty());
70 EXPECT_FALSE(stack2.is_empty());
71 EXPECT_EQ(stack1.pop(), i);
72 EXPECT_EQ(stack2.pop(), i);
73 }
74 EXPECT_TRUE(stack1.is_empty());
75 EXPECT_TRUE(stack2.is_empty());
76}
77
78TEST(stack, MoveAssignment)
79{
80 Stack<int> stack1 = {1, 2, 3, 4, 5, 6, 7};
81 Stack<int> stack2 = {5, 3, 7, 2, 2};
82 stack2 = std::move(stack1);
83 EXPECT_EQ(stack1.size(), 0); /* NOLINT: bugprone-use-after-move */
84 EXPECT_EQ(stack2.size(), 7);
85 for (int i = 7; i >= 1; i--) {
86 EXPECT_EQ(stack2.pop(), i);
87 }
88}
89
90TEST(stack, Push)
91{
92 Stack<int> stack;
93 EXPECT_EQ(stack.size(), 0);
94 stack.push(3);
95 EXPECT_EQ(stack.size(), 1);
96 stack.push(5);
97 EXPECT_EQ(stack.size(), 2);
98}
99
100TEST(stack, PushAs)
101{
102 Stack<StringRef> stack;
103 stack.push_as("hello", 3);
104 stack.push_as("world", 1);
105 EXPECT_EQ(stack.pop(), "w");
106 EXPECT_EQ(stack.pop(), "hel");
107}
108
109TEST(stack, PushMultiple)
110{
111 Stack<int> stack;
112 EXPECT_EQ(stack.size(), 0);
113 stack.push_multiple({1, 2, 3});
114 EXPECT_EQ(stack.size(), 3);
115 EXPECT_EQ(stack.pop(), 3);
116 EXPECT_EQ(stack.pop(), 2);
117 EXPECT_EQ(stack.pop(), 1);
118}
119
120TEST(stack, PushPopMany)
121{
122 Stack<int> stack;
123 for (int i = 0; i < 1000; i++) {
124 stack.push(i);
125 EXPECT_EQ(stack.size(), uint(i + 1));
126 }
127 for (int i = 999; i > 50; i--) {
128 EXPECT_EQ(stack.pop(), i);
129 EXPECT_EQ(stack.size(), uint(i));
130 }
131 for (int i = 51; i < 5000; i++) {
132 stack.push(i);
133 EXPECT_EQ(stack.size(), uint(i + 1));
134 }
135 for (int i = 4999; i >= 0; i--) {
136 EXPECT_EQ(stack.pop(), i);
137 EXPECT_EQ(stack.size(), uint(i));
138 }
139}
140
141TEST(stack, PushMultipleAfterPop)
142{
143 Stack<int> stack;
144 for (int i = 0; i < 1000; i++) {
145 stack.push(i);
146 }
147 for (int i = 999; i >= 0; i--) {
148 EXPECT_EQ(stack.pop(), i);
149 }
150
151 Vector<int> values;
152 for (int i = 0; i < 5000; i++) {
153 values.append(i);
154 }
155 stack.push_multiple(values);
156 EXPECT_EQ(stack.size(), 5000);
157
158 for (int i = 4999; i >= 0; i--) {
159 EXPECT_EQ(stack.pop(), i);
160 }
161}
162
163TEST(stack, Pop)
164{
165 Stack<int> stack;
166 stack.push(4);
167 stack.push(6);
168 EXPECT_EQ(stack.pop(), 6);
169 EXPECT_EQ(stack.pop(), 4);
170}
171
172TEST(stack, Peek)
173{
174 Stack<int> stack;
175 stack.push(3);
176 stack.push(4);
177 EXPECT_EQ(stack.peek(), 4);
178 EXPECT_EQ(stack.peek(), 4);
179 stack.pop();
180 EXPECT_EQ(stack.peek(), 3);
181}
182
183TEST(stack, UniquePtrValues)
184{
186 stack.push(std::make_unique<int>());
187 stack.push(std::make_unique<int>());
188 std::unique_ptr<int> a = stack.pop();
189 std::unique_ptr<int> &b = stack.peek();
190 UNUSED_VARS(a, b);
191}
192
193TEST(stack, OveralignedValues)
194{
196 for (int i = 0; i < 100; i++) {
197 stack.push({});
198 EXPECT_EQ(uintptr_t(&stack.peek()) % 512, 0);
199 }
200}
201
202TEST(stack, SpanConstructorExceptions)
203{
204 std::array<ExceptionThrower, 5> values;
205 values[3].throw_during_copy = true;
206 EXPECT_ANY_THROW({ Stack<ExceptionThrower> stack(values); });
207}
208
209TEST(stack, MoveConstructorExceptions)
210{
212 stack.push({});
213 stack.push({});
214 stack.peek().throw_during_move = true;
215 EXPECT_ANY_THROW({ Stack<ExceptionThrower> moved_stack{std::move(stack)}; });
216}
217
218TEST(stack, PushExceptions)
219{
221 stack.push({});
222 stack.push({});
223 ExceptionThrower *ptr1 = &stack.peek();
224 ExceptionThrower value;
225 value.throw_during_copy = true;
226 EXPECT_ANY_THROW({ stack.push(value); });
227 EXPECT_EQ(stack.size(), 2);
228 ExceptionThrower *ptr2 = &stack.peek();
229 EXPECT_EQ(ptr1, ptr2);
230 EXPECT_TRUE(stack.is_invariant_maintained());
231}
232
233TEST(stack, PopExceptions)
234{
236 stack.push({});
237 stack.peek().throw_during_move = true;
238 stack.push({});
239 stack.pop(); /* NOLINT: bugprone-throw-keyword-missing */
240 EXPECT_ANY_THROW({ stack.pop(); }); /* NOLINT: bugprone-throw-keyword-missing */
241 EXPECT_EQ(stack.size(), 1);
242 EXPECT_TRUE(stack.is_invariant_maintained());
243}
244
245TEST(stack, PushMultipleExceptions)
246{
248 stack.push({});
249 std::array<ExceptionThrower, 100> values;
250 values[6].throw_during_copy = true;
251 EXPECT_ANY_THROW({ stack.push_multiple(values); });
252 EXPECT_TRUE(stack.is_invariant_maintained());
253 EXPECT_ANY_THROW({ stack.push_multiple(values); });
254 EXPECT_TRUE(stack.is_invariant_maintained());
255}
256
257} // namespace blender::tests
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
unsigned int uint
#define UNUSED_VARS(...)
bool is_invariant_maintained() const
Definition BLI_stack.hh:342
void push_as(ForwardT &&...value)
Definition BLI_stack.hh:222
bool is_empty() const
Definition BLI_stack.hh:308
void push(const T &value)
Definition BLI_stack.hh:213
void push_multiple(Span< T > values)
Definition BLI_stack.hh:281
int64_t size() const
Definition BLI_stack.hh:316
void append(const T &value)
local_group_size(16, 16) .push_constant(Type b
TEST(any, DefaultConstructor)
_W64 unsigned int uintptr_t
Definition stdint.h:119