Blender  V2.93
BLI_span_test.cc
Go to the documentation of this file.
1 /* Apache License, Version 2.0 */
2 
3 #include "BLI_span.hh"
4 #include "BLI_strict_flags.h"
5 #include "BLI_vector.hh"
6 #include "testing/testing.h"
7 
8 namespace blender::tests {
9 
10 TEST(span, FromSmallVector)
11 {
12  Vector<int> a = {1, 2, 3};
13  Span<int> a_span = a;
14  EXPECT_EQ(a_span.size(), 3);
15  EXPECT_EQ(a_span[0], 1);
16  EXPECT_EQ(a_span[1], 2);
17  EXPECT_EQ(a_span[2], 3);
18 }
19 
20 TEST(span, AddConstToPointer)
21 {
22  int a = 0;
23  std::vector<int *> vec = {&a};
24  Span<int *> span = vec;
25  Span<const int *> const_span = span;
26  EXPECT_EQ(const_span.size(), 1);
27 }
28 
29 TEST(span, IsReferencing)
30 {
31  int array[] = {3, 5, 8};
33  EXPECT_EQ(span.size(), 3);
34  EXPECT_EQ(span[1], 5);
35  array[1] = 10;
36  EXPECT_EQ(span[1], 10);
37 }
38 
39 TEST(span, DropBack)
40 {
41  Vector<int> a = {4, 5, 6, 7};
42  auto slice = Span<int>(a).drop_back(2);
43  EXPECT_EQ(slice.size(), 2);
44  EXPECT_EQ(slice[0], 4);
45  EXPECT_EQ(slice[1], 5);
46 }
47 
48 TEST(span, DropBackAll)
49 {
50  Vector<int> a = {4, 5, 6, 7};
51  auto slice = Span<int>(a).drop_back(a.size());
52  EXPECT_EQ(slice.size(), 0);
53 }
54 
55 TEST(span, DropFront)
56 {
57  Vector<int> a = {4, 5, 6, 7};
58  auto slice = Span<int>(a).drop_front(1);
59  EXPECT_EQ(slice.size(), 3);
60  EXPECT_EQ(slice[0], 5);
61  EXPECT_EQ(slice[1], 6);
62  EXPECT_EQ(slice[2], 7);
63 }
64 
65 TEST(span, DropFrontLargeN)
66 {
67  Vector<int> a = {1, 2, 3, 4, 5};
68  Span<int> slice1 = Span<int>(a).drop_front(100);
70  EXPECT_TRUE(slice1.is_empty());
71  EXPECT_TRUE(slice2.is_empty());
72 }
73 
74 TEST(span, DropFrontAll)
75 {
76  Vector<int> a = {4, 5, 6, 7};
77  auto slice = Span<int>(a).drop_front(a.size());
78  EXPECT_EQ(slice.size(), 0);
79 }
80 
81 TEST(span, TakeFront)
82 {
83  Vector<int> a = {4, 5, 6, 7};
84  auto slice = Span<int>(a).take_front(2);
85  EXPECT_EQ(slice.size(), 2);
86  EXPECT_EQ(slice[0], 4);
87  EXPECT_EQ(slice[1], 5);
88 }
89 
90 TEST(span, TakeFrontLargeN)
91 {
92  Vector<int> a = {4, 5, 6, 7};
93  Span<int> slice1 = Span<int>(a).take_front(100);
95  EXPECT_EQ(slice1.size(), 4);
96  EXPECT_EQ(slice2.size(), 4);
97 }
98 
99 TEST(span, TakeBack)
100 {
101  Vector<int> a = {5, 6, 7, 8};
102  auto slice = Span<int>(a).take_back(2);
103  EXPECT_EQ(slice.size(), 2);
104  EXPECT_EQ(slice[0], 7);
105  EXPECT_EQ(slice[1], 8);
106 }
107 
108 TEST(span, TakeBackLargeN)
109 {
110  Vector<int> a = {3, 4, 5, 6};
111  Span<int> slice1 = Span<int>(a).take_back(100);
113  EXPECT_EQ(slice1.size(), 4);
114  EXPECT_EQ(slice2.size(), 4);
115 }
116 
117 TEST(span, Slice)
118 {
119  Vector<int> a = {4, 5, 6, 7};
120  auto slice = Span<int>(a).slice(1, 2);
121  EXPECT_EQ(slice.size(), 2);
122  EXPECT_EQ(slice[0], 5);
123  EXPECT_EQ(slice[1], 6);
124 }
125 
126 TEST(span, SliceEmpty)
127 {
128  Vector<int> a = {4, 5, 6, 7};
129  auto slice = Span<int>(a).slice(2, 0);
130  EXPECT_EQ(slice.size(), 0);
131 }
132 
133 TEST(span, SliceRange)
134 {
135  Vector<int> a = {1, 2, 3, 4, 5};
136  auto slice = Span<int>(a).slice(IndexRange(2, 2));
137  EXPECT_EQ(slice.size(), 2);
138  EXPECT_EQ(slice[0], 3);
139  EXPECT_EQ(slice[1], 4);
140 }
141 
142 TEST(span, SliceLargeN)
143 {
144  Vector<int> a = {1, 2, 3, 4, 5};
145  Span<int> slice1 = Span<int>(a).slice(3, 100);
146  MutableSpan<int> slice2 = MutableSpan<int>(a).slice(3, 100);
147  EXPECT_EQ(slice1.size(), 2);
148  EXPECT_EQ(slice2.size(), 2);
149  EXPECT_EQ(slice1[0], 4);
150  EXPECT_EQ(slice2[0], 4);
151  EXPECT_EQ(slice1[1], 5);
152  EXPECT_EQ(slice2[1], 5);
153 }
154 
155 TEST(span, Contains)
156 {
157  Vector<int> a = {4, 5, 6, 7};
158  Span<int> a_span = a;
159  EXPECT_TRUE(a_span.contains(4));
160  EXPECT_TRUE(a_span.contains(5));
161  EXPECT_TRUE(a_span.contains(6));
162  EXPECT_TRUE(a_span.contains(7));
163  EXPECT_FALSE(a_span.contains(3));
164  EXPECT_FALSE(a_span.contains(8));
165 }
166 
167 TEST(span, Count)
168 {
169  Vector<int> a = {2, 3, 4, 3, 3, 2, 2, 2, 2};
170  Span<int> a_span = a;
171  EXPECT_EQ(a_span.count(1), 0);
172  EXPECT_EQ(a_span.count(2), 5);
173  EXPECT_EQ(a_span.count(3), 3);
174  EXPECT_EQ(a_span.count(4), 1);
175  EXPECT_EQ(a_span.count(5), 0);
176 }
177 
179 {
180  EXPECT_EQ(span.size(), 4);
181  EXPECT_EQ(span[0], 3);
182  EXPECT_EQ(span[1], 6);
183  EXPECT_EQ(span[2], 8);
184  EXPECT_EQ(span[3], 9);
185 }
186 
187 TEST(span, FromInitializerList)
188 {
189  test_ref_from_initializer_list({3, 6, 8, 9});
190 }
191 
192 TEST(span, FromVector)
193 {
194  std::vector<int> a = {1, 2, 3, 4};
195  Span<int> a_span(a);
196  EXPECT_EQ(a_span.size(), 4);
197  EXPECT_EQ(a_span[0], 1);
198  EXPECT_EQ(a_span[1], 2);
199  EXPECT_EQ(a_span[2], 3);
200  EXPECT_EQ(a_span[3], 4);
201 }
202 
203 TEST(span, FromArray)
204 {
205  std::array<int, 2> a = {5, 6};
206  Span<int> a_span(a);
207  EXPECT_EQ(a_span.size(), 2);
208  EXPECT_EQ(a_span[0], 5);
209  EXPECT_EQ(a_span[1], 6);
210 }
211 
212 TEST(span, Fill)
213 {
214  std::array<int, 5> a = {4, 5, 6, 7, 8};
215  MutableSpan<int> a_span(a);
216  a_span.fill(1);
217  EXPECT_EQ(a[0], 1);
218  EXPECT_EQ(a[1], 1);
219  EXPECT_EQ(a[2], 1);
220  EXPECT_EQ(a[3], 1);
221  EXPECT_EQ(a[4], 1);
222 }
223 
224 TEST(span, FillIndices)
225 {
226  std::array<int, 5> a = {0, 0, 0, 0, 0};
227  MutableSpan<int> a_span(a);
228  a_span.fill_indices({0, 2, 3}, 1);
229  EXPECT_EQ(a[0], 1);
230  EXPECT_EQ(a[1], 0);
231  EXPECT_EQ(a[2], 1);
232  EXPECT_EQ(a[3], 1);
233  EXPECT_EQ(a[4], 0);
234 }
235 
236 TEST(span, SizeInBytes)
237 {
238  std::array<int, 10> a;
239  Span<int> a_span(a);
240  EXPECT_EQ(a_span.size_in_bytes(), static_cast<int64_t>(sizeof(a)));
241  EXPECT_EQ(a_span.size_in_bytes(), 40);
242 }
243 
244 TEST(span, FirstLast)
245 {
246  std::array<int, 4> a = {6, 7, 8, 9};
247  Span<int> a_span(a);
248  EXPECT_EQ(a_span.first(), 6);
249  EXPECT_EQ(a_span.last(), 9);
250 }
251 
252 TEST(span, FirstLast_OneElement)
253 {
254  int a = 3;
255  Span<int> a_span(&a, 1);
256  EXPECT_EQ(a_span.first(), 3);
257  EXPECT_EQ(a_span.last(), 3);
258 }
259 
260 TEST(span, Get)
261 {
262  std::array<int, 3> a = {5, 6, 7};
263  Span<int> a_span(a);
264  EXPECT_EQ(a_span.get(0, 42), 5);
265  EXPECT_EQ(a_span.get(1, 42), 6);
266  EXPECT_EQ(a_span.get(2, 42), 7);
267  EXPECT_EQ(a_span.get(3, 42), 42);
268  EXPECT_EQ(a_span.get(4, 42), 42);
269 }
270 
271 TEST(span, ContainsPtr)
272 {
273  std::array<int, 3> a = {5, 6, 7};
274  int other = 10;
275  Span<int> a_span(a);
276  EXPECT_TRUE(a_span.contains_ptr(&a[0] + 0));
277  EXPECT_TRUE(a_span.contains_ptr(&a[0] + 1));
278  EXPECT_TRUE(a_span.contains_ptr(&a[0] + 2));
279  EXPECT_FALSE(a_span.contains_ptr(&a[0] + 3));
280  int *ptr_before = reinterpret_cast<int *>(reinterpret_cast<uintptr_t>(a.data()) - 1);
281  EXPECT_FALSE(a_span.contains_ptr(ptr_before));
282  EXPECT_FALSE(a_span.contains_ptr(&other));
283 }
284 
285 TEST(span, FirstIndex)
286 {
287  std::array<int, 5> a = {4, 5, 4, 2, 5};
288  Span<int> a_span(a);
289 
290  EXPECT_EQ(a_span.first_index(4), 0);
291  EXPECT_EQ(a_span.first_index(5), 1);
292  EXPECT_EQ(a_span.first_index(2), 3);
293 }
294 
295 TEST(span, CastSameSize)
296 {
297  int value = 0;
298  std::array<int *, 4> a = {&value, nullptr, nullptr, nullptr};
299  Span<int *> a_span = a;
300  Span<float *> new_a_span = a_span.cast<float *>();
301 
302  EXPECT_EQ(a_span.size(), 4);
303  EXPECT_EQ(new_a_span.size(), 4);
304 
305  EXPECT_EQ(a_span[0], &value);
306  EXPECT_EQ(new_a_span[0], (float *)&value);
307 }
308 
309 TEST(span, CastSmallerSize)
310 {
311  std::array<uint32_t, 4> a = {3, 4, 5, 6};
312  Span<uint32_t> a_span = a;
313  Span<uint16_t> new_a_span = a_span.cast<uint16_t>();
314 
315  EXPECT_EQ(a_span.size(), 4);
316  EXPECT_EQ(new_a_span.size(), 8);
317 }
318 
319 TEST(span, CastLargerSize)
320 {
321  std::array<uint16_t, 4> a = {4, 5, 6, 7};
322  Span<uint16_t> a_span = a;
323  Span<uint32_t> new_a_span = a_span.cast<uint32_t>();
324 
325  EXPECT_EQ(a_span.size(), 4);
326  EXPECT_EQ(new_a_span.size(), 2);
327 }
328 
329 TEST(span, VoidPointerSpan)
330 {
331  int a;
332  float b;
333  double c;
334 
335  auto func1 = [](Span<void *> span) { EXPECT_EQ(span.size(), 3); };
336  func1({&a, &b, &c});
337 }
338 
339 TEST(span, CopyFrom)
340 {
341  std::array<int, 4> src = {5, 6, 7, 8};
342  std::array<int, 4> dst = {1, 2, 3, 4};
343 
344  EXPECT_EQ(dst[2], 3);
345  MutableSpan(dst).copy_from(src);
346  EXPECT_EQ(dst[0], 5);
347  EXPECT_EQ(dst[1], 6);
348  EXPECT_EQ(dst[2], 7);
349  EXPECT_EQ(dst[3], 8);
350 }
351 
352 TEST(span, ReverseIterator)
353 {
354  std::array<int, 4> src = {4, 5, 6, 7};
355  Span<int> span = src;
356  Vector<int> reversed_vec;
357 
358  for (auto it = span.rbegin(); it != span.rend(); ++it) {
359  reversed_vec.append(*it);
360  }
361  EXPECT_EQ(reversed_vec.size(), 4);
362  EXPECT_EQ_ARRAY(reversed_vec.data(), Span({7, 6, 5, 4}).data(), 4);
363 }
364 
365 TEST(span, MutableReverseIterator)
366 {
367  std::array<int, 4> src = {4, 5, 6, 7};
368  MutableSpan<int> span = src;
369  Vector<int> reversed_vec;
370 
371  for (auto it = span.rbegin(); it != span.rend(); ++it) {
372  reversed_vec.append(*it);
373  *it += 10;
374  }
375  EXPECT_EQ(reversed_vec.size(), 4);
376  EXPECT_EQ_ARRAY(reversed_vec.data(), Span({7, 6, 5, 4}).data(), 4);
377  EXPECT_EQ_ARRAY(src.data(), Span({14, 15, 16, 17}).data(), 4);
378 }
379 
380 TEST(span, Constexpr)
381 {
382  static constexpr std::array<int, 3> src = {3, 2, 1};
383  constexpr Span<int> span(src);
384  BLI_STATIC_ASSERT(span[2] == 1, "");
385  BLI_STATIC_ASSERT(span.size() == 3, "");
386  BLI_STATIC_ASSERT(span.slice(1, 2).size() == 2, "");
387  BLI_STATIC_ASSERT(span.has_duplicates__linear_search() == false, "");
388 
389  std::integral_constant<bool, span.first_index(1) == 2> ic;
390  BLI_STATIC_ASSERT(ic.value, "");
391 
392  EXPECT_EQ(span.slice(1, 2).size(), 2);
393 }
394 
395 TEST(span, ImplicitConversions)
396 {
397  BLI_STATIC_ASSERT((std::is_convertible_v<MutableSpan<int>, Span<int>>), "");
398  BLI_STATIC_ASSERT((std::is_convertible_v<Span<int *>, Span<const int *>>), "");
399  BLI_STATIC_ASSERT((std::is_convertible_v<MutableSpan<int *>, Span<int *>>), "");
400  BLI_STATIC_ASSERT((std::is_convertible_v<MutableSpan<int *>, Span<const int *>>), "");
401  BLI_STATIC_ASSERT((std::is_convertible_v<MutableSpan<int *>, MutableSpan<const int *>>), "");
402  BLI_STATIC_ASSERT((!std::is_convertible_v<MutableSpan<const int *>, MutableSpan<int *>>), "");
403  BLI_STATIC_ASSERT((!std::is_convertible_v<Span<const int *>, Span<int *>>), "");
404  BLI_STATIC_ASSERT((!std::is_convertible_v<Span<int *>, MutableSpan<const int *>>), "");
405 }
406 
407 TEST(span, Comparison)
408 {
409  std::array<int, 3> a = {3, 4, 5};
410  std::array<int, 4> b = {3, 4, 5, 6};
411 
412  EXPECT_FALSE(Span(a) == Span(b));
413  EXPECT_FALSE(Span(b) == Span(a));
414  EXPECT_TRUE(Span(a) == Span(b).take_front(3));
415  EXPECT_TRUE(Span(a) == Span(a));
416  EXPECT_TRUE(Span(b) == Span(b));
417 
418  EXPECT_TRUE(Span(a) != Span(b));
419  EXPECT_TRUE(Span(b) != Span(a));
420  EXPECT_FALSE(Span(a) != Span(b).take_front(3));
421  EXPECT_FALSE(Span(a) != Span(a));
422 }
423 
424 } // namespace blender::tests
#define BLI_STATIC_ASSERT(a, msg)
Definition: BLI_assert.h:86
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 ARRAY_SIZE(arr)
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White RGB Map Separate Set Z Dilate Combine Combine Color Channel Split ID Combine Luminance Directional Alpha Distance Hue Movie Ellipse Bokeh View Corner Anti Mix RGB Hue Separate TEX_NODE_PROC TEX_NODE_PROC TEX_NODE_PROC TEX_NODE_PROC TEX_NODE_PROC Boolean Random Edge Subdivision Point Object Attribute Attribute Fill
constexpr int64_t size() const
Definition: BLI_span.hh:524
constexpr void fill(const T &value)
Definition: BLI_span.hh:540
constexpr MutableSpan slice(const int64_t start, const int64_t size) const
Definition: BLI_span.hh:594
constexpr bool is_empty() const
Definition: BLI_span.hh:532
constexpr MutableSpan take_back(const int64_t n) const
Definition: BLI_span.hh:639
constexpr MutableSpan drop_front(const int64_t n) const
Definition: BLI_span.hh:606
constexpr void fill_indices(Span< int64_t > indices, const T &value)
Definition: BLI_span.hh:549
constexpr void copy_from(Span< T > values)
Definition: BLI_span.hh:694
constexpr std::reverse_iterator< T * > rend() const
Definition: BLI_span.hh:579
constexpr std::reverse_iterator< T * > rbegin() const
Definition: BLI_span.hh:575
constexpr MutableSpan take_front(const int64_t n) const
Definition: BLI_span.hh:628
constexpr std::reverse_iterator< const T * > rend() const
Definition: BLI_span.hh:235
constexpr Span drop_front(int64_t n) const
Definition: BLI_span.hh:173
constexpr std::reverse_iterator< const T * > rbegin() const
Definition: BLI_span.hh:231
constexpr Span slice(int64_t start, int64_t size) const
Definition: BLI_span.hh:156
constexpr int64_t size_in_bytes() const
Definition: BLI_span.hh:270
constexpr Span take_back(int64_t n) const
Definition: BLI_span.hh:206
constexpr const T & last() const
Definition: BLI_span.hh:327
constexpr Span drop_back(int64_t n) const
Definition: BLI_span.hh:184
constexpr T get(int64_t index, const T &fallback) const
Definition: BLI_span.hh:337
constexpr int64_t count(const T &value) const
Definition: BLI_span.hh:302
constexpr const T & first() const
Definition: BLI_span.hh:317
constexpr int64_t first_index(const T &search_value) const
Definition: BLI_span.hh:390
constexpr int64_t size() const
Definition: BLI_span.hh:254
constexpr Span< NewT > cast() const
Definition: BLI_span.hh:422
constexpr Span take_front(int64_t n) const
Definition: BLI_span.hh:195
constexpr bool is_empty() const
Definition: BLI_span.hh:262
constexpr bool contains(const T &value) const
Definition: BLI_span.hh:279
constexpr bool contains_ptr(const T *ptr) const
Definition: BLI_span.hh:293
int64_t size() const
Definition: BLI_vector.hh:662
void append(const T &value)
Definition: BLI_vector.hh:438
static unsigned c
Definition: RandGen.cpp:97
static unsigned a[3]
Definition: RandGen.cpp:92
static void test_ref_from_initializer_list(Span< int > span)
TEST(array, DefaultConstructor)
unsigned short uint16_t
Definition: stdint.h:82
_W64 unsigned int uintptr_t
Definition: stdint.h:122
unsigned int uint32_t
Definition: stdint.h:83
__int64 int64_t
Definition: stdint.h:92