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