Blender  V2.93
BLI_stack_cxx_test.cc
Go to the documentation of this file.
1 /* Apache License, Version 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, PushMultiple)
97 {
98  Stack<int> stack;
99  EXPECT_EQ(stack.size(), 0);
100  stack.push_multiple({1, 2, 3});
101  EXPECT_EQ(stack.size(), 3);
102  EXPECT_EQ(stack.pop(), 3);
103  EXPECT_EQ(stack.pop(), 2);
104  EXPECT_EQ(stack.pop(), 1);
105 }
106 
107 TEST(stack, PushPopMany)
108 {
109  Stack<int> stack;
110  for (int i = 0; i < 1000; i++) {
111  stack.push(i);
112  EXPECT_EQ(stack.size(), static_cast<unsigned int>(i + 1));
113  }
114  for (int i = 999; i > 50; i--) {
115  EXPECT_EQ(stack.pop(), i);
116  EXPECT_EQ(stack.size(), static_cast<unsigned int>(i));
117  }
118  for (int i = 51; i < 5000; i++) {
119  stack.push(i);
120  EXPECT_EQ(stack.size(), static_cast<unsigned int>(i + 1));
121  }
122  for (int i = 4999; i >= 0; i--) {
123  EXPECT_EQ(stack.pop(), i);
124  EXPECT_EQ(stack.size(), static_cast<unsigned int>(i));
125  }
126 }
127 
128 TEST(stack, PushMultipleAfterPop)
129 {
130  Stack<int> stack;
131  for (int i = 0; i < 1000; i++) {
132  stack.push(i);
133  }
134  for (int i = 999; i >= 0; i--) {
135  EXPECT_EQ(stack.pop(), i);
136  }
137 
138  Vector<int> values;
139  for (int i = 0; i < 5000; i++) {
140  values.append(i);
141  }
142  stack.push_multiple(values);
143  EXPECT_EQ(stack.size(), 5000);
144 
145  for (int i = 4999; i >= 0; i--) {
146  EXPECT_EQ(stack.pop(), i);
147  }
148 }
149 
150 TEST(stack, Pop)
151 {
152  Stack<int> stack;
153  stack.push(4);
154  stack.push(6);
155  EXPECT_EQ(stack.pop(), 6);
156  EXPECT_EQ(stack.pop(), 4);
157 }
158 
159 TEST(stack, Peek)
160 {
161  Stack<int> stack;
162  stack.push(3);
163  stack.push(4);
164  EXPECT_EQ(stack.peek(), 4);
165  EXPECT_EQ(stack.peek(), 4);
166  stack.pop();
167  EXPECT_EQ(stack.peek(), 3);
168 }
169 
170 TEST(stack, UniquePtrValues)
171 {
173  stack.push(std::make_unique<int>());
174  stack.push(std::make_unique<int>());
175  std::unique_ptr<int> a = stack.pop();
176  std::unique_ptr<int> &b = stack.peek();
177  UNUSED_VARS(a, b);
178 }
179 
180 TEST(stack, OveralignedValues)
181 {
182  Stack<AlignedBuffer<1, 512>, 2> stack;
183  for (int i = 0; i < 100; i++) {
184  stack.push({});
185  EXPECT_EQ((uintptr_t)&stack.peek() % 512, 0);
186  }
187 }
188 
189 TEST(stack, SpanConstructorExceptions)
190 {
191  std::array<ExceptionThrower, 5> values;
192  values[3].throw_during_copy = true;
193  EXPECT_ANY_THROW({ Stack<ExceptionThrower> stack(values); });
194 }
195 
196 TEST(stack, MoveConstructorExceptions)
197 {
199  stack.push({});
200  stack.push({});
201  stack.peek().throw_during_move = true;
202  EXPECT_ANY_THROW({ Stack<ExceptionThrower> moved_stack{std::move(stack)}; });
203 }
204 
205 TEST(stack, PushExceptions)
206 {
208  stack.push({});
209  stack.push({});
210  ExceptionThrower *ptr1 = &stack.peek();
211  ExceptionThrower value;
212  value.throw_during_copy = true;
213  EXPECT_ANY_THROW({ stack.push(value); });
214  EXPECT_EQ(stack.size(), 2);
215  ExceptionThrower *ptr2 = &stack.peek();
216  EXPECT_EQ(ptr1, ptr2);
217  EXPECT_TRUE(stack.is_invariant_maintained());
218 }
219 
220 TEST(stack, PopExceptions)
221 {
223  stack.push({});
224  stack.peek().throw_during_move = true;
225  stack.push({});
226  stack.pop(); /* NOLINT: bugprone-throw-keyword-missing */
227  EXPECT_ANY_THROW({ stack.pop(); }); /* NOLINT: bugprone-throw-keyword-missing */
228  EXPECT_EQ(stack.size(), 1);
229  EXPECT_TRUE(stack.is_invariant_maintained());
230 }
231 
232 TEST(stack, PushMultipleExceptions)
233 {
235  stack.push({});
236  std::array<ExceptionThrower, 100> values;
237  values[6].throw_during_copy = true;
238  EXPECT_ANY_THROW({ stack.push_multiple(values); });
239  EXPECT_TRUE(stack.is_invariant_maintained());
240  EXPECT_ANY_THROW({ stack.push_multiple(values); });
241  EXPECT_TRUE(stack.is_invariant_maintained());
242 }
243 
244 } // 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:346
bool is_empty() const
Definition: BLI_stack.hh:321
void push(const T &value)
Definition: BLI_stack.hh:227
void push_multiple(Span< T > values)
Definition: BLI_stack.hh:294
int64_t size() const
Definition: BLI_stack.hh:329
void append(const T &value)
Definition: BLI_vector.hh:438
static unsigned a[3]
Definition: RandGen.cpp:92
TEST(array, DefaultConstructor)
_W64 unsigned int uintptr_t
Definition: stdint.h:122