1 //
2 // Copyright 2019 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // span_unittests.cpp: Unit tests for the TSpan class.
7 //
8
9 #include "Common.h"
10
11 #include <gtest/gtest.h>
12
13 using namespace angle;
14
15 namespace
16 {
17
18 using Span = sh::TSpan<const unsigned int>;
19 constexpr size_t kSpanDataSize = 16;
20 constexpr unsigned int kSpanData[kSpanDataSize] = {0, 1, 2, 3, 4, 5, 6, 7,
21 8, 9, 10, 11, 12, 13, 14, 15};
22
23 // Test that comparing spans work
TEST(SpanTest,Comparison)24 TEST(SpanTest, Comparison)
25 {
26 // Duplicate data to make sure comparison is being done on values (and not addresses).
27 constexpr unsigned int kSpanDataDup[kSpanDataSize] = {0, 1, 2, 3, 4, 5, 6, 7,
28 8, 9, 10, 11, 12, 13, 14, 15};
29
30 // Don't use ASSERT_EQ at first because the == is more hidden
31 ASSERT_TRUE(Span() == Span(kSpanData, 0));
32 ASSERT_TRUE(Span(kSpanData + 3, 4) != Span(kSpanDataDup + 5, 4));
33
34 // Check ASSERT_EQ and ASSERT_NE work correctly
35 ASSERT_EQ(Span(kSpanData, kSpanDataSize), Span(kSpanDataDup, kSpanDataSize));
36 ASSERT_NE(Span(kSpanData, kSpanDataSize - 1), Span(kSpanDataDup + 1, kSpanDataSize - 1));
37 ASSERT_NE(Span(kSpanData, kSpanDataSize), Span(kSpanDataDup, kSpanDataSize - 1));
38 ASSERT_NE(Span(kSpanData, kSpanDataSize - 1), Span(kSpanDataDup, kSpanDataSize));
39 ASSERT_NE(Span(kSpanData, 0), Span(kSpanDataDup, 1));
40 ASSERT_NE(Span(kSpanData, 1), Span(kSpanDataDup, 0));
41 }
42
43 // Test indexing
TEST(SpanTest,Indexing)44 TEST(SpanTest, Indexing)
45 {
46 constexpr Span sp(kSpanData, kSpanDataSize);
47
48 for (size_t i = 0; i < kSpanDataSize; ++i)
49 {
50 ASSERT_EQ(sp[i], i);
51 }
52
53 unsigned int storage[kSpanDataSize] = {};
54 sh::TSpan<unsigned int> writableSpan(storage, kSpanDataSize);
55
56 for (size_t i = 0; i < kSpanDataSize; ++i)
57 {
58 writableSpan[i] = i;
59 }
60 for (size_t i = 0; i < kSpanDataSize; ++i)
61 {
62 ASSERT_EQ(writableSpan[i], i);
63 }
64 for (size_t i = 0; i < kSpanDataSize; ++i)
65 {
66 ASSERT_EQ(storage[i], i);
67 }
68 }
69
70 // Test for the various constructors
TEST(SpanTest,Constructors)71 TEST(SpanTest, Constructors)
72 {
73 // Default constructor
74 {
75 Span sp;
76 ASSERT_TRUE(sp.size() == 0);
77 ASSERT_TRUE(sp.empty());
78 }
79
80 // Constexpr construct from pointer
81 {
82 constexpr Span sp(kSpanData, kSpanDataSize);
83 ASSERT_EQ(sp.data(), kSpanData);
84 ASSERT_EQ(sp.size(), kSpanDataSize);
85 ASSERT_FALSE(sp.empty());
86 }
87
88 // Copy constructor and copy assignment
89 {
90 Span sp(kSpanData, kSpanDataSize);
91 Span sp2(sp);
92 Span sp3;
93
94 ASSERT_EQ(sp, sp2);
95 ASSERT_EQ(sp2.data(), kSpanData);
96 ASSERT_EQ(sp2.size(), kSpanDataSize);
97 ASSERT_FALSE(sp2.empty());
98
99 sp3 = sp;
100
101 ASSERT_EQ(sp, sp3);
102 ASSERT_EQ(sp3.data(), kSpanData);
103 ASSERT_EQ(sp3.size(), kSpanDataSize);
104 ASSERT_FALSE(sp3.empty());
105 }
106 }
107
108 // Test accessing the data directly
TEST(SpanTest,DataAccess)109 TEST(SpanTest, DataAccess)
110 {
111 constexpr Span sp(kSpanData, kSpanDataSize);
112 const unsigned int *data = sp.data();
113
114 for (size_t i = 0; i < kSpanDataSize; ++i)
115 {
116 ASSERT_EQ(data[i], i);
117 }
118 }
119
120 // Test front and back
TEST(SpanTest,FrontAndBack)121 TEST(SpanTest, FrontAndBack)
122 {
123 constexpr Span sp(kSpanData, kSpanDataSize);
124 ASSERT_TRUE(sp.front() == 0);
125 ASSERT_EQ(sp.back(), kSpanDataSize - 1);
126 }
127
128 // Test begin and end
TEST(SpanTest,BeginAndEnd)129 TEST(SpanTest, BeginAndEnd)
130 {
131 constexpr Span sp(kSpanData, kSpanDataSize);
132
133 size_t currentIndex = 0;
134 for (unsigned int value : sp)
135 {
136 ASSERT_EQ(value, currentIndex);
137 ++currentIndex;
138 }
139 }
140
141 // Test reverse begin and end
TEST(SpanTest,RbeginAndRend)142 TEST(SpanTest, RbeginAndRend)
143 {
144 constexpr Span sp(kSpanData, kSpanDataSize);
145
146 size_t currentIndex = 0;
147 for (auto iter = sp.rbegin(); iter != sp.rend(); ++iter)
148 {
149 ASSERT_EQ(*iter, kSpanDataSize - 1 - currentIndex);
150 ++currentIndex;
151 }
152 }
153
154 // Test first and last
TEST(SpanTest,FirstAndLast)155 TEST(SpanTest, FirstAndLast)
156 {
157 constexpr Span sp(kSpanData, kSpanDataSize);
158 constexpr size_t kSplitSize = kSpanDataSize / 4;
159 constexpr Span first = sp.first(kSplitSize);
160 constexpr Span last = sp.last(kSplitSize);
161
162 ASSERT_EQ(first, Span(kSpanData, kSplitSize));
163 ASSERT_EQ(first.data(), kSpanData);
164 ASSERT_EQ(first.size(), kSplitSize);
165
166 ASSERT_EQ(last, Span(kSpanData + kSpanDataSize - kSplitSize, kSplitSize));
167 ASSERT_EQ(last.data(), kSpanData + kSpanDataSize - kSplitSize);
168 ASSERT_EQ(last.size(), kSplitSize);
169 }
170
171 // Test subspan
TEST(SpanTest,Subspan)172 TEST(SpanTest, Subspan)
173 {
174 constexpr Span sp(kSpanData, kSpanDataSize);
175 constexpr size_t kSplitOffset = kSpanDataSize / 4;
176 constexpr size_t kSplitSize = kSpanDataSize / 2;
177 constexpr Span subspan = sp.subspan(kSplitOffset, kSplitSize);
178
179 ASSERT_EQ(subspan, Span(kSpanData + kSplitOffset, kSplitSize));
180 ASSERT_EQ(subspan.data(), kSpanData + kSplitOffset);
181 ASSERT_EQ(subspan.size(), kSplitSize);
182 }
183
184 } // anonymous namespace
185