blob: 1d7158ffc0b934c1582152d91d86153903430a3e [file] [log] [blame]
Austin Schuh36244a12019-09-21 17:52:38 -07001// Copyright 2018 The Abseil Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "absl/container/internal/layout.h"
16
17// We need ::max_align_t because some libstdc++ versions don't provide
18// std::max_align_t
19#include <stddef.h>
Austin Schuhb4691e92020-12-31 12:37:18 -080020
Austin Schuh36244a12019-09-21 17:52:38 -070021#include <cstdint>
22#include <memory>
23#include <sstream>
24#include <type_traits>
25
26#include "gmock/gmock.h"
27#include "gtest/gtest.h"
Austin Schuhb4691e92020-12-31 12:37:18 -080028#include "absl/base/config.h"
Austin Schuh36244a12019-09-21 17:52:38 -070029#include "absl/base/internal/raw_logging.h"
30#include "absl/types/span.h"
31
32namespace absl {
Austin Schuhb4691e92020-12-31 12:37:18 -080033ABSL_NAMESPACE_BEGIN
Austin Schuh36244a12019-09-21 17:52:38 -070034namespace container_internal {
35namespace {
36
37using ::absl::Span;
38using ::testing::ElementsAre;
39
40size_t Distance(const void* from, const void* to) {
41 ABSL_RAW_CHECK(from <= to, "Distance must be non-negative");
42 return static_cast<const char*>(to) - static_cast<const char*>(from);
43}
44
45template <class Expected, class Actual>
46Expected Type(Actual val) {
47 static_assert(std::is_same<Expected, Actual>(), "");
48 return val;
49}
50
51// Helper classes to test different size and alignments.
52struct alignas(8) Int128 {
53 uint64_t a, b;
54 friend bool operator==(Int128 lhs, Int128 rhs) {
55 return std::tie(lhs.a, lhs.b) == std::tie(rhs.a, rhs.b);
56 }
57
58 static std::string Name() {
59 return internal_layout::adl_barrier::TypeName<Int128>();
60 }
61};
62
63// int64_t is *not* 8-byte aligned on all platforms!
64struct alignas(8) Int64 {
65 int64_t a;
66 friend bool operator==(Int64 lhs, Int64 rhs) {
67 return lhs.a == rhs.a;
68 }
69};
70
71// Properties of types that this test relies on.
72static_assert(sizeof(int8_t) == 1, "");
73static_assert(alignof(int8_t) == 1, "");
74static_assert(sizeof(int16_t) == 2, "");
75static_assert(alignof(int16_t) == 2, "");
76static_assert(sizeof(int32_t) == 4, "");
77static_assert(alignof(int32_t) == 4, "");
78static_assert(sizeof(Int64) == 8, "");
79static_assert(alignof(Int64) == 8, "");
80static_assert(sizeof(Int128) == 16, "");
81static_assert(alignof(Int128) == 8, "");
82
83template <class Expected, class Actual>
84void SameType() {
85 static_assert(std::is_same<Expected, Actual>(), "");
86}
87
88TEST(Layout, ElementType) {
89 {
90 using L = Layout<int32_t>;
91 SameType<int32_t, L::ElementType<0>>();
92 SameType<int32_t, decltype(L::Partial())::ElementType<0>>();
93 SameType<int32_t, decltype(L::Partial(0))::ElementType<0>>();
94 }
95 {
96 using L = Layout<int32_t, int32_t>;
97 SameType<int32_t, L::ElementType<0>>();
98 SameType<int32_t, L::ElementType<1>>();
99 SameType<int32_t, decltype(L::Partial())::ElementType<0>>();
100 SameType<int32_t, decltype(L::Partial())::ElementType<1>>();
101 SameType<int32_t, decltype(L::Partial(0))::ElementType<0>>();
102 SameType<int32_t, decltype(L::Partial(0))::ElementType<1>>();
103 }
104 {
105 using L = Layout<int8_t, int32_t, Int128>;
106 SameType<int8_t, L::ElementType<0>>();
107 SameType<int32_t, L::ElementType<1>>();
108 SameType<Int128, L::ElementType<2>>();
109 SameType<int8_t, decltype(L::Partial())::ElementType<0>>();
110 SameType<int8_t, decltype(L::Partial(0))::ElementType<0>>();
111 SameType<int32_t, decltype(L::Partial(0))::ElementType<1>>();
112 SameType<int8_t, decltype(L::Partial(0, 0))::ElementType<0>>();
113 SameType<int32_t, decltype(L::Partial(0, 0))::ElementType<1>>();
114 SameType<Int128, decltype(L::Partial(0, 0))::ElementType<2>>();
115 SameType<int8_t, decltype(L::Partial(0, 0, 0))::ElementType<0>>();
116 SameType<int32_t, decltype(L::Partial(0, 0, 0))::ElementType<1>>();
117 SameType<Int128, decltype(L::Partial(0, 0, 0))::ElementType<2>>();
118 }
119}
120
121TEST(Layout, ElementTypes) {
122 {
123 using L = Layout<int32_t>;
124 SameType<std::tuple<int32_t>, L::ElementTypes>();
125 SameType<std::tuple<int32_t>, decltype(L::Partial())::ElementTypes>();
126 SameType<std::tuple<int32_t>, decltype(L::Partial(0))::ElementTypes>();
127 }
128 {
129 using L = Layout<int32_t, int32_t>;
130 SameType<std::tuple<int32_t, int32_t>, L::ElementTypes>();
Austin Schuhb4691e92020-12-31 12:37:18 -0800131 SameType<std::tuple<int32_t, int32_t>,
132 decltype(L::Partial())::ElementTypes>();
133 SameType<std::tuple<int32_t, int32_t>,
134 decltype(L::Partial(0))::ElementTypes>();
Austin Schuh36244a12019-09-21 17:52:38 -0700135 }
136 {
137 using L = Layout<int8_t, int32_t, Int128>;
138 SameType<std::tuple<int8_t, int32_t, Int128>, L::ElementTypes>();
139 SameType<std::tuple<int8_t, int32_t, Int128>,
140 decltype(L::Partial())::ElementTypes>();
141 SameType<std::tuple<int8_t, int32_t, Int128>,
142 decltype(L::Partial(0))::ElementTypes>();
143 SameType<std::tuple<int8_t, int32_t, Int128>,
144 decltype(L::Partial(0, 0))::ElementTypes>();
145 SameType<std::tuple<int8_t, int32_t, Int128>,
146 decltype(L::Partial(0, 0, 0))::ElementTypes>();
147 }
148}
149
150TEST(Layout, OffsetByIndex) {
151 {
152 using L = Layout<int32_t>;
153 EXPECT_EQ(0, L::Partial().Offset<0>());
154 EXPECT_EQ(0, L::Partial(3).Offset<0>());
155 EXPECT_EQ(0, L(3).Offset<0>());
156 }
157 {
158 using L = Layout<int32_t, int32_t>;
159 EXPECT_EQ(0, L::Partial().Offset<0>());
160 EXPECT_EQ(0, L::Partial(3).Offset<0>());
161 EXPECT_EQ(12, L::Partial(3).Offset<1>());
162 EXPECT_EQ(0, L::Partial(3, 5).Offset<0>());
163 EXPECT_EQ(12, L::Partial(3, 5).Offset<1>());
164 EXPECT_EQ(0, L(3, 5).Offset<0>());
165 EXPECT_EQ(12, L(3, 5).Offset<1>());
166 }
167 {
168 using L = Layout<int8_t, int32_t, Int128>;
169 EXPECT_EQ(0, L::Partial().Offset<0>());
170 EXPECT_EQ(0, L::Partial(0).Offset<0>());
171 EXPECT_EQ(0, L::Partial(0).Offset<1>());
172 EXPECT_EQ(0, L::Partial(1).Offset<0>());
173 EXPECT_EQ(4, L::Partial(1).Offset<1>());
174 EXPECT_EQ(0, L::Partial(5).Offset<0>());
175 EXPECT_EQ(8, L::Partial(5).Offset<1>());
176 EXPECT_EQ(0, L::Partial(0, 0).Offset<0>());
177 EXPECT_EQ(0, L::Partial(0, 0).Offset<1>());
178 EXPECT_EQ(0, L::Partial(0, 0).Offset<2>());
179 EXPECT_EQ(0, L::Partial(1, 0).Offset<0>());
180 EXPECT_EQ(4, L::Partial(1, 0).Offset<1>());
181 EXPECT_EQ(8, L::Partial(1, 0).Offset<2>());
182 EXPECT_EQ(0, L::Partial(5, 3).Offset<0>());
183 EXPECT_EQ(8, L::Partial(5, 3).Offset<1>());
184 EXPECT_EQ(24, L::Partial(5, 3).Offset<2>());
185 EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<0>());
186 EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<1>());
187 EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<2>());
188 EXPECT_EQ(0, L::Partial(1, 0, 0).Offset<0>());
189 EXPECT_EQ(4, L::Partial(1, 0, 0).Offset<1>());
190 EXPECT_EQ(8, L::Partial(1, 0, 0).Offset<2>());
191 EXPECT_EQ(0, L::Partial(5, 3, 1).Offset<0>());
192 EXPECT_EQ(24, L::Partial(5, 3, 1).Offset<2>());
193 EXPECT_EQ(8, L::Partial(5, 3, 1).Offset<1>());
194 EXPECT_EQ(0, L(5, 3, 1).Offset<0>());
195 EXPECT_EQ(24, L(5, 3, 1).Offset<2>());
196 EXPECT_EQ(8, L(5, 3, 1).Offset<1>());
197 }
198}
199
200TEST(Layout, OffsetByType) {
201 {
202 using L = Layout<int32_t>;
203 EXPECT_EQ(0, L::Partial().Offset<int32_t>());
204 EXPECT_EQ(0, L::Partial(3).Offset<int32_t>());
205 EXPECT_EQ(0, L(3).Offset<int32_t>());
206 }
207 {
208 using L = Layout<int8_t, int32_t, Int128>;
209 EXPECT_EQ(0, L::Partial().Offset<int8_t>());
210 EXPECT_EQ(0, L::Partial(0).Offset<int8_t>());
211 EXPECT_EQ(0, L::Partial(0).Offset<int32_t>());
212 EXPECT_EQ(0, L::Partial(1).Offset<int8_t>());
213 EXPECT_EQ(4, L::Partial(1).Offset<int32_t>());
214 EXPECT_EQ(0, L::Partial(5).Offset<int8_t>());
215 EXPECT_EQ(8, L::Partial(5).Offset<int32_t>());
216 EXPECT_EQ(0, L::Partial(0, 0).Offset<int8_t>());
217 EXPECT_EQ(0, L::Partial(0, 0).Offset<int32_t>());
218 EXPECT_EQ(0, L::Partial(0, 0).Offset<Int128>());
219 EXPECT_EQ(0, L::Partial(1, 0).Offset<int8_t>());
220 EXPECT_EQ(4, L::Partial(1, 0).Offset<int32_t>());
221 EXPECT_EQ(8, L::Partial(1, 0).Offset<Int128>());
222 EXPECT_EQ(0, L::Partial(5, 3).Offset<int8_t>());
223 EXPECT_EQ(8, L::Partial(5, 3).Offset<int32_t>());
224 EXPECT_EQ(24, L::Partial(5, 3).Offset<Int128>());
225 EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<int8_t>());
226 EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<int32_t>());
227 EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<Int128>());
228 EXPECT_EQ(0, L::Partial(1, 0, 0).Offset<int8_t>());
229 EXPECT_EQ(4, L::Partial(1, 0, 0).Offset<int32_t>());
230 EXPECT_EQ(8, L::Partial(1, 0, 0).Offset<Int128>());
231 EXPECT_EQ(0, L::Partial(5, 3, 1).Offset<int8_t>());
232 EXPECT_EQ(24, L::Partial(5, 3, 1).Offset<Int128>());
233 EXPECT_EQ(8, L::Partial(5, 3, 1).Offset<int32_t>());
234 EXPECT_EQ(0, L(5, 3, 1).Offset<int8_t>());
235 EXPECT_EQ(24, L(5, 3, 1).Offset<Int128>());
236 EXPECT_EQ(8, L(5, 3, 1).Offset<int32_t>());
237 }
238}
239
240TEST(Layout, Offsets) {
241 {
242 using L = Layout<int32_t>;
243 EXPECT_THAT(L::Partial().Offsets(), ElementsAre(0));
244 EXPECT_THAT(L::Partial(3).Offsets(), ElementsAre(0));
245 EXPECT_THAT(L(3).Offsets(), ElementsAre(0));
246 }
247 {
248 using L = Layout<int32_t, int32_t>;
249 EXPECT_THAT(L::Partial().Offsets(), ElementsAre(0));
250 EXPECT_THAT(L::Partial(3).Offsets(), ElementsAre(0, 12));
251 EXPECT_THAT(L::Partial(3, 5).Offsets(), ElementsAre(0, 12));
252 EXPECT_THAT(L(3, 5).Offsets(), ElementsAre(0, 12));
253 }
254 {
255 using L = Layout<int8_t, int32_t, Int128>;
256 EXPECT_THAT(L::Partial().Offsets(), ElementsAre(0));
257 EXPECT_THAT(L::Partial(1).Offsets(), ElementsAre(0, 4));
258 EXPECT_THAT(L::Partial(5).Offsets(), ElementsAre(0, 8));
259 EXPECT_THAT(L::Partial(0, 0).Offsets(), ElementsAre(0, 0, 0));
260 EXPECT_THAT(L::Partial(1, 0).Offsets(), ElementsAre(0, 4, 8));
261 EXPECT_THAT(L::Partial(5, 3).Offsets(), ElementsAre(0, 8, 24));
262 EXPECT_THAT(L::Partial(0, 0, 0).Offsets(), ElementsAre(0, 0, 0));
263 EXPECT_THAT(L::Partial(1, 0, 0).Offsets(), ElementsAre(0, 4, 8));
264 EXPECT_THAT(L::Partial(5, 3, 1).Offsets(), ElementsAre(0, 8, 24));
265 EXPECT_THAT(L(5, 3, 1).Offsets(), ElementsAre(0, 8, 24));
266 }
267}
268
269TEST(Layout, AllocSize) {
270 {
271 using L = Layout<int32_t>;
272 EXPECT_EQ(0, L::Partial(0).AllocSize());
273 EXPECT_EQ(12, L::Partial(3).AllocSize());
274 EXPECT_EQ(12, L(3).AllocSize());
275 }
276 {
277 using L = Layout<int32_t, int32_t>;
278 EXPECT_EQ(32, L::Partial(3, 5).AllocSize());
279 EXPECT_EQ(32, L(3, 5).AllocSize());
280 }
281 {
282 using L = Layout<int8_t, int32_t, Int128>;
283 EXPECT_EQ(0, L::Partial(0, 0, 0).AllocSize());
284 EXPECT_EQ(8, L::Partial(1, 0, 0).AllocSize());
285 EXPECT_EQ(8, L::Partial(0, 1, 0).AllocSize());
286 EXPECT_EQ(16, L::Partial(0, 0, 1).AllocSize());
287 EXPECT_EQ(24, L::Partial(1, 1, 1).AllocSize());
288 EXPECT_EQ(136, L::Partial(3, 5, 7).AllocSize());
289 EXPECT_EQ(136, L(3, 5, 7).AllocSize());
290 }
291}
292
293TEST(Layout, SizeByIndex) {
294 {
295 using L = Layout<int32_t>;
296 EXPECT_EQ(0, L::Partial(0).Size<0>());
297 EXPECT_EQ(3, L::Partial(3).Size<0>());
298 EXPECT_EQ(3, L(3).Size<0>());
299 }
300 {
301 using L = Layout<int32_t, int32_t>;
302 EXPECT_EQ(0, L::Partial(0).Size<0>());
303 EXPECT_EQ(3, L::Partial(3).Size<0>());
304 EXPECT_EQ(3, L::Partial(3, 5).Size<0>());
305 EXPECT_EQ(5, L::Partial(3, 5).Size<1>());
306 EXPECT_EQ(3, L(3, 5).Size<0>());
307 EXPECT_EQ(5, L(3, 5).Size<1>());
308 }
309 {
310 using L = Layout<int8_t, int32_t, Int128>;
311 EXPECT_EQ(3, L::Partial(3).Size<0>());
312 EXPECT_EQ(3, L::Partial(3, 5).Size<0>());
313 EXPECT_EQ(5, L::Partial(3, 5).Size<1>());
314 EXPECT_EQ(3, L::Partial(3, 5, 7).Size<0>());
315 EXPECT_EQ(5, L::Partial(3, 5, 7).Size<1>());
316 EXPECT_EQ(7, L::Partial(3, 5, 7).Size<2>());
317 EXPECT_EQ(3, L(3, 5, 7).Size<0>());
318 EXPECT_EQ(5, L(3, 5, 7).Size<1>());
319 EXPECT_EQ(7, L(3, 5, 7).Size<2>());
320 }
321}
322
323TEST(Layout, SizeByType) {
324 {
325 using L = Layout<int32_t>;
326 EXPECT_EQ(0, L::Partial(0).Size<int32_t>());
327 EXPECT_EQ(3, L::Partial(3).Size<int32_t>());
328 EXPECT_EQ(3, L(3).Size<int32_t>());
329 }
330 {
331 using L = Layout<int8_t, int32_t, Int128>;
332 EXPECT_EQ(3, L::Partial(3).Size<int8_t>());
333 EXPECT_EQ(3, L::Partial(3, 5).Size<int8_t>());
334 EXPECT_EQ(5, L::Partial(3, 5).Size<int32_t>());
335 EXPECT_EQ(3, L::Partial(3, 5, 7).Size<int8_t>());
336 EXPECT_EQ(5, L::Partial(3, 5, 7).Size<int32_t>());
337 EXPECT_EQ(7, L::Partial(3, 5, 7).Size<Int128>());
338 EXPECT_EQ(3, L(3, 5, 7).Size<int8_t>());
339 EXPECT_EQ(5, L(3, 5, 7).Size<int32_t>());
340 EXPECT_EQ(7, L(3, 5, 7).Size<Int128>());
341 }
342}
343
344TEST(Layout, Sizes) {
345 {
346 using L = Layout<int32_t>;
347 EXPECT_THAT(L::Partial().Sizes(), ElementsAre());
348 EXPECT_THAT(L::Partial(3).Sizes(), ElementsAre(3));
349 EXPECT_THAT(L(3).Sizes(), ElementsAre(3));
350 }
351 {
352 using L = Layout<int32_t, int32_t>;
353 EXPECT_THAT(L::Partial().Sizes(), ElementsAre());
354 EXPECT_THAT(L::Partial(3).Sizes(), ElementsAre(3));
355 EXPECT_THAT(L::Partial(3, 5).Sizes(), ElementsAre(3, 5));
356 EXPECT_THAT(L(3, 5).Sizes(), ElementsAre(3, 5));
357 }
358 {
359 using L = Layout<int8_t, int32_t, Int128>;
360 EXPECT_THAT(L::Partial().Sizes(), ElementsAre());
361 EXPECT_THAT(L::Partial(3).Sizes(), ElementsAre(3));
362 EXPECT_THAT(L::Partial(3, 5).Sizes(), ElementsAre(3, 5));
363 EXPECT_THAT(L::Partial(3, 5, 7).Sizes(), ElementsAre(3, 5, 7));
364 EXPECT_THAT(L(3, 5, 7).Sizes(), ElementsAre(3, 5, 7));
365 }
366}
367
368TEST(Layout, PointerByIndex) {
369 alignas(max_align_t) const unsigned char p[100] = {};
370 {
371 using L = Layout<int32_t>;
372 EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L::Partial().Pointer<0>(p))));
Austin Schuhb4691e92020-12-31 12:37:18 -0800373 EXPECT_EQ(0,
374 Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<0>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700375 EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L(3).Pointer<0>(p))));
376 }
377 {
378 using L = Layout<int32_t, int32_t>;
379 EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L::Partial().Pointer<0>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700380 EXPECT_EQ(0,
Austin Schuhb4691e92020-12-31 12:37:18 -0800381 Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<0>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700382 EXPECT_EQ(12,
Austin Schuhb4691e92020-12-31 12:37:18 -0800383 Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<1>(p))));
384 EXPECT_EQ(
385 0, Distance(p, Type<const int32_t*>(L::Partial(3, 5).Pointer<0>(p))));
386 EXPECT_EQ(
387 12, Distance(p, Type<const int32_t*>(L::Partial(3, 5).Pointer<1>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700388 EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L(3, 5).Pointer<0>(p))));
389 EXPECT_EQ(12, Distance(p, Type<const int32_t*>(L(3, 5).Pointer<1>(p))));
390 }
391 {
392 using L = Layout<int8_t, int32_t, Int128>;
393 EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial().Pointer<0>(p))));
394 EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial(0).Pointer<0>(p))));
Austin Schuhb4691e92020-12-31 12:37:18 -0800395 EXPECT_EQ(0,
396 Distance(p, Type<const int32_t*>(L::Partial(0).Pointer<1>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700397 EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial(1).Pointer<0>(p))));
Austin Schuhb4691e92020-12-31 12:37:18 -0800398 EXPECT_EQ(4,
399 Distance(p, Type<const int32_t*>(L::Partial(1).Pointer<1>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700400 EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial(5).Pointer<0>(p))));
Austin Schuhb4691e92020-12-31 12:37:18 -0800401 EXPECT_EQ(8,
402 Distance(p, Type<const int32_t*>(L::Partial(5).Pointer<1>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700403 EXPECT_EQ(0,
404 Distance(p, Type<const int8_t*>(L::Partial(0, 0).Pointer<0>(p))));
Austin Schuhb4691e92020-12-31 12:37:18 -0800405 EXPECT_EQ(
406 0, Distance(p, Type<const int32_t*>(L::Partial(0, 0).Pointer<1>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700407 EXPECT_EQ(0,
408 Distance(p, Type<const Int128*>(L::Partial(0, 0).Pointer<2>(p))));
409 EXPECT_EQ(0,
410 Distance(p, Type<const int8_t*>(L::Partial(1, 0).Pointer<0>(p))));
Austin Schuhb4691e92020-12-31 12:37:18 -0800411 EXPECT_EQ(
412 4, Distance(p, Type<const int32_t*>(L::Partial(1, 0).Pointer<1>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700413 EXPECT_EQ(8,
414 Distance(p, Type<const Int128*>(L::Partial(1, 0).Pointer<2>(p))));
415 EXPECT_EQ(0,
416 Distance(p, Type<const int8_t*>(L::Partial(5, 3).Pointer<0>(p))));
Austin Schuhb4691e92020-12-31 12:37:18 -0800417 EXPECT_EQ(
418 8, Distance(p, Type<const int32_t*>(L::Partial(5, 3).Pointer<1>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700419 EXPECT_EQ(24,
420 Distance(p, Type<const Int128*>(L::Partial(5, 3).Pointer<2>(p))));
421 EXPECT_EQ(
422 0, Distance(p, Type<const int8_t*>(L::Partial(0, 0, 0).Pointer<0>(p))));
423 EXPECT_EQ(
Austin Schuhb4691e92020-12-31 12:37:18 -0800424 0,
425 Distance(p, Type<const int32_t*>(L::Partial(0, 0, 0).Pointer<1>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700426 EXPECT_EQ(
427 0, Distance(p, Type<const Int128*>(L::Partial(0, 0, 0).Pointer<2>(p))));
428 EXPECT_EQ(
429 0, Distance(p, Type<const int8_t*>(L::Partial(1, 0, 0).Pointer<0>(p))));
430 EXPECT_EQ(
Austin Schuhb4691e92020-12-31 12:37:18 -0800431 4,
432 Distance(p, Type<const int32_t*>(L::Partial(1, 0, 0).Pointer<1>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700433 EXPECT_EQ(
434 8, Distance(p, Type<const Int128*>(L::Partial(1, 0, 0).Pointer<2>(p))));
435 EXPECT_EQ(
436 0, Distance(p, Type<const int8_t*>(L::Partial(5, 3, 1).Pointer<0>(p))));
437 EXPECT_EQ(
438 24,
439 Distance(p, Type<const Int128*>(L::Partial(5, 3, 1).Pointer<2>(p))));
440 EXPECT_EQ(
Austin Schuhb4691e92020-12-31 12:37:18 -0800441 8,
442 Distance(p, Type<const int32_t*>(L::Partial(5, 3, 1).Pointer<1>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700443 EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L(5, 3, 1).Pointer<0>(p))));
444 EXPECT_EQ(24, Distance(p, Type<const Int128*>(L(5, 3, 1).Pointer<2>(p))));
445 EXPECT_EQ(8, Distance(p, Type<const int32_t*>(L(5, 3, 1).Pointer<1>(p))));
446 }
447}
448
449TEST(Layout, PointerByType) {
450 alignas(max_align_t) const unsigned char p[100] = {};
451 {
452 using L = Layout<int32_t>;
Austin Schuhb4691e92020-12-31 12:37:18 -0800453 EXPECT_EQ(
454 0, Distance(p, Type<const int32_t*>(L::Partial().Pointer<int32_t>(p))));
455 EXPECT_EQ(
456 0,
457 Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<int32_t>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700458 EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L(3).Pointer<int32_t>(p))));
459 }
460 {
461 using L = Layout<int8_t, int32_t, Int128>;
Austin Schuh36244a12019-09-21 17:52:38 -0700462 EXPECT_EQ(
Austin Schuhb4691e92020-12-31 12:37:18 -0800463 0, Distance(p, Type<const int8_t*>(L::Partial().Pointer<int8_t>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700464 EXPECT_EQ(
Austin Schuhb4691e92020-12-31 12:37:18 -0800465 0, Distance(p, Type<const int8_t*>(L::Partial(0).Pointer<int8_t>(p))));
466 EXPECT_EQ(
467 0,
468 Distance(p, Type<const int32_t*>(L::Partial(0).Pointer<int32_t>(p))));
469 EXPECT_EQ(
470 0, Distance(p, Type<const int8_t*>(L::Partial(1).Pointer<int8_t>(p))));
471 EXPECT_EQ(
472 4,
473 Distance(p, Type<const int32_t*>(L::Partial(1).Pointer<int32_t>(p))));
474 EXPECT_EQ(
475 0, Distance(p, Type<const int8_t*>(L::Partial(5).Pointer<int8_t>(p))));
476 EXPECT_EQ(
477 8,
478 Distance(p, Type<const int32_t*>(L::Partial(5).Pointer<int32_t>(p))));
479 EXPECT_EQ(
480 0,
481 Distance(p, Type<const int8_t*>(L::Partial(0, 0).Pointer<int8_t>(p))));
482 EXPECT_EQ(0, Distance(p, Type<const int32_t*>(
483 L::Partial(0, 0).Pointer<int32_t>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700484 EXPECT_EQ(
485 0,
486 Distance(p, Type<const Int128*>(L::Partial(0, 0).Pointer<Int128>(p))));
487 EXPECT_EQ(
Austin Schuhb4691e92020-12-31 12:37:18 -0800488 0,
489 Distance(p, Type<const int8_t*>(L::Partial(1, 0).Pointer<int8_t>(p))));
490 EXPECT_EQ(4, Distance(p, Type<const int32_t*>(
491 L::Partial(1, 0).Pointer<int32_t>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700492 EXPECT_EQ(
493 8,
494 Distance(p, Type<const Int128*>(L::Partial(1, 0).Pointer<Int128>(p))));
495 EXPECT_EQ(
Austin Schuhb4691e92020-12-31 12:37:18 -0800496 0,
497 Distance(p, Type<const int8_t*>(L::Partial(5, 3).Pointer<int8_t>(p))));
498 EXPECT_EQ(8, Distance(p, Type<const int32_t*>(
499 L::Partial(5, 3).Pointer<int32_t>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700500 EXPECT_EQ(
501 24,
502 Distance(p, Type<const Int128*>(L::Partial(5, 3).Pointer<Int128>(p))));
Austin Schuhb4691e92020-12-31 12:37:18 -0800503 EXPECT_EQ(0, Distance(p, Type<const int8_t*>(
504 L::Partial(0, 0, 0).Pointer<int8_t>(p))));
505 EXPECT_EQ(0, Distance(p, Type<const int32_t*>(
506 L::Partial(0, 0, 0).Pointer<int32_t>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700507 EXPECT_EQ(0, Distance(p, Type<const Int128*>(
508 L::Partial(0, 0, 0).Pointer<Int128>(p))));
Austin Schuhb4691e92020-12-31 12:37:18 -0800509 EXPECT_EQ(0, Distance(p, Type<const int8_t*>(
510 L::Partial(1, 0, 0).Pointer<int8_t>(p))));
511 EXPECT_EQ(4, Distance(p, Type<const int32_t*>(
512 L::Partial(1, 0, 0).Pointer<int32_t>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700513 EXPECT_EQ(8, Distance(p, Type<const Int128*>(
514 L::Partial(1, 0, 0).Pointer<Int128>(p))));
Austin Schuhb4691e92020-12-31 12:37:18 -0800515 EXPECT_EQ(0, Distance(p, Type<const int8_t*>(
516 L::Partial(5, 3, 1).Pointer<int8_t>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700517 EXPECT_EQ(24, Distance(p, Type<const Int128*>(
518 L::Partial(5, 3, 1).Pointer<Int128>(p))));
Austin Schuhb4691e92020-12-31 12:37:18 -0800519 EXPECT_EQ(8, Distance(p, Type<const int32_t*>(
520 L::Partial(5, 3, 1).Pointer<int32_t>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700521 EXPECT_EQ(24,
522 Distance(p, Type<const Int128*>(L(5, 3, 1).Pointer<Int128>(p))));
Austin Schuhb4691e92020-12-31 12:37:18 -0800523 EXPECT_EQ(
524 8, Distance(p, Type<const int32_t*>(L(5, 3, 1).Pointer<int32_t>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700525 }
526}
527
528TEST(Layout, MutablePointerByIndex) {
529 alignas(max_align_t) unsigned char p[100];
530 {
531 using L = Layout<int32_t>;
532 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial().Pointer<0>(p))));
533 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(3).Pointer<0>(p))));
534 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L(3).Pointer<0>(p))));
535 }
536 {
537 using L = Layout<int32_t, int32_t>;
538 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial().Pointer<0>(p))));
539 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(3).Pointer<0>(p))));
540 EXPECT_EQ(12, Distance(p, Type<int32_t*>(L::Partial(3).Pointer<1>(p))));
541 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(3, 5).Pointer<0>(p))));
542 EXPECT_EQ(12, Distance(p, Type<int32_t*>(L::Partial(3, 5).Pointer<1>(p))));
543 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L(3, 5).Pointer<0>(p))));
544 EXPECT_EQ(12, Distance(p, Type<int32_t*>(L(3, 5).Pointer<1>(p))));
545 }
546 {
547 using L = Layout<int8_t, int32_t, Int128>;
548 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial().Pointer<0>(p))));
549 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0).Pointer<0>(p))));
550 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(0).Pointer<1>(p))));
551 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1).Pointer<0>(p))));
552 EXPECT_EQ(4, Distance(p, Type<int32_t*>(L::Partial(1).Pointer<1>(p))));
553 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5).Pointer<0>(p))));
554 EXPECT_EQ(8, Distance(p, Type<int32_t*>(L::Partial(5).Pointer<1>(p))));
555 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0, 0).Pointer<0>(p))));
556 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(0, 0).Pointer<1>(p))));
557 EXPECT_EQ(0, Distance(p, Type<Int128*>(L::Partial(0, 0).Pointer<2>(p))));
558 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1, 0).Pointer<0>(p))));
559 EXPECT_EQ(4, Distance(p, Type<int32_t*>(L::Partial(1, 0).Pointer<1>(p))));
560 EXPECT_EQ(8, Distance(p, Type<Int128*>(L::Partial(1, 0).Pointer<2>(p))));
561 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5, 3).Pointer<0>(p))));
562 EXPECT_EQ(8, Distance(p, Type<int32_t*>(L::Partial(5, 3).Pointer<1>(p))));
563 EXPECT_EQ(24, Distance(p, Type<Int128*>(L::Partial(5, 3).Pointer<2>(p))));
564 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0, 0, 0).Pointer<0>(p))));
Austin Schuhb4691e92020-12-31 12:37:18 -0800565 EXPECT_EQ(0,
566 Distance(p, Type<int32_t*>(L::Partial(0, 0, 0).Pointer<1>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700567 EXPECT_EQ(0, Distance(p, Type<Int128*>(L::Partial(0, 0, 0).Pointer<2>(p))));
568 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1, 0, 0).Pointer<0>(p))));
Austin Schuhb4691e92020-12-31 12:37:18 -0800569 EXPECT_EQ(4,
570 Distance(p, Type<int32_t*>(L::Partial(1, 0, 0).Pointer<1>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700571 EXPECT_EQ(8, Distance(p, Type<Int128*>(L::Partial(1, 0, 0).Pointer<2>(p))));
572 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5, 3, 1).Pointer<0>(p))));
573 EXPECT_EQ(24,
574 Distance(p, Type<Int128*>(L::Partial(5, 3, 1).Pointer<2>(p))));
Austin Schuhb4691e92020-12-31 12:37:18 -0800575 EXPECT_EQ(8,
576 Distance(p, Type<int32_t*>(L::Partial(5, 3, 1).Pointer<1>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700577 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L(5, 3, 1).Pointer<0>(p))));
578 EXPECT_EQ(24, Distance(p, Type<Int128*>(L(5, 3, 1).Pointer<2>(p))));
579 EXPECT_EQ(8, Distance(p, Type<int32_t*>(L(5, 3, 1).Pointer<1>(p))));
580 }
581}
582
583TEST(Layout, MutablePointerByType) {
584 alignas(max_align_t) unsigned char p[100];
585 {
586 using L = Layout<int32_t>;
587 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial().Pointer<int32_t>(p))));
Austin Schuhb4691e92020-12-31 12:37:18 -0800588 EXPECT_EQ(0,
589 Distance(p, Type<int32_t*>(L::Partial(3).Pointer<int32_t>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700590 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L(3).Pointer<int32_t>(p))));
591 }
592 {
593 using L = Layout<int8_t, int32_t, Int128>;
594 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial().Pointer<int8_t>(p))));
595 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0).Pointer<int8_t>(p))));
Austin Schuhb4691e92020-12-31 12:37:18 -0800596 EXPECT_EQ(0,
597 Distance(p, Type<int32_t*>(L::Partial(0).Pointer<int32_t>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700598 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1).Pointer<int8_t>(p))));
Austin Schuhb4691e92020-12-31 12:37:18 -0800599 EXPECT_EQ(4,
600 Distance(p, Type<int32_t*>(L::Partial(1).Pointer<int32_t>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700601 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5).Pointer<int8_t>(p))));
Austin Schuhb4691e92020-12-31 12:37:18 -0800602 EXPECT_EQ(8,
603 Distance(p, Type<int32_t*>(L::Partial(5).Pointer<int32_t>(p))));
604 EXPECT_EQ(0,
605 Distance(p, Type<int8_t*>(L::Partial(0, 0).Pointer<int8_t>(p))));
606 EXPECT_EQ(
607 0, Distance(p, Type<int32_t*>(L::Partial(0, 0).Pointer<int32_t>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700608 EXPECT_EQ(0,
609 Distance(p, Type<Int128*>(L::Partial(0, 0).Pointer<Int128>(p))));
Austin Schuhb4691e92020-12-31 12:37:18 -0800610 EXPECT_EQ(0,
611 Distance(p, Type<int8_t*>(L::Partial(1, 0).Pointer<int8_t>(p))));
612 EXPECT_EQ(
613 4, Distance(p, Type<int32_t*>(L::Partial(1, 0).Pointer<int32_t>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700614 EXPECT_EQ(8,
615 Distance(p, Type<Int128*>(L::Partial(1, 0).Pointer<Int128>(p))));
Austin Schuhb4691e92020-12-31 12:37:18 -0800616 EXPECT_EQ(0,
617 Distance(p, Type<int8_t*>(L::Partial(5, 3).Pointer<int8_t>(p))));
618 EXPECT_EQ(
619 8, Distance(p, Type<int32_t*>(L::Partial(5, 3).Pointer<int32_t>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700620 EXPECT_EQ(24,
621 Distance(p, Type<Int128*>(L::Partial(5, 3).Pointer<Int128>(p))));
Austin Schuhb4691e92020-12-31 12:37:18 -0800622 EXPECT_EQ(
623 0, Distance(p, Type<int8_t*>(L::Partial(0, 0, 0).Pointer<int8_t>(p))));
624 EXPECT_EQ(
625 0,
626 Distance(p, Type<int32_t*>(L::Partial(0, 0, 0).Pointer<int32_t>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700627 EXPECT_EQ(
628 0, Distance(p, Type<Int128*>(L::Partial(0, 0, 0).Pointer<Int128>(p))));
Austin Schuhb4691e92020-12-31 12:37:18 -0800629 EXPECT_EQ(
630 0, Distance(p, Type<int8_t*>(L::Partial(1, 0, 0).Pointer<int8_t>(p))));
631 EXPECT_EQ(
632 4,
633 Distance(p, Type<int32_t*>(L::Partial(1, 0, 0).Pointer<int32_t>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700634 EXPECT_EQ(
635 8, Distance(p, Type<Int128*>(L::Partial(1, 0, 0).Pointer<Int128>(p))));
Austin Schuhb4691e92020-12-31 12:37:18 -0800636 EXPECT_EQ(
637 0, Distance(p, Type<int8_t*>(L::Partial(5, 3, 1).Pointer<int8_t>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700638 EXPECT_EQ(
639 24, Distance(p, Type<Int128*>(L::Partial(5, 3, 1).Pointer<Int128>(p))));
Austin Schuhb4691e92020-12-31 12:37:18 -0800640 EXPECT_EQ(
641 8,
642 Distance(p, Type<int32_t*>(L::Partial(5, 3, 1).Pointer<int32_t>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -0700643 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L(5, 3, 1).Pointer<int8_t>(p))));
644 EXPECT_EQ(24, Distance(p, Type<Int128*>(L(5, 3, 1).Pointer<Int128>(p))));
645 EXPECT_EQ(8, Distance(p, Type<int32_t*>(L(5, 3, 1).Pointer<int32_t>(p))));
646 }
647}
648
649TEST(Layout, Pointers) {
650 alignas(max_align_t) const unsigned char p[100] = {};
651 using L = Layout<int8_t, int8_t, Int128>;
652 {
653 const auto x = L::Partial();
654 EXPECT_EQ(std::make_tuple(x.Pointer<0>(p)),
655 Type<std::tuple<const int8_t*>>(x.Pointers(p)));
656 }
657 {
658 const auto x = L::Partial(1);
659 EXPECT_EQ(std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p)),
660 (Type<std::tuple<const int8_t*, const int8_t*>>(x.Pointers(p))));
661 }
662 {
663 const auto x = L::Partial(1, 2);
664 EXPECT_EQ(
665 std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
666 (Type<std::tuple<const int8_t*, const int8_t*, const Int128*>>(
667 x.Pointers(p))));
668 }
669 {
670 const auto x = L::Partial(1, 2, 3);
671 EXPECT_EQ(
672 std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
673 (Type<std::tuple<const int8_t*, const int8_t*, const Int128*>>(
674 x.Pointers(p))));
675 }
676 {
677 const L x(1, 2, 3);
678 EXPECT_EQ(
679 std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
680 (Type<std::tuple<const int8_t*, const int8_t*, const Int128*>>(
681 x.Pointers(p))));
682 }
683}
684
685TEST(Layout, MutablePointers) {
686 alignas(max_align_t) unsigned char p[100];
687 using L = Layout<int8_t, int8_t, Int128>;
688 {
689 const auto x = L::Partial();
690 EXPECT_EQ(std::make_tuple(x.Pointer<0>(p)),
691 Type<std::tuple<int8_t*>>(x.Pointers(p)));
692 }
693 {
694 const auto x = L::Partial(1);
695 EXPECT_EQ(std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p)),
696 (Type<std::tuple<int8_t*, int8_t*>>(x.Pointers(p))));
697 }
698 {
699 const auto x = L::Partial(1, 2);
700 EXPECT_EQ(
701 std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
702 (Type<std::tuple<int8_t*, int8_t*, Int128*>>(x.Pointers(p))));
703 }
704 {
705 const auto x = L::Partial(1, 2, 3);
706 EXPECT_EQ(
707 std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
708 (Type<std::tuple<int8_t*, int8_t*, Int128*>>(x.Pointers(p))));
709 }
710 {
711 const L x(1, 2, 3);
712 EXPECT_EQ(
713 std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
714 (Type<std::tuple<int8_t*, int8_t*, Int128*>>(x.Pointers(p))));
715 }
716}
717
718TEST(Layout, SliceByIndexSize) {
719 alignas(max_align_t) const unsigned char p[100] = {};
720 {
721 using L = Layout<int32_t>;
722 EXPECT_EQ(0, L::Partial(0).Slice<0>(p).size());
723 EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size());
724 EXPECT_EQ(3, L(3).Slice<0>(p).size());
725 }
726 {
727 using L = Layout<int32_t, int32_t>;
728 EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size());
729 EXPECT_EQ(5, L::Partial(3, 5).Slice<1>(p).size());
730 EXPECT_EQ(5, L(3, 5).Slice<1>(p).size());
731 }
732 {
733 using L = Layout<int8_t, int32_t, Int128>;
734 EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size());
735 EXPECT_EQ(3, L::Partial(3, 5).Slice<0>(p).size());
736 EXPECT_EQ(5, L::Partial(3, 5).Slice<1>(p).size());
737 EXPECT_EQ(3, L::Partial(3, 5, 7).Slice<0>(p).size());
738 EXPECT_EQ(5, L::Partial(3, 5, 7).Slice<1>(p).size());
739 EXPECT_EQ(7, L::Partial(3, 5, 7).Slice<2>(p).size());
740 EXPECT_EQ(3, L(3, 5, 7).Slice<0>(p).size());
741 EXPECT_EQ(5, L(3, 5, 7).Slice<1>(p).size());
742 EXPECT_EQ(7, L(3, 5, 7).Slice<2>(p).size());
743 }
744}
745
746TEST(Layout, SliceByTypeSize) {
747 alignas(max_align_t) const unsigned char p[100] = {};
748 {
749 using L = Layout<int32_t>;
750 EXPECT_EQ(0, L::Partial(0).Slice<int32_t>(p).size());
751 EXPECT_EQ(3, L::Partial(3).Slice<int32_t>(p).size());
752 EXPECT_EQ(3, L(3).Slice<int32_t>(p).size());
753 }
754 {
755 using L = Layout<int8_t, int32_t, Int128>;
756 EXPECT_EQ(3, L::Partial(3).Slice<int8_t>(p).size());
757 EXPECT_EQ(3, L::Partial(3, 5).Slice<int8_t>(p).size());
758 EXPECT_EQ(5, L::Partial(3, 5).Slice<int32_t>(p).size());
759 EXPECT_EQ(3, L::Partial(3, 5, 7).Slice<int8_t>(p).size());
760 EXPECT_EQ(5, L::Partial(3, 5, 7).Slice<int32_t>(p).size());
761 EXPECT_EQ(7, L::Partial(3, 5, 7).Slice<Int128>(p).size());
762 EXPECT_EQ(3, L(3, 5, 7).Slice<int8_t>(p).size());
763 EXPECT_EQ(5, L(3, 5, 7).Slice<int32_t>(p).size());
764 EXPECT_EQ(7, L(3, 5, 7).Slice<Int128>(p).size());
765 }
766}
767
768TEST(Layout, MutableSliceByIndexSize) {
769 alignas(max_align_t) unsigned char p[100];
770 {
771 using L = Layout<int32_t>;
772 EXPECT_EQ(0, L::Partial(0).Slice<0>(p).size());
773 EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size());
774 EXPECT_EQ(3, L(3).Slice<0>(p).size());
775 }
776 {
777 using L = Layout<int32_t, int32_t>;
778 EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size());
779 EXPECT_EQ(5, L::Partial(3, 5).Slice<1>(p).size());
780 EXPECT_EQ(5, L(3, 5).Slice<1>(p).size());
781 }
782 {
783 using L = Layout<int8_t, int32_t, Int128>;
784 EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size());
785 EXPECT_EQ(3, L::Partial(3, 5).Slice<0>(p).size());
786 EXPECT_EQ(5, L::Partial(3, 5).Slice<1>(p).size());
787 EXPECT_EQ(3, L::Partial(3, 5, 7).Slice<0>(p).size());
788 EXPECT_EQ(5, L::Partial(3, 5, 7).Slice<1>(p).size());
789 EXPECT_EQ(7, L::Partial(3, 5, 7).Slice<2>(p).size());
790 EXPECT_EQ(3, L(3, 5, 7).Slice<0>(p).size());
791 EXPECT_EQ(5, L(3, 5, 7).Slice<1>(p).size());
792 EXPECT_EQ(7, L(3, 5, 7).Slice<2>(p).size());
793 }
794}
795
796TEST(Layout, MutableSliceByTypeSize) {
797 alignas(max_align_t) unsigned char p[100];
798 {
799 using L = Layout<int32_t>;
800 EXPECT_EQ(0, L::Partial(0).Slice<int32_t>(p).size());
801 EXPECT_EQ(3, L::Partial(3).Slice<int32_t>(p).size());
802 EXPECT_EQ(3, L(3).Slice<int32_t>(p).size());
803 }
804 {
805 using L = Layout<int8_t, int32_t, Int128>;
806 EXPECT_EQ(3, L::Partial(3).Slice<int8_t>(p).size());
807 EXPECT_EQ(3, L::Partial(3, 5).Slice<int8_t>(p).size());
808 EXPECT_EQ(5, L::Partial(3, 5).Slice<int32_t>(p).size());
809 EXPECT_EQ(3, L::Partial(3, 5, 7).Slice<int8_t>(p).size());
810 EXPECT_EQ(5, L::Partial(3, 5, 7).Slice<int32_t>(p).size());
811 EXPECT_EQ(7, L::Partial(3, 5, 7).Slice<Int128>(p).size());
812 EXPECT_EQ(3, L(3, 5, 7).Slice<int8_t>(p).size());
813 EXPECT_EQ(5, L(3, 5, 7).Slice<int32_t>(p).size());
814 EXPECT_EQ(7, L(3, 5, 7).Slice<Int128>(p).size());
815 }
816}
817
818TEST(Layout, SliceByIndexData) {
819 alignas(max_align_t) const unsigned char p[100] = {};
820 {
821 using L = Layout<int32_t>;
822 EXPECT_EQ(
Austin Schuhb4691e92020-12-31 12:37:18 -0800823 0, Distance(
824 p, Type<Span<const int32_t>>(L::Partial(0).Slice<0>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -0700825 EXPECT_EQ(
Austin Schuhb4691e92020-12-31 12:37:18 -0800826 0, Distance(
827 p, Type<Span<const int32_t>>(L::Partial(3).Slice<0>(p)).data()));
828 EXPECT_EQ(0,
829 Distance(p, Type<Span<const int32_t>>(L(3).Slice<0>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -0700830 }
831 {
832 using L = Layout<int32_t, int32_t>;
833 EXPECT_EQ(
Austin Schuhb4691e92020-12-31 12:37:18 -0800834 0, Distance(
835 p, Type<Span<const int32_t>>(L::Partial(3).Slice<0>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -0700836 EXPECT_EQ(
837 0,
Austin Schuhb4691e92020-12-31 12:37:18 -0800838 Distance(
839 p, Type<Span<const int32_t>>(L::Partial(3, 5).Slice<0>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -0700840 EXPECT_EQ(
841 12,
Austin Schuhb4691e92020-12-31 12:37:18 -0800842 Distance(
843 p, Type<Span<const int32_t>>(L::Partial(3, 5).Slice<1>(p)).data()));
844 EXPECT_EQ(
845 0, Distance(p, Type<Span<const int32_t>>(L(3, 5).Slice<0>(p)).data()));
846 EXPECT_EQ(
847 12, Distance(p, Type<Span<const int32_t>>(L(3, 5).Slice<1>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -0700848 }
849 {
850 using L = Layout<int8_t, int32_t, Int128>;
851 EXPECT_EQ(
Austin Schuhb4691e92020-12-31 12:37:18 -0800852 0, Distance(
853 p, Type<Span<const int8_t>>(L::Partial(0).Slice<0>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -0700854 EXPECT_EQ(
855 0, Distance(
Austin Schuhb4691e92020-12-31 12:37:18 -0800856 p, Type<Span<const int8_t>>(L::Partial(1).Slice<0>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -0700857 EXPECT_EQ(
858 0, Distance(
Austin Schuhb4691e92020-12-31 12:37:18 -0800859 p, Type<Span<const int8_t>>(L::Partial(5).Slice<0>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -0700860 EXPECT_EQ(
861 0,
862 Distance(
Austin Schuhb4691e92020-12-31 12:37:18 -0800863 p, Type<Span<const int8_t>>(L::Partial(0, 0).Slice<0>(p)).data()));
864 EXPECT_EQ(
865 0,
866 Distance(
867 p, Type<Span<const int32_t>>(L::Partial(0, 0).Slice<1>(p)).data()));
868 EXPECT_EQ(
869 0,
870 Distance(
871 p, Type<Span<const int8_t>>(L::Partial(1, 0).Slice<0>(p)).data()));
872 EXPECT_EQ(
873 4,
874 Distance(
875 p, Type<Span<const int32_t>>(L::Partial(1, 0).Slice<1>(p)).data()));
876 EXPECT_EQ(
877 0,
878 Distance(
879 p, Type<Span<const int8_t>>(L::Partial(5, 3).Slice<0>(p)).data()));
880 EXPECT_EQ(
881 8,
882 Distance(
883 p, Type<Span<const int32_t>>(L::Partial(5, 3).Slice<1>(p)).data()));
884 EXPECT_EQ(
885 0,
886 Distance(
887 p,
888 Type<Span<const int8_t>>(L::Partial(0, 0, 0).Slice<0>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -0700889 EXPECT_EQ(
890 0,
891 Distance(
892 p,
893 Type<Span<const int32_t>>(L::Partial(0, 0, 0).Slice<1>(p)).data()));
894 EXPECT_EQ(
895 0,
896 Distance(
897 p,
898 Type<Span<const Int128>>(L::Partial(0, 0, 0).Slice<2>(p)).data()));
899 EXPECT_EQ(
900 0,
901 Distance(
Austin Schuhb4691e92020-12-31 12:37:18 -0800902 p,
903 Type<Span<const int8_t>>(L::Partial(1, 0, 0).Slice<0>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -0700904 EXPECT_EQ(
905 4,
906 Distance(
907 p,
908 Type<Span<const int32_t>>(L::Partial(1, 0, 0).Slice<1>(p)).data()));
909 EXPECT_EQ(
910 8,
911 Distance(
912 p,
913 Type<Span<const Int128>>(L::Partial(1, 0, 0).Slice<2>(p)).data()));
914 EXPECT_EQ(
915 0,
916 Distance(
Austin Schuhb4691e92020-12-31 12:37:18 -0800917 p,
918 Type<Span<const int8_t>>(L::Partial(5, 3, 1).Slice<0>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -0700919 EXPECT_EQ(
920 24,
921 Distance(
922 p,
923 Type<Span<const Int128>>(L::Partial(5, 3, 1).Slice<2>(p)).data()));
924 EXPECT_EQ(
925 8,
926 Distance(
927 p,
928 Type<Span<const int32_t>>(L::Partial(5, 3, 1).Slice<1>(p)).data()));
929 EXPECT_EQ(
Austin Schuhb4691e92020-12-31 12:37:18 -0800930 0,
931 Distance(p, Type<Span<const int8_t>>(L(5, 3, 1).Slice<0>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -0700932 EXPECT_EQ(
933 24,
934 Distance(p, Type<Span<const Int128>>(L(5, 3, 1).Slice<2>(p)).data()));
935 EXPECT_EQ(
Austin Schuhb4691e92020-12-31 12:37:18 -0800936 8,
937 Distance(p, Type<Span<const int32_t>>(L(5, 3, 1).Slice<1>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -0700938 }
939}
940
941TEST(Layout, SliceByTypeData) {
942 alignas(max_align_t) const unsigned char p[100] = {};
943 {
944 using L = Layout<int32_t>;
945 EXPECT_EQ(
946 0,
947 Distance(
Austin Schuhb4691e92020-12-31 12:37:18 -0800948 p,
949 Type<Span<const int32_t>>(L::Partial(0).Slice<int32_t>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -0700950 EXPECT_EQ(
951 0,
952 Distance(
Austin Schuhb4691e92020-12-31 12:37:18 -0800953 p,
954 Type<Span<const int32_t>>(L::Partial(3).Slice<int32_t>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -0700955 EXPECT_EQ(
Austin Schuhb4691e92020-12-31 12:37:18 -0800956 0,
957 Distance(p, Type<Span<const int32_t>>(L(3).Slice<int32_t>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -0700958 }
959 {
960 using L = Layout<int8_t, int32_t, Int128>;
961 EXPECT_EQ(
Austin Schuh36244a12019-09-21 17:52:38 -0700962 0,
963 Distance(
Austin Schuhb4691e92020-12-31 12:37:18 -0800964 p,
965 Type<Span<const int8_t>>(L::Partial(0).Slice<int8_t>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -0700966 EXPECT_EQ(
967 0,
968 Distance(
969 p,
Austin Schuhb4691e92020-12-31 12:37:18 -0800970 Type<Span<const int8_t>>(L::Partial(1).Slice<int8_t>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -0700971 EXPECT_EQ(
972 0,
973 Distance(
974 p,
Austin Schuhb4691e92020-12-31 12:37:18 -0800975 Type<Span<const int8_t>>(L::Partial(5).Slice<int8_t>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -0700976 EXPECT_EQ(
977 0,
Austin Schuhb4691e92020-12-31 12:37:18 -0800978 Distance(p, Type<Span<const int8_t>>(L::Partial(0, 0).Slice<int8_t>(p))
Austin Schuh36244a12019-09-21 17:52:38 -0700979 .data()));
Austin Schuhb4691e92020-12-31 12:37:18 -0800980 EXPECT_EQ(0, Distance(p, Type<Span<const int32_t>>(
981 L::Partial(0, 0).Slice<int32_t>(p))
982 .data()));
983 EXPECT_EQ(
984 0,
985 Distance(p, Type<Span<const int8_t>>(L::Partial(1, 0).Slice<int8_t>(p))
986 .data()));
987 EXPECT_EQ(4, Distance(p, Type<Span<const int32_t>>(
988 L::Partial(1, 0).Slice<int32_t>(p))
989 .data()));
990 EXPECT_EQ(
991 0,
992 Distance(p, Type<Span<const int8_t>>(L::Partial(5, 3).Slice<int8_t>(p))
993 .data()));
994 EXPECT_EQ(8, Distance(p, Type<Span<const int32_t>>(
995 L::Partial(5, 3).Slice<int32_t>(p))
996 .data()));
997 EXPECT_EQ(0, Distance(p, Type<Span<const int8_t>>(
998 L::Partial(0, 0, 0).Slice<int8_t>(p))
999 .data()));
1000 EXPECT_EQ(0, Distance(p, Type<Span<const int32_t>>(
1001 L::Partial(0, 0, 0).Slice<int32_t>(p))
1002 .data()));
Austin Schuh36244a12019-09-21 17:52:38 -07001003 EXPECT_EQ(0, Distance(p, Type<Span<const Int128>>(
1004 L::Partial(0, 0, 0).Slice<Int128>(p))
1005 .data()));
Austin Schuhb4691e92020-12-31 12:37:18 -08001006 EXPECT_EQ(0, Distance(p, Type<Span<const int8_t>>(
1007 L::Partial(1, 0, 0).Slice<int8_t>(p))
1008 .data()));
1009 EXPECT_EQ(4, Distance(p, Type<Span<const int32_t>>(
1010 L::Partial(1, 0, 0).Slice<int32_t>(p))
1011 .data()));
Austin Schuh36244a12019-09-21 17:52:38 -07001012 EXPECT_EQ(8, Distance(p, Type<Span<const Int128>>(
1013 L::Partial(1, 0, 0).Slice<Int128>(p))
1014 .data()));
Austin Schuhb4691e92020-12-31 12:37:18 -08001015 EXPECT_EQ(0, Distance(p, Type<Span<const int8_t>>(
1016 L::Partial(5, 3, 1).Slice<int8_t>(p))
1017 .data()));
Austin Schuh36244a12019-09-21 17:52:38 -07001018 EXPECT_EQ(24, Distance(p, Type<Span<const Int128>>(
1019 L::Partial(5, 3, 1).Slice<Int128>(p))
1020 .data()));
Austin Schuhb4691e92020-12-31 12:37:18 -08001021 EXPECT_EQ(8, Distance(p, Type<Span<const int32_t>>(
1022 L::Partial(5, 3, 1).Slice<int32_t>(p))
1023 .data()));
Austin Schuh36244a12019-09-21 17:52:38 -07001024 EXPECT_EQ(
1025 0,
Austin Schuhb4691e92020-12-31 12:37:18 -08001026 Distance(p,
1027 Type<Span<const int8_t>>(L(5, 3, 1).Slice<int8_t>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -07001028 EXPECT_EQ(
1029 24,
1030 Distance(p,
1031 Type<Span<const Int128>>(L(5, 3, 1).Slice<Int128>(p)).data()));
1032 EXPECT_EQ(
Austin Schuhb4691e92020-12-31 12:37:18 -08001033 8,
1034 Distance(
1035 p, Type<Span<const int32_t>>(L(5, 3, 1).Slice<int32_t>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -07001036 }
1037}
1038
1039TEST(Layout, MutableSliceByIndexData) {
1040 alignas(max_align_t) unsigned char p[100];
1041 {
1042 using L = Layout<int32_t>;
Austin Schuhb4691e92020-12-31 12:37:18 -08001043 EXPECT_EQ(
1044 0, Distance(p, Type<Span<int32_t>>(L::Partial(0).Slice<0>(p)).data()));
1045 EXPECT_EQ(
1046 0, Distance(p, Type<Span<int32_t>>(L::Partial(3).Slice<0>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -07001047 EXPECT_EQ(0, Distance(p, Type<Span<int32_t>>(L(3).Slice<0>(p)).data()));
1048 }
1049 {
1050 using L = Layout<int32_t, int32_t>;
Austin Schuh36244a12019-09-21 17:52:38 -07001051 EXPECT_EQ(
Austin Schuhb4691e92020-12-31 12:37:18 -08001052 0, Distance(p, Type<Span<int32_t>>(L::Partial(3).Slice<0>(p)).data()));
1053 EXPECT_EQ(
1054 0,
1055 Distance(p, Type<Span<int32_t>>(L::Partial(3, 5).Slice<0>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -07001056 EXPECT_EQ(
1057 12,
1058 Distance(p, Type<Span<int32_t>>(L::Partial(3, 5).Slice<1>(p)).data()));
1059 EXPECT_EQ(0, Distance(p, Type<Span<int32_t>>(L(3, 5).Slice<0>(p)).data()));
1060 EXPECT_EQ(12, Distance(p, Type<Span<int32_t>>(L(3, 5).Slice<1>(p)).data()));
1061 }
1062 {
1063 using L = Layout<int8_t, int32_t, Int128>;
Austin Schuh36244a12019-09-21 17:52:38 -07001064 EXPECT_EQ(
Austin Schuhb4691e92020-12-31 12:37:18 -08001065 0, Distance(p, Type<Span<int8_t>>(L::Partial(0).Slice<0>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -07001066 EXPECT_EQ(
Austin Schuhb4691e92020-12-31 12:37:18 -08001067 0, Distance(p, Type<Span<int8_t>>(L::Partial(1).Slice<0>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -07001068 EXPECT_EQ(
Austin Schuhb4691e92020-12-31 12:37:18 -08001069 0, Distance(p, Type<Span<int8_t>>(L::Partial(5).Slice<0>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -07001070 EXPECT_EQ(
1071 0,
Austin Schuhb4691e92020-12-31 12:37:18 -08001072 Distance(p, Type<Span<int8_t>>(L::Partial(0, 0).Slice<0>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -07001073 EXPECT_EQ(
1074 0,
Austin Schuhb4691e92020-12-31 12:37:18 -08001075 Distance(p, Type<Span<int32_t>>(L::Partial(0, 0).Slice<1>(p)).data()));
1076 EXPECT_EQ(
1077 0,
1078 Distance(p, Type<Span<int8_t>>(L::Partial(1, 0).Slice<0>(p)).data()));
1079 EXPECT_EQ(
1080 4,
1081 Distance(p, Type<Span<int32_t>>(L::Partial(1, 0).Slice<1>(p)).data()));
1082 EXPECT_EQ(
1083 0,
1084 Distance(p, Type<Span<int8_t>>(L::Partial(5, 3).Slice<0>(p)).data()));
1085 EXPECT_EQ(
1086 8,
1087 Distance(p, Type<Span<int32_t>>(L::Partial(5, 3).Slice<1>(p)).data()));
1088 EXPECT_EQ(
1089 0, Distance(
1090 p, Type<Span<int8_t>>(L::Partial(0, 0, 0).Slice<0>(p)).data()));
1091 EXPECT_EQ(
1092 0, Distance(
1093 p, Type<Span<int32_t>>(L::Partial(0, 0, 0).Slice<1>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -07001094 EXPECT_EQ(
1095 0, Distance(
1096 p, Type<Span<Int128>>(L::Partial(0, 0, 0).Slice<2>(p)).data()));
1097 EXPECT_EQ(
Austin Schuhb4691e92020-12-31 12:37:18 -08001098 0, Distance(
1099 p, Type<Span<int8_t>>(L::Partial(1, 0, 0).Slice<0>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -07001100 EXPECT_EQ(
Austin Schuhb4691e92020-12-31 12:37:18 -08001101 4, Distance(
1102 p, Type<Span<int32_t>>(L::Partial(1, 0, 0).Slice<1>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -07001103 EXPECT_EQ(
1104 8, Distance(
1105 p, Type<Span<Int128>>(L::Partial(1, 0, 0).Slice<2>(p)).data()));
1106 EXPECT_EQ(
Austin Schuhb4691e92020-12-31 12:37:18 -08001107 0, Distance(
1108 p, Type<Span<int8_t>>(L::Partial(5, 3, 1).Slice<0>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -07001109 EXPECT_EQ(
1110 24, Distance(
1111 p, Type<Span<Int128>>(L::Partial(5, 3, 1).Slice<2>(p)).data()));
1112 EXPECT_EQ(
Austin Schuhb4691e92020-12-31 12:37:18 -08001113 8, Distance(
1114 p, Type<Span<int32_t>>(L::Partial(5, 3, 1).Slice<1>(p)).data()));
1115 EXPECT_EQ(0,
1116 Distance(p, Type<Span<int8_t>>(L(5, 3, 1).Slice<0>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -07001117 EXPECT_EQ(24,
1118 Distance(p, Type<Span<Int128>>(L(5, 3, 1).Slice<2>(p)).data()));
Austin Schuhb4691e92020-12-31 12:37:18 -08001119 EXPECT_EQ(8,
1120 Distance(p, Type<Span<int32_t>>(L(5, 3, 1).Slice<1>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -07001121 }
1122}
1123
1124TEST(Layout, MutableSliceByTypeData) {
1125 alignas(max_align_t) unsigned char p[100];
1126 {
1127 using L = Layout<int32_t>;
1128 EXPECT_EQ(
Austin Schuhb4691e92020-12-31 12:37:18 -08001129 0, Distance(
1130 p, Type<Span<int32_t>>(L::Partial(0).Slice<int32_t>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -07001131 EXPECT_EQ(
Austin Schuhb4691e92020-12-31 12:37:18 -08001132 0, Distance(
1133 p, Type<Span<int32_t>>(L::Partial(3).Slice<int32_t>(p)).data()));
1134 EXPECT_EQ(0,
1135 Distance(p, Type<Span<int32_t>>(L(3).Slice<int32_t>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -07001136 }
1137 {
1138 using L = Layout<int8_t, int32_t, Int128>;
1139 EXPECT_EQ(
Austin Schuhb4691e92020-12-31 12:37:18 -08001140 0,
1141 Distance(p, Type<Span<int8_t>>(L::Partial(0).Slice<int8_t>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -07001142 EXPECT_EQ(
1143 0,
Austin Schuhb4691e92020-12-31 12:37:18 -08001144 Distance(p, Type<Span<int8_t>>(L::Partial(1).Slice<int8_t>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -07001145 EXPECT_EQ(
1146 0,
Austin Schuhb4691e92020-12-31 12:37:18 -08001147 Distance(p, Type<Span<int8_t>>(L::Partial(5).Slice<int8_t>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -07001148 EXPECT_EQ(
1149 0,
Austin Schuhb4691e92020-12-31 12:37:18 -08001150 Distance(p,
1151 Type<Span<int8_t>>(L::Partial(0, 0).Slice<int8_t>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -07001152 EXPECT_EQ(
1153 0,
1154 Distance(
Austin Schuhb4691e92020-12-31 12:37:18 -08001155 p, Type<Span<int32_t>>(L::Partial(0, 0).Slice<int32_t>(p)).data()));
1156 EXPECT_EQ(
1157 0,
1158 Distance(p,
1159 Type<Span<int8_t>>(L::Partial(1, 0).Slice<int8_t>(p)).data()));
1160 EXPECT_EQ(
1161 4,
1162 Distance(
1163 p, Type<Span<int32_t>>(L::Partial(1, 0).Slice<int32_t>(p)).data()));
1164 EXPECT_EQ(
1165 0,
1166 Distance(p,
1167 Type<Span<int8_t>>(L::Partial(5, 3).Slice<int8_t>(p)).data()));
1168 EXPECT_EQ(
1169 8,
1170 Distance(
1171 p, Type<Span<int32_t>>(L::Partial(5, 3).Slice<int32_t>(p)).data()));
1172 EXPECT_EQ(
1173 0,
1174 Distance(
1175 p,
1176 Type<Span<int8_t>>(L::Partial(0, 0, 0).Slice<int8_t>(p)).data()));
1177 EXPECT_EQ(
1178 0,
1179 Distance(
1180 p,
1181 Type<Span<int32_t>>(L::Partial(0, 0, 0).Slice<int32_t>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -07001182 EXPECT_EQ(
1183 0,
1184 Distance(
1185 p,
1186 Type<Span<Int128>>(L::Partial(0, 0, 0).Slice<Int128>(p)).data()));
1187 EXPECT_EQ(
Austin Schuhb4691e92020-12-31 12:37:18 -08001188 0,
1189 Distance(
1190 p,
1191 Type<Span<int8_t>>(L::Partial(1, 0, 0).Slice<int8_t>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -07001192 EXPECT_EQ(
1193 4,
1194 Distance(
Austin Schuhb4691e92020-12-31 12:37:18 -08001195 p,
1196 Type<Span<int32_t>>(L::Partial(1, 0, 0).Slice<int32_t>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -07001197 EXPECT_EQ(
1198 8,
1199 Distance(
1200 p,
1201 Type<Span<Int128>>(L::Partial(1, 0, 0).Slice<Int128>(p)).data()));
1202 EXPECT_EQ(
Austin Schuhb4691e92020-12-31 12:37:18 -08001203 0,
1204 Distance(
1205 p,
1206 Type<Span<int8_t>>(L::Partial(5, 3, 1).Slice<int8_t>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -07001207 EXPECT_EQ(
1208 24,
1209 Distance(
1210 p,
1211 Type<Span<Int128>>(L::Partial(5, 3, 1).Slice<Int128>(p)).data()));
1212 EXPECT_EQ(
1213 8,
1214 Distance(
Austin Schuhb4691e92020-12-31 12:37:18 -08001215 p,
1216 Type<Span<int32_t>>(L::Partial(5, 3, 1).Slice<int32_t>(p)).data()));
1217 EXPECT_EQ(
1218 0, Distance(p, Type<Span<int8_t>>(L(5, 3, 1).Slice<int8_t>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -07001219 EXPECT_EQ(
1220 24,
1221 Distance(p, Type<Span<Int128>>(L(5, 3, 1).Slice<Int128>(p)).data()));
1222 EXPECT_EQ(
Austin Schuhb4691e92020-12-31 12:37:18 -08001223 8,
1224 Distance(p, Type<Span<int32_t>>(L(5, 3, 1).Slice<int32_t>(p)).data()));
Austin Schuh36244a12019-09-21 17:52:38 -07001225 }
1226}
1227
1228MATCHER_P(IsSameSlice, slice, "") {
1229 return arg.size() == slice.size() && arg.data() == slice.data();
1230}
1231
1232template <typename... M>
1233class TupleMatcher {
1234 public:
1235 explicit TupleMatcher(M... matchers) : matchers_(std::move(matchers)...) {}
1236
1237 template <typename Tuple>
1238 bool MatchAndExplain(const Tuple& p,
1239 testing::MatchResultListener* /* listener */) const {
1240 static_assert(std::tuple_size<Tuple>::value == sizeof...(M), "");
1241 return MatchAndExplainImpl(
1242 p, absl::make_index_sequence<std::tuple_size<Tuple>::value>{});
1243 }
1244
1245 // For the matcher concept. Left empty as we don't really need the diagnostics
1246 // right now.
1247 void DescribeTo(::std::ostream* os) const {}
1248 void DescribeNegationTo(::std::ostream* os) const {}
1249
1250 private:
1251 template <typename Tuple, size_t... Is>
1252 bool MatchAndExplainImpl(const Tuple& p, absl::index_sequence<Is...>) const {
1253 // Using std::min as a simple variadic "and".
1254 return std::min(
1255 {true, testing::SafeMatcherCast<
1256 const typename std::tuple_element<Is, Tuple>::type&>(
1257 std::get<Is>(matchers_))
1258 .Matches(std::get<Is>(p))...});
1259 }
1260
1261 std::tuple<M...> matchers_;
1262};
1263
1264template <typename... M>
1265testing::PolymorphicMatcher<TupleMatcher<M...>> Tuple(M... matchers) {
1266 return testing::MakePolymorphicMatcher(
1267 TupleMatcher<M...>(std::move(matchers)...));
1268}
1269
1270TEST(Layout, Slices) {
1271 alignas(max_align_t) const unsigned char p[100] = {};
1272 using L = Layout<int8_t, int8_t, Int128>;
1273 {
1274 const auto x = L::Partial();
1275 EXPECT_THAT(Type<std::tuple<>>(x.Slices(p)), Tuple());
1276 }
1277 {
1278 const auto x = L::Partial(1);
1279 EXPECT_THAT(Type<std::tuple<Span<const int8_t>>>(x.Slices(p)),
1280 Tuple(IsSameSlice(x.Slice<0>(p))));
1281 }
1282 {
1283 const auto x = L::Partial(1, 2);
1284 EXPECT_THAT(
1285 (Type<std::tuple<Span<const int8_t>, Span<const int8_t>>>(x.Slices(p))),
1286 Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p))));
1287 }
1288 {
1289 const auto x = L::Partial(1, 2, 3);
1290 EXPECT_THAT((Type<std::tuple<Span<const int8_t>, Span<const int8_t>,
1291 Span<const Int128>>>(x.Slices(p))),
1292 Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)),
1293 IsSameSlice(x.Slice<2>(p))));
1294 }
1295 {
1296 const L x(1, 2, 3);
1297 EXPECT_THAT((Type<std::tuple<Span<const int8_t>, Span<const int8_t>,
1298 Span<const Int128>>>(x.Slices(p))),
1299 Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)),
1300 IsSameSlice(x.Slice<2>(p))));
1301 }
1302}
1303
1304TEST(Layout, MutableSlices) {
1305 alignas(max_align_t) unsigned char p[100] = {};
1306 using L = Layout<int8_t, int8_t, Int128>;
1307 {
1308 const auto x = L::Partial();
1309 EXPECT_THAT(Type<std::tuple<>>(x.Slices(p)), Tuple());
1310 }
1311 {
1312 const auto x = L::Partial(1);
1313 EXPECT_THAT(Type<std::tuple<Span<int8_t>>>(x.Slices(p)),
1314 Tuple(IsSameSlice(x.Slice<0>(p))));
1315 }
1316 {
1317 const auto x = L::Partial(1, 2);
1318 EXPECT_THAT((Type<std::tuple<Span<int8_t>, Span<int8_t>>>(x.Slices(p))),
1319 Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p))));
1320 }
1321 {
1322 const auto x = L::Partial(1, 2, 3);
Austin Schuhb4691e92020-12-31 12:37:18 -08001323 EXPECT_THAT((Type<std::tuple<Span<int8_t>, Span<int8_t>, Span<Int128>>>(
1324 x.Slices(p))),
1325 Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)),
1326 IsSameSlice(x.Slice<2>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -07001327 }
1328 {
1329 const L x(1, 2, 3);
Austin Schuhb4691e92020-12-31 12:37:18 -08001330 EXPECT_THAT((Type<std::tuple<Span<int8_t>, Span<int8_t>, Span<Int128>>>(
1331 x.Slices(p))),
1332 Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)),
1333 IsSameSlice(x.Slice<2>(p))));
Austin Schuh36244a12019-09-21 17:52:38 -07001334 }
1335}
1336
1337TEST(Layout, UnalignedTypes) {
1338 constexpr Layout<unsigned char, unsigned char, unsigned char> x(1, 2, 3);
1339 alignas(max_align_t) unsigned char p[x.AllocSize() + 1];
1340 EXPECT_THAT(x.Pointers(p + 1), Tuple(p + 1, p + 2, p + 4));
1341}
1342
1343TEST(Layout, CustomAlignment) {
1344 constexpr Layout<unsigned char, Aligned<unsigned char, 8>> x(1, 2);
1345 alignas(max_align_t) unsigned char p[x.AllocSize()];
1346 EXPECT_EQ(10, x.AllocSize());
1347 EXPECT_THAT(x.Pointers(p), Tuple(p + 0, p + 8));
1348}
1349
1350TEST(Layout, OverAligned) {
1351 constexpr size_t M = alignof(max_align_t);
1352 constexpr Layout<unsigned char, Aligned<unsigned char, 2 * M>> x(1, 3);
1353 alignas(2 * M) unsigned char p[x.AllocSize()];
1354 EXPECT_EQ(2 * M + 3, x.AllocSize());
1355 EXPECT_THAT(x.Pointers(p), Tuple(p + 0, p + 2 * M));
1356}
1357
1358TEST(Layout, Alignment) {
1359 static_assert(Layout<int8_t>::Alignment() == 1, "");
1360 static_assert(Layout<int32_t>::Alignment() == 4, "");
1361 static_assert(Layout<Int64>::Alignment() == 8, "");
1362 static_assert(Layout<Aligned<int8_t, 64>>::Alignment() == 64, "");
1363 static_assert(Layout<int8_t, int32_t, Int64>::Alignment() == 8, "");
1364 static_assert(Layout<int8_t, Int64, int32_t>::Alignment() == 8, "");
1365 static_assert(Layout<int32_t, int8_t, Int64>::Alignment() == 8, "");
1366 static_assert(Layout<int32_t, Int64, int8_t>::Alignment() == 8, "");
1367 static_assert(Layout<Int64, int8_t, int32_t>::Alignment() == 8, "");
1368 static_assert(Layout<Int64, int32_t, int8_t>::Alignment() == 8, "");
1369}
1370
1371TEST(Layout, ConstexprPartial) {
1372 constexpr size_t M = alignof(max_align_t);
1373 constexpr Layout<unsigned char, Aligned<unsigned char, 2 * M>> x(1, 3);
1374 static_assert(x.Partial(1).template Offset<1>() == 2 * M, "");
1375}
1376// [from, to)
1377struct Region {
1378 size_t from;
1379 size_t to;
1380};
1381
1382void ExpectRegionPoisoned(const unsigned char* p, size_t n, bool poisoned) {
Austin Schuhb4691e92020-12-31 12:37:18 -08001383#ifdef ABSL_HAVE_ADDRESS_SANITIZER
Austin Schuh36244a12019-09-21 17:52:38 -07001384 for (size_t i = 0; i != n; ++i) {
1385 EXPECT_EQ(poisoned, __asan_address_is_poisoned(p + i));
1386 }
1387#endif
1388}
1389
1390template <size_t N>
1391void ExpectPoisoned(const unsigned char (&buf)[N],
1392 std::initializer_list<Region> reg) {
1393 size_t prev = 0;
1394 for (const Region& r : reg) {
1395 ExpectRegionPoisoned(buf + prev, r.from - prev, false);
1396 ExpectRegionPoisoned(buf + r.from, r.to - r.from, true);
1397 prev = r.to;
1398 }
1399 ExpectRegionPoisoned(buf + prev, N - prev, false);
1400}
1401
1402TEST(Layout, PoisonPadding) {
1403 using L = Layout<int8_t, Int64, int32_t, Int128>;
1404
1405 constexpr size_t n = L::Partial(1, 2, 3, 4).AllocSize();
1406 {
1407 constexpr auto x = L::Partial();
1408 alignas(max_align_t) const unsigned char c[n] = {};
1409 x.PoisonPadding(c);
1410 EXPECT_EQ(x.Slices(c), x.Slices(c));
1411 ExpectPoisoned(c, {});
1412 }
1413 {
1414 constexpr auto x = L::Partial(1);
1415 alignas(max_align_t) const unsigned char c[n] = {};
1416 x.PoisonPadding(c);
1417 EXPECT_EQ(x.Slices(c), x.Slices(c));
1418 ExpectPoisoned(c, {{1, 8}});
1419 }
1420 {
1421 constexpr auto x = L::Partial(1, 2);
1422 alignas(max_align_t) const unsigned char c[n] = {};
1423 x.PoisonPadding(c);
1424 EXPECT_EQ(x.Slices(c), x.Slices(c));
1425 ExpectPoisoned(c, {{1, 8}});
1426 }
1427 {
1428 constexpr auto x = L::Partial(1, 2, 3);
1429 alignas(max_align_t) const unsigned char c[n] = {};
1430 x.PoisonPadding(c);
1431 EXPECT_EQ(x.Slices(c), x.Slices(c));
1432 ExpectPoisoned(c, {{1, 8}, {36, 40}});
1433 }
1434 {
1435 constexpr auto x = L::Partial(1, 2, 3, 4);
1436 alignas(max_align_t) const unsigned char c[n] = {};
1437 x.PoisonPadding(c);
1438 EXPECT_EQ(x.Slices(c), x.Slices(c));
1439 ExpectPoisoned(c, {{1, 8}, {36, 40}});
1440 }
1441 {
1442 constexpr L x(1, 2, 3, 4);
1443 alignas(max_align_t) const unsigned char c[n] = {};
1444 x.PoisonPadding(c);
1445 EXPECT_EQ(x.Slices(c), x.Slices(c));
1446 ExpectPoisoned(c, {{1, 8}, {36, 40}});
1447 }
1448}
1449
1450TEST(Layout, DebugString) {
1451 {
1452 constexpr auto x = Layout<int8_t, int32_t, int8_t, Int128>::Partial();
1453 EXPECT_EQ("@0<signed char>(1)", x.DebugString());
1454 }
1455 {
1456 constexpr auto x = Layout<int8_t, int32_t, int8_t, Int128>::Partial(1);
1457 EXPECT_EQ("@0<signed char>(1)[1]; @4<int>(4)", x.DebugString());
1458 }
1459 {
1460 constexpr auto x = Layout<int8_t, int32_t, int8_t, Int128>::Partial(1, 2);
1461 EXPECT_EQ("@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)",
1462 x.DebugString());
1463 }
1464 {
Austin Schuhb4691e92020-12-31 12:37:18 -08001465 constexpr auto x =
1466 Layout<int8_t, int32_t, int8_t, Int128>::Partial(1, 2, 3);
Austin Schuh36244a12019-09-21 17:52:38 -07001467 EXPECT_EQ(
1468 "@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)[3]; "
1469 "@16" +
1470 Int128::Name() + "(16)",
1471 x.DebugString());
1472 }
1473 {
Austin Schuhb4691e92020-12-31 12:37:18 -08001474 constexpr auto x =
1475 Layout<int8_t, int32_t, int8_t, Int128>::Partial(1, 2, 3, 4);
Austin Schuh36244a12019-09-21 17:52:38 -07001476 EXPECT_EQ(
1477 "@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)[3]; "
1478 "@16" +
1479 Int128::Name() + "(16)[4]",
1480 x.DebugString());
1481 }
1482 {
1483 constexpr Layout<int8_t, int32_t, int8_t, Int128> x(1, 2, 3, 4);
1484 EXPECT_EQ(
1485 "@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)[3]; "
1486 "@16" +
1487 Int128::Name() + "(16)[4]",
1488 x.DebugString());
1489 }
1490}
1491
1492TEST(Layout, CharTypes) {
1493 constexpr Layout<int32_t> x(1);
1494 alignas(max_align_t) char c[x.AllocSize()] = {};
1495 alignas(max_align_t) unsigned char uc[x.AllocSize()] = {};
1496 alignas(max_align_t) signed char sc[x.AllocSize()] = {};
1497 alignas(max_align_t) const char cc[x.AllocSize()] = {};
1498 alignas(max_align_t) const unsigned char cuc[x.AllocSize()] = {};
1499 alignas(max_align_t) const signed char csc[x.AllocSize()] = {};
1500
1501 Type<int32_t*>(x.Pointer<0>(c));
1502 Type<int32_t*>(x.Pointer<0>(uc));
1503 Type<int32_t*>(x.Pointer<0>(sc));
1504 Type<const int32_t*>(x.Pointer<0>(cc));
1505 Type<const int32_t*>(x.Pointer<0>(cuc));
1506 Type<const int32_t*>(x.Pointer<0>(csc));
1507
1508 Type<int32_t*>(x.Pointer<int32_t>(c));
1509 Type<int32_t*>(x.Pointer<int32_t>(uc));
1510 Type<int32_t*>(x.Pointer<int32_t>(sc));
1511 Type<const int32_t*>(x.Pointer<int32_t>(cc));
1512 Type<const int32_t*>(x.Pointer<int32_t>(cuc));
1513 Type<const int32_t*>(x.Pointer<int32_t>(csc));
1514
1515 Type<std::tuple<int32_t*>>(x.Pointers(c));
1516 Type<std::tuple<int32_t*>>(x.Pointers(uc));
1517 Type<std::tuple<int32_t*>>(x.Pointers(sc));
1518 Type<std::tuple<const int32_t*>>(x.Pointers(cc));
1519 Type<std::tuple<const int32_t*>>(x.Pointers(cuc));
1520 Type<std::tuple<const int32_t*>>(x.Pointers(csc));
1521
1522 Type<Span<int32_t>>(x.Slice<0>(c));
1523 Type<Span<int32_t>>(x.Slice<0>(uc));
1524 Type<Span<int32_t>>(x.Slice<0>(sc));
1525 Type<Span<const int32_t>>(x.Slice<0>(cc));
1526 Type<Span<const int32_t>>(x.Slice<0>(cuc));
1527 Type<Span<const int32_t>>(x.Slice<0>(csc));
1528
1529 Type<std::tuple<Span<int32_t>>>(x.Slices(c));
1530 Type<std::tuple<Span<int32_t>>>(x.Slices(uc));
1531 Type<std::tuple<Span<int32_t>>>(x.Slices(sc));
1532 Type<std::tuple<Span<const int32_t>>>(x.Slices(cc));
1533 Type<std::tuple<Span<const int32_t>>>(x.Slices(cuc));
1534 Type<std::tuple<Span<const int32_t>>>(x.Slices(csc));
1535}
1536
1537TEST(Layout, ConstElementType) {
1538 constexpr Layout<const int32_t> x(1);
1539 alignas(int32_t) char c[x.AllocSize()] = {};
1540 const char* cc = c;
1541 const int32_t* p = reinterpret_cast<const int32_t*>(cc);
1542
1543 EXPECT_EQ(alignof(int32_t), x.Alignment());
1544
1545 EXPECT_EQ(0, x.Offset<0>());
1546 EXPECT_EQ(0, x.Offset<const int32_t>());
1547
1548 EXPECT_THAT(x.Offsets(), ElementsAre(0));
1549
1550 EXPECT_EQ(1, x.Size<0>());
1551 EXPECT_EQ(1, x.Size<const int32_t>());
1552
1553 EXPECT_THAT(x.Sizes(), ElementsAre(1));
1554
1555 EXPECT_EQ(sizeof(int32_t), x.AllocSize());
1556
1557 EXPECT_EQ(p, Type<const int32_t*>(x.Pointer<0>(c)));
1558 EXPECT_EQ(p, Type<const int32_t*>(x.Pointer<0>(cc)));
1559
1560 EXPECT_EQ(p, Type<const int32_t*>(x.Pointer<const int32_t>(c)));
1561 EXPECT_EQ(p, Type<const int32_t*>(x.Pointer<const int32_t>(cc)));
1562
1563 EXPECT_THAT(Type<std::tuple<const int32_t*>>(x.Pointers(c)), Tuple(p));
1564 EXPECT_THAT(Type<std::tuple<const int32_t*>>(x.Pointers(cc)), Tuple(p));
1565
1566 EXPECT_THAT(Type<Span<const int32_t>>(x.Slice<0>(c)),
1567 IsSameSlice(Span<const int32_t>(p, 1)));
1568 EXPECT_THAT(Type<Span<const int32_t>>(x.Slice<0>(cc)),
1569 IsSameSlice(Span<const int32_t>(p, 1)));
1570
1571 EXPECT_THAT(Type<Span<const int32_t>>(x.Slice<const int32_t>(c)),
1572 IsSameSlice(Span<const int32_t>(p, 1)));
1573 EXPECT_THAT(Type<Span<const int32_t>>(x.Slice<const int32_t>(cc)),
1574 IsSameSlice(Span<const int32_t>(p, 1)));
1575
1576 EXPECT_THAT(Type<std::tuple<Span<const int32_t>>>(x.Slices(c)),
1577 Tuple(IsSameSlice(Span<const int32_t>(p, 1))));
1578 EXPECT_THAT(Type<std::tuple<Span<const int32_t>>>(x.Slices(cc)),
1579 Tuple(IsSameSlice(Span<const int32_t>(p, 1))));
1580}
1581
1582namespace example {
1583
1584// Immutable move-only string with sizeof equal to sizeof(void*). The string
1585// size and the characters are kept in the same heap allocation.
1586class CompactString {
1587 public:
1588 CompactString(const char* s = "") { // NOLINT
1589 const size_t size = strlen(s);
1590 // size_t[1], followed by char[size + 1].
1591 // This statement doesn't allocate memory.
1592 const L layout(1, size + 1);
1593 // AllocSize() tells us how much memory we need to allocate for all our
1594 // data.
1595 p_.reset(new unsigned char[layout.AllocSize()]);
1596 // If running under ASAN, mark the padding bytes, if any, to catch memory
1597 // errors.
1598 layout.PoisonPadding(p_.get());
1599 // Store the size in the allocation.
1600 // Pointer<size_t>() is a synonym for Pointer<0>().
1601 *layout.Pointer<size_t>(p_.get()) = size;
1602 // Store the characters in the allocation.
1603 memcpy(layout.Pointer<char>(p_.get()), s, size + 1);
1604 }
1605
1606 size_t size() const {
1607 // Equivalent to reinterpret_cast<size_t&>(*p).
1608 return *L::Partial().Pointer<size_t>(p_.get());
1609 }
1610
1611 const char* c_str() const {
1612 // Equivalent to reinterpret_cast<char*>(p.get() + sizeof(size_t)).
1613 // The argument in Partial(1) specifies that we have size_t[1] in front of
1614 // the characters.
1615 return L::Partial(1).Pointer<char>(p_.get());
1616 }
1617
1618 private:
1619 // Our heap allocation contains a size_t followed by an array of chars.
1620 using L = Layout<size_t, char>;
1621 std::unique_ptr<unsigned char[]> p_;
1622};
1623
1624TEST(CompactString, Works) {
1625 CompactString s = "hello";
1626 EXPECT_EQ(5, s.size());
1627 EXPECT_STREQ("hello", s.c_str());
1628}
1629
1630} // namespace example
1631
1632} // namespace
1633} // namespace container_internal
Austin Schuhb4691e92020-12-31 12:37:18 -08001634ABSL_NAMESPACE_END
Austin Schuh36244a12019-09-21 17:52:38 -07001635} // namespace absl