23 #include <type_traits> 25 #include "gmock/gmock.h" 26 #include "gtest/gtest.h" 31 namespace container_internal {
35 using ::testing::ElementsAre;
37 size_t Distance(
const void*
from,
const void*
to) {
39 return static_cast<const char*
>(
to) - static_cast<const char*>(from);
42 template <
class Expected,
class Actual>
43 Expected Type(Actual val) {
44 static_assert(std::is_same<Expected, Actual>(),
"");
49 struct alignas(8) Int128 {
51 friend bool operator==(Int128 lhs, Int128 rhs) {
52 return std::tie(lhs.a, lhs.b) == std::tie(rhs.a, rhs.b);
55 static std::string Name() {
56 return internal_layout::adl_barrier::TypeName<Int128>();
61 struct alignas(8) Int64 {
64 return lhs.a == rhs.a;
69 static_assert(
sizeof(int8_t) == 1,
"");
70 static_assert(
alignof(int8_t) == 1,
"");
71 static_assert(
sizeof(int16_t) == 2,
"");
72 static_assert(
alignof(int16_t) == 2,
"");
73 static_assert(
sizeof(int32_t) == 4,
"");
74 static_assert(
alignof(int32_t) == 4,
"");
75 static_assert(
sizeof(Int64) == 8,
"");
76 static_assert(
alignof(Int64) == 8,
"");
77 static_assert(
sizeof(Int128) == 16,
"");
78 static_assert(
alignof(Int128) == 8,
"");
80 template <
class Expected,
class Actual>
82 static_assert(std::is_same<Expected, Actual>(),
"");
85 TEST(Layout, ElementType) {
87 using L = Layout<int32_t>;
88 SameType<int32_t, L::ElementType<0>>();
89 SameType<int32_t, decltype(L::Partial())::ElementType<0>>();
90 SameType<int32_t, decltype(L::Partial(0))::ElementType<0>>();
93 using L = Layout<int32_t, int32_t>;
94 SameType<int32_t, L::ElementType<0>>();
95 SameType<int32_t, L::ElementType<1>>();
96 SameType<int32_t, decltype(L::Partial())::ElementType<0>>();
97 SameType<int32_t, decltype(L::Partial())::ElementType<1>>();
98 SameType<int32_t, decltype(L::Partial(0))::ElementType<0>>();
99 SameType<int32_t, decltype(L::Partial(0))::ElementType<1>>();
102 using L = Layout<int8_t, int32_t, Int128>;
103 SameType<int8_t, L::ElementType<0>>();
104 SameType<int32_t, L::ElementType<1>>();
105 SameType<Int128, L::ElementType<2>>();
106 SameType<int8_t, decltype(L::Partial())::ElementType<0>>();
107 SameType<int8_t, decltype(L::Partial(0))::ElementType<0>>();
108 SameType<int32_t, decltype(L::Partial(0))::ElementType<1>>();
109 SameType<int8_t, decltype(L::Partial(0, 0))::ElementType<0>>();
110 SameType<int32_t, decltype(L::Partial(0, 0))::ElementType<1>>();
111 SameType<Int128, decltype(L::Partial(0, 0))::ElementType<2>>();
112 SameType<int8_t, decltype(L::Partial(0, 0, 0))::ElementType<0>>();
113 SameType<int32_t, decltype(L::Partial(0, 0, 0))::ElementType<1>>();
114 SameType<Int128, decltype(L::Partial(0, 0, 0))::ElementType<2>>();
118 TEST(Layout, ElementTypes) {
120 using L = Layout<int32_t>;
121 SameType<std::tuple<int32_t>, L::ElementTypes>();
122 SameType<std::tuple<int32_t>, decltype(L::Partial())::ElementTypes>();
123 SameType<std::tuple<int32_t>, decltype(L::Partial(0))::ElementTypes>();
126 using L = Layout<int32_t, int32_t>;
127 SameType<std::tuple<int32_t, int32_t>, L::ElementTypes>();
128 SameType<std::tuple<int32_t, int32_t>, decltype(L::Partial())::ElementTypes>();
129 SameType<std::tuple<int32_t, int32_t>, decltype(L::Partial(0))::ElementTypes>();
132 using L = Layout<int8_t, int32_t, Int128>;
133 SameType<std::tuple<int8_t, int32_t, Int128>, L::ElementTypes>();
134 SameType<std::tuple<int8_t, int32_t, Int128>,
135 decltype(L::Partial())::ElementTypes>();
136 SameType<std::tuple<int8_t, int32_t, Int128>,
137 decltype(L::Partial(0))::ElementTypes>();
138 SameType<std::tuple<int8_t, int32_t, Int128>,
139 decltype(L::Partial(0, 0))::ElementTypes>();
140 SameType<std::tuple<int8_t, int32_t, Int128>,
141 decltype(L::Partial(0, 0, 0))::ElementTypes>();
145 TEST(Layout, OffsetByIndex) {
147 using L = Layout<int32_t>;
148 EXPECT_EQ(0, L::Partial().Offset<0>());
149 EXPECT_EQ(0, L::Partial(3).Offset<0>());
150 EXPECT_EQ(0, L(3).Offset<0>());
153 using L = Layout<int32_t, int32_t>;
154 EXPECT_EQ(0, L::Partial().Offset<0>());
155 EXPECT_EQ(0, L::Partial(3).Offset<0>());
156 EXPECT_EQ(12, L::Partial(3).Offset<1>());
157 EXPECT_EQ(0, L::Partial(3, 5).Offset<0>());
158 EXPECT_EQ(12, L::Partial(3, 5).Offset<1>());
159 EXPECT_EQ(0, L(3, 5).Offset<0>());
160 EXPECT_EQ(12, L(3, 5).Offset<1>());
163 using L = Layout<int8_t, int32_t, Int128>;
164 EXPECT_EQ(0, L::Partial().Offset<0>());
165 EXPECT_EQ(0, L::Partial(0).Offset<0>());
166 EXPECT_EQ(0, L::Partial(0).Offset<1>());
167 EXPECT_EQ(0, L::Partial(1).Offset<0>());
168 EXPECT_EQ(4, L::Partial(1).Offset<1>());
169 EXPECT_EQ(0, L::Partial(5).Offset<0>());
170 EXPECT_EQ(8, L::Partial(5).Offset<1>());
171 EXPECT_EQ(0, L::Partial(0, 0).Offset<0>());
172 EXPECT_EQ(0, L::Partial(0, 0).Offset<1>());
173 EXPECT_EQ(0, L::Partial(0, 0).Offset<2>());
174 EXPECT_EQ(0, L::Partial(1, 0).Offset<0>());
175 EXPECT_EQ(4, L::Partial(1, 0).Offset<1>());
176 EXPECT_EQ(8, L::Partial(1, 0).Offset<2>());
177 EXPECT_EQ(0, L::Partial(5, 3).Offset<0>());
178 EXPECT_EQ(8, L::Partial(5, 3).Offset<1>());
179 EXPECT_EQ(24, L::Partial(5, 3).Offset<2>());
180 EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<0>());
181 EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<1>());
182 EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<2>());
183 EXPECT_EQ(0, L::Partial(1, 0, 0).Offset<0>());
184 EXPECT_EQ(4, L::Partial(1, 0, 0).Offset<1>());
185 EXPECT_EQ(8, L::Partial(1, 0, 0).Offset<2>());
186 EXPECT_EQ(0, L::Partial(5, 3, 1).Offset<0>());
187 EXPECT_EQ(24, L::Partial(5, 3, 1).Offset<2>());
188 EXPECT_EQ(8, L::Partial(5, 3, 1).Offset<1>());
189 EXPECT_EQ(0, L(5, 3, 1).Offset<0>());
190 EXPECT_EQ(24, L(5, 3, 1).Offset<2>());
191 EXPECT_EQ(8, L(5, 3, 1).Offset<1>());
195 TEST(Layout, OffsetByType) {
197 using L = Layout<int32_t>;
198 EXPECT_EQ(0, L::Partial().Offset<int32_t>());
199 EXPECT_EQ(0, L::Partial(3).Offset<int32_t>());
200 EXPECT_EQ(0, L(3).Offset<int32_t>());
203 using L = Layout<int8_t, int32_t, Int128>;
204 EXPECT_EQ(0, L::Partial().Offset<int8_t>());
205 EXPECT_EQ(0, L::Partial(0).Offset<int8_t>());
206 EXPECT_EQ(0, L::Partial(0).Offset<int32_t>());
207 EXPECT_EQ(0, L::Partial(1).Offset<int8_t>());
208 EXPECT_EQ(4, L::Partial(1).Offset<int32_t>());
209 EXPECT_EQ(0, L::Partial(5).Offset<int8_t>());
210 EXPECT_EQ(8, L::Partial(5).Offset<int32_t>());
211 EXPECT_EQ(0, L::Partial(0, 0).Offset<int8_t>());
212 EXPECT_EQ(0, L::Partial(0, 0).Offset<int32_t>());
213 EXPECT_EQ(0, L::Partial(0, 0).Offset<Int128>());
214 EXPECT_EQ(0, L::Partial(1, 0).Offset<int8_t>());
215 EXPECT_EQ(4, L::Partial(1, 0).Offset<int32_t>());
216 EXPECT_EQ(8, L::Partial(1, 0).Offset<Int128>());
217 EXPECT_EQ(0, L::Partial(5, 3).Offset<int8_t>());
218 EXPECT_EQ(8, L::Partial(5, 3).Offset<int32_t>());
219 EXPECT_EQ(24, L::Partial(5, 3).Offset<Int128>());
220 EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<int8_t>());
221 EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<int32_t>());
222 EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<Int128>());
223 EXPECT_EQ(0, L::Partial(1, 0, 0).Offset<int8_t>());
224 EXPECT_EQ(4, L::Partial(1, 0, 0).Offset<int32_t>());
225 EXPECT_EQ(8, L::Partial(1, 0, 0).Offset<Int128>());
226 EXPECT_EQ(0, L::Partial(5, 3, 1).Offset<int8_t>());
227 EXPECT_EQ(24, L::Partial(5, 3, 1).Offset<Int128>());
228 EXPECT_EQ(8, L::Partial(5, 3, 1).Offset<int32_t>());
229 EXPECT_EQ(0, L(5, 3, 1).Offset<int8_t>());
230 EXPECT_EQ(24, L(5, 3, 1).Offset<Int128>());
231 EXPECT_EQ(8, L(5, 3, 1).Offset<int32_t>());
235 TEST(Layout, Offsets) {
237 using L = Layout<int32_t>;
238 EXPECT_THAT(L::Partial().Offsets(), ElementsAre(0));
239 EXPECT_THAT(L::Partial(3).Offsets(), ElementsAre(0));
240 EXPECT_THAT(L(3).Offsets(), ElementsAre(0));
243 using L = Layout<int32_t, int32_t>;
244 EXPECT_THAT(L::Partial().Offsets(), ElementsAre(0));
245 EXPECT_THAT(L::Partial(3).Offsets(), ElementsAre(0, 12));
246 EXPECT_THAT(L::Partial(3, 5).Offsets(), ElementsAre(0, 12));
247 EXPECT_THAT(L(3, 5).Offsets(), ElementsAre(0, 12));
250 using L = Layout<int8_t, int32_t, Int128>;
251 EXPECT_THAT(L::Partial().Offsets(), ElementsAre(0));
252 EXPECT_THAT(L::Partial(1).Offsets(), ElementsAre(0, 4));
253 EXPECT_THAT(L::Partial(5).Offsets(), ElementsAre(0, 8));
254 EXPECT_THAT(L::Partial(0, 0).Offsets(), ElementsAre(0, 0, 0));
255 EXPECT_THAT(L::Partial(1, 0).Offsets(), ElementsAre(0, 4, 8));
256 EXPECT_THAT(L::Partial(5, 3).Offsets(), ElementsAre(0, 8, 24));
257 EXPECT_THAT(L::Partial(0, 0, 0).Offsets(), ElementsAre(0, 0, 0));
258 EXPECT_THAT(L::Partial(1, 0, 0).Offsets(), ElementsAre(0, 4, 8));
259 EXPECT_THAT(L::Partial(5, 3, 1).Offsets(), ElementsAre(0, 8, 24));
260 EXPECT_THAT(L(5, 3, 1).Offsets(), ElementsAre(0, 8, 24));
264 TEST(Layout, AllocSize) {
266 using L = Layout<int32_t>;
267 EXPECT_EQ(0, L::Partial(0).AllocSize());
268 EXPECT_EQ(12, L::Partial(3).AllocSize());
269 EXPECT_EQ(12, L(3).AllocSize());
272 using L = Layout<int32_t, int32_t>;
273 EXPECT_EQ(32, L::Partial(3, 5).AllocSize());
274 EXPECT_EQ(32, L(3, 5).AllocSize());
277 using L = Layout<int8_t, int32_t, Int128>;
278 EXPECT_EQ(0, L::Partial(0, 0, 0).AllocSize());
279 EXPECT_EQ(8, L::Partial(1, 0, 0).AllocSize());
280 EXPECT_EQ(8, L::Partial(0, 1, 0).AllocSize());
281 EXPECT_EQ(16, L::Partial(0, 0, 1).AllocSize());
282 EXPECT_EQ(24, L::Partial(1, 1, 1).AllocSize());
283 EXPECT_EQ(136, L::Partial(3, 5, 7).AllocSize());
284 EXPECT_EQ(136, L(3, 5, 7).AllocSize());
288 TEST(Layout, SizeByIndex) {
290 using L = Layout<int32_t>;
291 EXPECT_EQ(0, L::Partial(0).Size<0>());
292 EXPECT_EQ(3, L::Partial(3).Size<0>());
293 EXPECT_EQ(3, L(3).Size<0>());
296 using L = Layout<int32_t, int32_t>;
297 EXPECT_EQ(0, L::Partial(0).Size<0>());
298 EXPECT_EQ(3, L::Partial(3).Size<0>());
299 EXPECT_EQ(3, L::Partial(3, 5).Size<0>());
300 EXPECT_EQ(5, L::Partial(3, 5).Size<1>());
301 EXPECT_EQ(3, L(3, 5).Size<0>());
302 EXPECT_EQ(5, L(3, 5).Size<1>());
305 using L = Layout<int8_t, int32_t, Int128>;
306 EXPECT_EQ(3, L::Partial(3).Size<0>());
307 EXPECT_EQ(3, L::Partial(3, 5).Size<0>());
308 EXPECT_EQ(5, L::Partial(3, 5).Size<1>());
309 EXPECT_EQ(3, L::Partial(3, 5, 7).Size<0>());
310 EXPECT_EQ(5, L::Partial(3, 5, 7).Size<1>());
311 EXPECT_EQ(7, L::Partial(3, 5, 7).Size<2>());
312 EXPECT_EQ(3, L(3, 5, 7).Size<0>());
313 EXPECT_EQ(5, L(3, 5, 7).Size<1>());
314 EXPECT_EQ(7, L(3, 5, 7).Size<2>());
318 TEST(Layout, SizeByType) {
320 using L = Layout<int32_t>;
321 EXPECT_EQ(0, L::Partial(0).Size<int32_t>());
322 EXPECT_EQ(3, L::Partial(3).Size<int32_t>());
323 EXPECT_EQ(3, L(3).Size<int32_t>());
326 using L = Layout<int8_t, int32_t, Int128>;
327 EXPECT_EQ(3, L::Partial(3).Size<int8_t>());
328 EXPECT_EQ(3, L::Partial(3, 5).Size<int8_t>());
329 EXPECT_EQ(5, L::Partial(3, 5).Size<int32_t>());
330 EXPECT_EQ(3, L::Partial(3, 5, 7).Size<int8_t>());
331 EXPECT_EQ(5, L::Partial(3, 5, 7).Size<int32_t>());
332 EXPECT_EQ(7, L::Partial(3, 5, 7).Size<Int128>());
333 EXPECT_EQ(3, L(3, 5, 7).Size<int8_t>());
334 EXPECT_EQ(5, L(3, 5, 7).Size<int32_t>());
335 EXPECT_EQ(7, L(3, 5, 7).Size<Int128>());
339 TEST(Layout, Sizes) {
341 using L = Layout<int32_t>;
342 EXPECT_THAT(L::Partial().Sizes(), ElementsAre());
343 EXPECT_THAT(L::Partial(3).Sizes(), ElementsAre(3));
344 EXPECT_THAT(L(3).Sizes(), ElementsAre(3));
347 using L = Layout<int32_t, int32_t>;
348 EXPECT_THAT(L::Partial().Sizes(), ElementsAre());
349 EXPECT_THAT(L::Partial(3).Sizes(), ElementsAre(3));
350 EXPECT_THAT(L::Partial(3, 5).Sizes(), ElementsAre(3, 5));
351 EXPECT_THAT(L(3, 5).Sizes(), ElementsAre(3, 5));
354 using L = Layout<int8_t, int32_t, Int128>;
355 EXPECT_THAT(L::Partial().Sizes(), ElementsAre());
356 EXPECT_THAT(L::Partial(3).Sizes(), ElementsAre(3));
357 EXPECT_THAT(L::Partial(3, 5).Sizes(), ElementsAre(3, 5));
358 EXPECT_THAT(L::Partial(3, 5, 7).Sizes(), ElementsAre(3, 5, 7));
359 EXPECT_THAT(L(3, 5, 7).Sizes(), ElementsAre(3, 5, 7));
363 TEST(Layout, PointerByIndex) {
364 alignas(max_align_t)
const unsigned char p[100] = {};
366 using L = Layout<int32_t>;
367 EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L::Partial().Pointer<0>(p))));
368 EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<0>(p))));
369 EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L(3).Pointer<0>(p))));
372 using L = Layout<int32_t, int32_t>;
373 EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L::Partial().Pointer<0>(p))));
374 EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<0>(p))));
375 EXPECT_EQ(12, Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<1>(p))));
377 Distance(p, Type<const int32_t*>(L::Partial(3, 5).Pointer<0>(p))));
379 Distance(p, Type<const int32_t*>(L::Partial(3, 5).Pointer<1>(p))));
380 EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L(3, 5).Pointer<0>(p))));
381 EXPECT_EQ(12, Distance(p, Type<const int32_t*>(L(3, 5).Pointer<1>(p))));
384 using L = Layout<int8_t, int32_t, Int128>;
385 EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial().Pointer<0>(p))));
386 EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial(0).Pointer<0>(p))));
387 EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L::Partial(0).Pointer<1>(p))));
388 EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial(1).Pointer<0>(p))));
389 EXPECT_EQ(4, Distance(p, Type<const int32_t*>(L::Partial(1).Pointer<1>(p))));
390 EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial(5).Pointer<0>(p))));
391 EXPECT_EQ(8, Distance(p, Type<const int32_t*>(L::Partial(5).Pointer<1>(p))));
393 Distance(p, Type<const int8_t*>(L::Partial(0, 0).Pointer<0>(p))));
395 Distance(p, Type<const int32_t*>(L::Partial(0, 0).Pointer<1>(p))));
397 Distance(p, Type<const Int128*>(L::Partial(0, 0).Pointer<2>(p))));
399 Distance(p, Type<const int8_t*>(L::Partial(1, 0).Pointer<0>(p))));
401 Distance(p, Type<const int32_t*>(L::Partial(1, 0).Pointer<1>(p))));
403 Distance(p, Type<const Int128*>(L::Partial(1, 0).Pointer<2>(p))));
405 Distance(p, Type<const int8_t*>(L::Partial(5, 3).Pointer<0>(p))));
407 Distance(p, Type<const int32_t*>(L::Partial(5, 3).Pointer<1>(p))));
409 Distance(p, Type<const Int128*>(L::Partial(5, 3).Pointer<2>(p))));
411 0, Distance(p, Type<const int8_t*>(L::Partial(0, 0, 0).Pointer<0>(p))));
413 0, Distance(p, Type<const int32_t*>(L::Partial(0, 0, 0).Pointer<1>(p))));
415 0, Distance(p, Type<const Int128*>(L::Partial(0, 0, 0).Pointer<2>(p))));
417 0, Distance(p, Type<const int8_t*>(L::Partial(1, 0, 0).Pointer<0>(p))));
419 4, Distance(p, Type<const int32_t*>(L::Partial(1, 0, 0).Pointer<1>(p))));
421 8, Distance(p, Type<const Int128*>(L::Partial(1, 0, 0).Pointer<2>(p))));
423 0, Distance(p, Type<const int8_t*>(L::Partial(5, 3, 1).Pointer<0>(p))));
426 Distance(p, Type<const Int128*>(L::Partial(5, 3, 1).Pointer<2>(p))));
428 8, Distance(p, Type<const int32_t*>(L::Partial(5, 3, 1).Pointer<1>(p))));
429 EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L(5, 3, 1).Pointer<0>(p))));
430 EXPECT_EQ(24, Distance(p, Type<const Int128*>(L(5, 3, 1).Pointer<2>(p))));
431 EXPECT_EQ(8, Distance(p, Type<const int32_t*>(L(5, 3, 1).Pointer<1>(p))));
435 TEST(Layout, PointerByType) {
436 alignas(max_align_t)
const unsigned char p[100] = {};
438 using L = Layout<int32_t>;
440 Distance(p, Type<const int32_t*>(L::Partial().Pointer<int32_t>(p))));
442 Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<int32_t>(p))));
443 EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L(3).Pointer<int32_t>(p))));
446 using L = Layout<int8_t, int32_t, Int128>;
447 EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial().Pointer<int8_t>(p))));
449 Distance(p, Type<const int8_t*>(L::Partial(0).Pointer<int8_t>(p))));
451 Distance(p, Type<const int32_t*>(L::Partial(0).Pointer<int32_t>(p))));
453 Distance(p, Type<const int8_t*>(L::Partial(1).Pointer<int8_t>(p))));
455 Distance(p, Type<const int32_t*>(L::Partial(1).Pointer<int32_t>(p))));
457 Distance(p, Type<const int8_t*>(L::Partial(5).Pointer<int8_t>(p))));
459 Distance(p, Type<const int32_t*>(L::Partial(5).Pointer<int32_t>(p))));
461 0, Distance(p, Type<const int8_t*>(L::Partial(0, 0).Pointer<int8_t>(p))));
463 0, Distance(p, Type<const int32_t*>(L::Partial(0, 0).Pointer<int32_t>(p))));
466 Distance(p, Type<const Int128*>(L::Partial(0, 0).Pointer<Int128>(p))));
468 0, Distance(p, Type<const int8_t*>(L::Partial(1, 0).Pointer<int8_t>(p))));
470 4, Distance(p, Type<const int32_t*>(L::Partial(1, 0).Pointer<int32_t>(p))));
473 Distance(p, Type<const Int128*>(L::Partial(1, 0).Pointer<Int128>(p))));
475 0, Distance(p, Type<const int8_t*>(L::Partial(5, 3).Pointer<int8_t>(p))));
477 8, Distance(p, Type<const int32_t*>(L::Partial(5, 3).Pointer<int32_t>(p))));
480 Distance(p, Type<const Int128*>(L::Partial(5, 3).Pointer<Int128>(p))));
483 Distance(p, Type<const int8_t*>(L::Partial(0, 0, 0).Pointer<int8_t>(p))));
486 Distance(p, Type<const int32_t*>(L::Partial(0, 0, 0).Pointer<int32_t>(p))));
487 EXPECT_EQ(0, Distance(p, Type<const Int128*>(
488 L::Partial(0, 0, 0).Pointer<Int128>(p))));
491 Distance(p, Type<const int8_t*>(L::Partial(1, 0, 0).Pointer<int8_t>(p))));
494 Distance(p, Type<const int32_t*>(L::Partial(1, 0, 0).Pointer<int32_t>(p))));
495 EXPECT_EQ(8, Distance(p, Type<const Int128*>(
496 L::Partial(1, 0, 0).Pointer<Int128>(p))));
499 Distance(p, Type<const int8_t*>(L::Partial(5, 3, 1).Pointer<int8_t>(p))));
500 EXPECT_EQ(24, Distance(p, Type<const Int128*>(
501 L::Partial(5, 3, 1).Pointer<Int128>(p))));
504 Distance(p, Type<const int32_t*>(L::Partial(5, 3, 1).Pointer<int32_t>(p))));
506 Distance(p, Type<const Int128*>(L(5, 3, 1).Pointer<Int128>(p))));
507 EXPECT_EQ(8, Distance(p, Type<const int32_t*>(L(5, 3, 1).Pointer<int32_t>(p))));
511 TEST(Layout, MutablePointerByIndex) {
512 alignas(max_align_t)
unsigned char p[100];
514 using L = Layout<int32_t>;
515 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial().Pointer<0>(p))));
516 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(3).Pointer<0>(p))));
517 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L(3).Pointer<0>(p))));
520 using L = Layout<int32_t, int32_t>;
521 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial().Pointer<0>(p))));
522 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(3).Pointer<0>(p))));
523 EXPECT_EQ(12, Distance(p, Type<int32_t*>(L::Partial(3).Pointer<1>(p))));
524 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(3, 5).Pointer<0>(p))));
525 EXPECT_EQ(12, Distance(p, Type<int32_t*>(L::Partial(3, 5).Pointer<1>(p))));
526 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L(3, 5).Pointer<0>(p))));
527 EXPECT_EQ(12, Distance(p, Type<int32_t*>(L(3, 5).Pointer<1>(p))));
530 using L = Layout<int8_t, int32_t, Int128>;
531 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial().Pointer<0>(p))));
532 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0).Pointer<0>(p))));
533 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(0).Pointer<1>(p))));
534 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1).Pointer<0>(p))));
535 EXPECT_EQ(4, Distance(p, Type<int32_t*>(L::Partial(1).Pointer<1>(p))));
536 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5).Pointer<0>(p))));
537 EXPECT_EQ(8, Distance(p, Type<int32_t*>(L::Partial(5).Pointer<1>(p))));
538 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0, 0).Pointer<0>(p))));
539 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(0, 0).Pointer<1>(p))));
540 EXPECT_EQ(0, Distance(p, Type<Int128*>(L::Partial(0, 0).Pointer<2>(p))));
541 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1, 0).Pointer<0>(p))));
542 EXPECT_EQ(4, Distance(p, Type<int32_t*>(L::Partial(1, 0).Pointer<1>(p))));
543 EXPECT_EQ(8, Distance(p, Type<Int128*>(L::Partial(1, 0).Pointer<2>(p))));
544 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5, 3).Pointer<0>(p))));
545 EXPECT_EQ(8, Distance(p, Type<int32_t*>(L::Partial(5, 3).Pointer<1>(p))));
546 EXPECT_EQ(24, Distance(p, Type<Int128*>(L::Partial(5, 3).Pointer<2>(p))));
547 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0, 0, 0).Pointer<0>(p))));
548 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(0, 0, 0).Pointer<1>(p))));
549 EXPECT_EQ(0, Distance(p, Type<Int128*>(L::Partial(0, 0, 0).Pointer<2>(p))));
550 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1, 0, 0).Pointer<0>(p))));
551 EXPECT_EQ(4, Distance(p, Type<int32_t*>(L::Partial(1, 0, 0).Pointer<1>(p))));
552 EXPECT_EQ(8, Distance(p, Type<Int128*>(L::Partial(1, 0, 0).Pointer<2>(p))));
553 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5, 3, 1).Pointer<0>(p))));
555 Distance(p, Type<Int128*>(L::Partial(5, 3, 1).Pointer<2>(p))));
556 EXPECT_EQ(8, Distance(p, Type<int32_t*>(L::Partial(5, 3, 1).Pointer<1>(p))));
557 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L(5, 3, 1).Pointer<0>(p))));
558 EXPECT_EQ(24, Distance(p, Type<Int128*>(L(5, 3, 1).Pointer<2>(p))));
559 EXPECT_EQ(8, Distance(p, Type<int32_t*>(L(5, 3, 1).Pointer<1>(p))));
563 TEST(Layout, MutablePointerByType) {
564 alignas(max_align_t)
unsigned char p[100];
566 using L = Layout<int32_t>;
567 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial().Pointer<int32_t>(p))));
568 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(3).Pointer<int32_t>(p))));
569 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L(3).Pointer<int32_t>(p))));
572 using L = Layout<int8_t, int32_t, Int128>;
573 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial().Pointer<int8_t>(p))));
574 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0).Pointer<int8_t>(p))));
575 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(0).Pointer<int32_t>(p))));
576 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1).Pointer<int8_t>(p))));
577 EXPECT_EQ(4, Distance(p, Type<int32_t*>(L::Partial(1).Pointer<int32_t>(p))));
578 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5).Pointer<int8_t>(p))));
579 EXPECT_EQ(8, Distance(p, Type<int32_t*>(L::Partial(5).Pointer<int32_t>(p))));
580 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0, 0).Pointer<int8_t>(p))));
581 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(0, 0).Pointer<int32_t>(p))));
583 Distance(p, Type<Int128*>(L::Partial(0, 0).Pointer<Int128>(p))));
584 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1, 0).Pointer<int8_t>(p))));
585 EXPECT_EQ(4, Distance(p, Type<int32_t*>(L::Partial(1, 0).Pointer<int32_t>(p))));
587 Distance(p, Type<Int128*>(L::Partial(1, 0).Pointer<Int128>(p))));
588 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5, 3).Pointer<int8_t>(p))));
589 EXPECT_EQ(8, Distance(p, Type<int32_t*>(L::Partial(5, 3).Pointer<int32_t>(p))));
591 Distance(p, Type<Int128*>(L::Partial(5, 3).Pointer<Int128>(p))));
593 Distance(p, Type<int8_t*>(L::Partial(0, 0, 0).Pointer<int8_t>(p))));
595 Distance(p, Type<int32_t*>(L::Partial(0, 0, 0).Pointer<int32_t>(p))));
597 0, Distance(p, Type<Int128*>(L::Partial(0, 0, 0).Pointer<Int128>(p))));
599 Distance(p, Type<int8_t*>(L::Partial(1, 0, 0).Pointer<int8_t>(p))));
601 Distance(p, Type<int32_t*>(L::Partial(1, 0, 0).Pointer<int32_t>(p))));
603 8, Distance(p, Type<Int128*>(L::Partial(1, 0, 0).Pointer<Int128>(p))));
605 Distance(p, Type<int8_t*>(L::Partial(5, 3, 1).Pointer<int8_t>(p))));
607 24, Distance(p, Type<Int128*>(L::Partial(5, 3, 1).Pointer<Int128>(p))));
609 Distance(p, Type<int32_t*>(L::Partial(5, 3, 1).Pointer<int32_t>(p))));
610 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L(5, 3, 1).Pointer<int8_t>(p))));
611 EXPECT_EQ(24, Distance(p, Type<Int128*>(L(5, 3, 1).Pointer<Int128>(p))));
612 EXPECT_EQ(8, Distance(p, Type<int32_t*>(L(5, 3, 1).Pointer<int32_t>(p))));
616 TEST(Layout, Pointers) {
617 alignas(max_align_t)
const unsigned char p[100] = {};
618 using L = Layout<int8_t, int8_t, Int128>;
620 const auto x = L::Partial();
621 EXPECT_EQ(std::make_tuple(x.Pointer<0>(p)),
622 Type<std::tuple<const int8_t*>>(x.Pointers(p)));
625 const auto x = L::Partial(1);
626 EXPECT_EQ(std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p)),
627 (Type<std::tuple<const int8_t*, const int8_t*>>(x.Pointers(p))));
630 const auto x = L::Partial(1, 2);
632 std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
633 (Type<std::tuple<const int8_t*, const int8_t*, const Int128*>>(
637 const auto x = L::Partial(1, 2, 3);
639 std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
640 (Type<std::tuple<const int8_t*, const int8_t*, const Int128*>>(
646 std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
647 (Type<std::tuple<const int8_t*, const int8_t*, const Int128*>>(
652 TEST(Layout, MutablePointers) {
653 alignas(max_align_t)
unsigned char p[100];
654 using L = Layout<int8_t, int8_t, Int128>;
656 const auto x = L::Partial();
657 EXPECT_EQ(std::make_tuple(x.Pointer<0>(p)),
658 Type<std::tuple<int8_t*>>(x.Pointers(p)));
661 const auto x = L::Partial(1);
662 EXPECT_EQ(std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p)),
663 (Type<std::tuple<int8_t*, int8_t*>>(x.Pointers(p))));
666 const auto x = L::Partial(1, 2);
668 std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
669 (Type<std::tuple<int8_t*, int8_t*, Int128*>>(x.Pointers(p))));
672 const auto x = L::Partial(1, 2, 3);
674 std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
675 (Type<std::tuple<int8_t*, int8_t*, Int128*>>(x.Pointers(p))));
680 std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
681 (Type<std::tuple<int8_t*, int8_t*, Int128*>>(x.Pointers(p))));
685 TEST(Layout, SliceByIndexSize) {
686 alignas(max_align_t)
const unsigned char p[100] = {};
688 using L = Layout<int32_t>;
689 EXPECT_EQ(0, L::Partial(0).Slice<0>(p).
size());
690 EXPECT_EQ(3, L::Partial(3).Slice<0>(p).
size());
691 EXPECT_EQ(3, L(3).Slice<0>(p).
size());
694 using L = Layout<int32_t, int32_t>;
695 EXPECT_EQ(3, L::Partial(3).Slice<0>(p).
size());
696 EXPECT_EQ(5, L::Partial(3, 5).Slice<1>(p).
size());
697 EXPECT_EQ(5, L(3, 5).Slice<1>(p).
size());
700 using L = Layout<int8_t, int32_t, Int128>;
701 EXPECT_EQ(3, L::Partial(3).Slice<0>(p).
size());
702 EXPECT_EQ(3, L::Partial(3, 5).Slice<0>(p).
size());
703 EXPECT_EQ(5, L::Partial(3, 5).Slice<1>(p).
size());
704 EXPECT_EQ(3, L::Partial(3, 5, 7).Slice<0>(p).
size());
705 EXPECT_EQ(5, L::Partial(3, 5, 7).Slice<1>(p).
size());
706 EXPECT_EQ(7, L::Partial(3, 5, 7).Slice<2>(p).
size());
707 EXPECT_EQ(3, L(3, 5, 7).Slice<0>(p).
size());
708 EXPECT_EQ(5, L(3, 5, 7).Slice<1>(p).
size());
709 EXPECT_EQ(7, L(3, 5, 7).Slice<2>(p).
size());
713 TEST(Layout, SliceByTypeSize) {
714 alignas(max_align_t)
const unsigned char p[100] = {};
716 using L = Layout<int32_t>;
717 EXPECT_EQ(0, L::Partial(0).Slice<int32_t>(p).
size());
718 EXPECT_EQ(3, L::Partial(3).Slice<int32_t>(p).
size());
719 EXPECT_EQ(3, L(3).Slice<int32_t>(p).
size());
722 using L = Layout<int8_t, int32_t, Int128>;
723 EXPECT_EQ(3, L::Partial(3).Slice<int8_t>(p).
size());
724 EXPECT_EQ(3, L::Partial(3, 5).Slice<int8_t>(p).
size());
725 EXPECT_EQ(5, L::Partial(3, 5).Slice<int32_t>(p).
size());
726 EXPECT_EQ(3, L::Partial(3, 5, 7).Slice<int8_t>(p).
size());
727 EXPECT_EQ(5, L::Partial(3, 5, 7).Slice<int32_t>(p).
size());
728 EXPECT_EQ(7, L::Partial(3, 5, 7).Slice<Int128>(p).
size());
729 EXPECT_EQ(3, L(3, 5, 7).Slice<int8_t>(p).
size());
730 EXPECT_EQ(5, L(3, 5, 7).Slice<int32_t>(p).
size());
731 EXPECT_EQ(7, L(3, 5, 7).Slice<Int128>(p).
size());
735 TEST(Layout, MutableSliceByIndexSize) {
736 alignas(max_align_t)
unsigned char p[100];
738 using L = Layout<int32_t>;
739 EXPECT_EQ(0, L::Partial(0).Slice<0>(p).
size());
740 EXPECT_EQ(3, L::Partial(3).Slice<0>(p).
size());
741 EXPECT_EQ(3, L(3).Slice<0>(p).
size());
744 using L = Layout<int32_t, int32_t>;
745 EXPECT_EQ(3, L::Partial(3).Slice<0>(p).
size());
746 EXPECT_EQ(5, L::Partial(3, 5).Slice<1>(p).
size());
747 EXPECT_EQ(5, L(3, 5).Slice<1>(p).
size());
750 using L = Layout<int8_t, int32_t, Int128>;
751 EXPECT_EQ(3, L::Partial(3).Slice<0>(p).
size());
752 EXPECT_EQ(3, L::Partial(3, 5).Slice<0>(p).
size());
753 EXPECT_EQ(5, L::Partial(3, 5).Slice<1>(p).
size());
754 EXPECT_EQ(3, L::Partial(3, 5, 7).Slice<0>(p).
size());
755 EXPECT_EQ(5, L::Partial(3, 5, 7).Slice<1>(p).
size());
756 EXPECT_EQ(7, L::Partial(3, 5, 7).Slice<2>(p).
size());
757 EXPECT_EQ(3, L(3, 5, 7).Slice<0>(p).
size());
758 EXPECT_EQ(5, L(3, 5, 7).Slice<1>(p).
size());
759 EXPECT_EQ(7, L(3, 5, 7).Slice<2>(p).
size());
763 TEST(Layout, MutableSliceByTypeSize) {
764 alignas(max_align_t)
unsigned char p[100];
766 using L = Layout<int32_t>;
767 EXPECT_EQ(0, L::Partial(0).Slice<int32_t>(p).
size());
768 EXPECT_EQ(3, L::Partial(3).Slice<int32_t>(p).
size());
769 EXPECT_EQ(3, L(3).Slice<int32_t>(p).
size());
772 using L = Layout<int8_t, int32_t, Int128>;
773 EXPECT_EQ(3, L::Partial(3).Slice<int8_t>(p).
size());
774 EXPECT_EQ(3, L::Partial(3, 5).Slice<int8_t>(p).
size());
775 EXPECT_EQ(5, L::Partial(3, 5).Slice<int32_t>(p).
size());
776 EXPECT_EQ(3, L::Partial(3, 5, 7).Slice<int8_t>(p).
size());
777 EXPECT_EQ(5, L::Partial(3, 5, 7).Slice<int32_t>(p).
size());
778 EXPECT_EQ(7, L::Partial(3, 5, 7).Slice<Int128>(p).
size());
779 EXPECT_EQ(3, L(3, 5, 7).Slice<int8_t>(p).
size());
780 EXPECT_EQ(5, L(3, 5, 7).Slice<int32_t>(p).
size());
781 EXPECT_EQ(7, L(3, 5, 7).Slice<Int128>(p).
size());
785 TEST(Layout, SliceByIndexData) {
786 alignas(max_align_t)
const unsigned char p[100] = {};
788 using L = Layout<int32_t>;
791 Distance(p, Type<Span<const int32_t>>(L::Partial(0).Slice<0>(p)).
data()));
794 Distance(p, Type<Span<const int32_t>>(L::Partial(3).Slice<0>(p)).
data()));
795 EXPECT_EQ(0, Distance(p, Type<Span<const int32_t>>(L(3).Slice<0>(p)).
data()));
798 using L = Layout<int32_t, int32_t>;
801 Distance(p, Type<Span<const int32_t>>(L::Partial(3).Slice<0>(p)).
data()));
805 Type<Span<const int32_t>>(L::Partial(3, 5).Slice<0>(p)).
data()));
809 Type<Span<const int32_t>>(L::Partial(3, 5).Slice<1>(p)).
data()));
811 Distance(p, Type<Span<const int32_t>>(L(3, 5).Slice<0>(p)).
data()));
813 Distance(p, Type<Span<const int32_t>>(L(3, 5).Slice<1>(p)).
data()));
816 using L = Layout<int8_t, int32_t, Int128>;
819 Distance(p, Type<Span<const int8_t>>(L::Partial(0).Slice<0>(p)).
data()));
822 Distance(p, Type<Span<const int8_t>>(L::Partial(1).Slice<0>(p)).
data()));
825 Distance(p, Type<Span<const int8_t>>(L::Partial(5).Slice<0>(p)).
data()));
828 p, Type<Span<const int8_t>>(L::Partial(0, 0).Slice<0>(p)).
data()));
832 Type<Span<const int32_t>>(L::Partial(0, 0).Slice<1>(p)).
data()));
835 p, Type<Span<const int8_t>>(L::Partial(1, 0).Slice<0>(p)).
data()));
839 Type<Span<const int32_t>>(L::Partial(1, 0).Slice<1>(p)).
data()));
842 p, Type<Span<const int8_t>>(L::Partial(5, 3).Slice<0>(p)).
data()));
846 Type<Span<const int32_t>>(L::Partial(5, 3).Slice<1>(p)).
data()));
850 p, Type<Span<const int8_t>>(L::Partial(0, 0, 0).Slice<0>(p)).
data()));
855 Type<Span<const int32_t>>(L::Partial(0, 0, 0).Slice<1>(p)).
data()));
860 Type<Span<const Int128>>(L::Partial(0, 0, 0).Slice<2>(p)).
data()));
864 p, Type<Span<const int8_t>>(L::Partial(1, 0, 0).Slice<0>(p)).
data()));
869 Type<Span<const int32_t>>(L::Partial(1, 0, 0).Slice<1>(p)).
data()));
874 Type<Span<const Int128>>(L::Partial(1, 0, 0).Slice<2>(p)).
data()));
878 p, Type<Span<const int8_t>>(L::Partial(5, 3, 1).Slice<0>(p)).
data()));
883 Type<Span<const Int128>>(L::Partial(5, 3, 1).Slice<2>(p)).
data()));
888 Type<Span<const int32_t>>(L::Partial(5, 3, 1).Slice<1>(p)).
data()));
890 0, Distance(p, Type<Span<const int8_t>>(L(5, 3, 1).Slice<0>(p)).
data()));
893 Distance(p, Type<Span<const Int128>>(L(5, 3, 1).Slice<2>(p)).
data()));
895 8, Distance(p, Type<Span<const int32_t>>(L(5, 3, 1).Slice<1>(p)).
data()));
899 TEST(Layout, SliceByTypeData) {
900 alignas(max_align_t)
const unsigned char p[100] = {};
902 using L = Layout<int32_t>;
906 p, Type<Span<const int32_t>>(L::Partial(0).Slice<int32_t>(p)).
data()));
910 p, Type<Span<const int32_t>>(L::Partial(3).Slice<int32_t>(p)).
data()));
912 0, Distance(p, Type<Span<const int32_t>>(L(3).Slice<int32_t>(p)).
data()));
915 using L = Layout<int8_t, int32_t, Int128>;
918 p, Type<Span<const int8_t>>(L::Partial(0).Slice<int8_t>(p)).
data()));
921 p, Type<Span<const int8_t>>(L::Partial(1).Slice<int8_t>(p)).
data()));
924 p, Type<Span<const int8_t>>(L::Partial(5).Slice<int8_t>(p)).
data()));
928 p, Type<Span<const int8_t>>(L::Partial(0, 0).Slice<int8_t>(p)).
data()));
933 Type<Span<const int32_t>>(L::Partial(0, 0).Slice<int32_t>(p)).
data()));
937 p, Type<Span<const int8_t>>(L::Partial(1, 0).Slice<int8_t>(p)).
data()));
942 Type<Span<const int32_t>>(L::Partial(1, 0).Slice<int32_t>(p)).
data()));
946 p, Type<Span<const int8_t>>(L::Partial(5, 3).Slice<int8_t>(p)).
data()));
951 Type<Span<const int32_t>>(L::Partial(5, 3).Slice<int32_t>(p)).
data()));
956 Type<Span<const int8_t>>(L::Partial(0, 0, 0).Slice<int8_t>(p)).
data()));
959 Distance(p, Type<Span<const int32_t>>(L::Partial(0, 0, 0).Slice<int32_t>(p))
961 EXPECT_EQ(0, Distance(p, Type<Span<const Int128>>(
962 L::Partial(0, 0, 0).Slice<Int128>(p))
968 Type<Span<const int8_t>>(L::Partial(1, 0, 0).Slice<int8_t>(p)).
data()));
971 Distance(p, Type<Span<const int32_t>>(L::Partial(1, 0, 0).Slice<int32_t>(p))
973 EXPECT_EQ(8, Distance(p, Type<Span<const Int128>>(
974 L::Partial(1, 0, 0).Slice<Int128>(p))
980 Type<Span<const int8_t>>(L::Partial(5, 3, 1).Slice<int8_t>(p)).
data()));
981 EXPECT_EQ(24, Distance(p, Type<Span<const Int128>>(
982 L::Partial(5, 3, 1).Slice<Int128>(p))
986 Distance(p, Type<Span<const int32_t>>(L::Partial(5, 3, 1).Slice<int32_t>(p))
990 Distance(p, Type<Span<const int8_t>>(L(5, 3, 1).Slice<int8_t>(p)).
data()));
994 Type<Span<const Int128>>(L(5, 3, 1).Slice<Int128>(p)).
data()));
997 p, Type<Span<const int32_t>>(L(5, 3, 1).Slice<int32_t>(p)).
data()));
1001 TEST(Layout, MutableSliceByIndexData) {
1002 alignas(max_align_t)
unsigned char p[100];
1004 using L = Layout<int32_t>;
1006 Distance(p, Type<Span<int32_t>>(L::Partial(0).Slice<0>(p)).
data()));
1008 Distance(p, Type<Span<int32_t>>(L::Partial(3).Slice<0>(p)).
data()));
1009 EXPECT_EQ(0, Distance(p, Type<Span<int32_t>>(L(3).Slice<0>(p)).
data()));
1012 using L = Layout<int32_t, int32_t>;
1014 Distance(p, Type<Span<int32_t>>(L::Partial(3).Slice<0>(p)).
data()));
1016 0, Distance(p, Type<Span<int32_t>>(L::Partial(3, 5).Slice<0>(p)).
data()));
1019 Distance(p, Type<Span<int32_t>>(L::Partial(3, 5).Slice<1>(p)).
data()));
1020 EXPECT_EQ(0, Distance(p, Type<Span<int32_t>>(L(3, 5).Slice<0>(p)).
data()));
1021 EXPECT_EQ(12, Distance(p, Type<Span<int32_t>>(L(3, 5).Slice<1>(p)).
data()));
1024 using L = Layout<int8_t, int32_t, Int128>;
1026 Distance(p, Type<Span<int8_t>>(L::Partial(0).Slice<0>(p)).
data()));
1028 Distance(p, Type<Span<int8_t>>(L::Partial(1).Slice<0>(p)).
data()));
1030 Distance(p, Type<Span<int8_t>>(L::Partial(5).Slice<0>(p)).
data()));
1032 0, Distance(p, Type<Span<int8_t>>(L::Partial(0, 0).Slice<0>(p)).
data()));
1034 0, Distance(p, Type<Span<int32_t>>(L::Partial(0, 0).Slice<1>(p)).
data()));
1036 0, Distance(p, Type<Span<int8_t>>(L::Partial(1, 0).Slice<0>(p)).
data()));
1038 4, Distance(p, Type<Span<int32_t>>(L::Partial(1, 0).Slice<1>(p)).
data()));
1040 0, Distance(p, Type<Span<int8_t>>(L::Partial(5, 3).Slice<0>(p)).
data()));
1042 8, Distance(p, Type<Span<int32_t>>(L::Partial(5, 3).Slice<1>(p)).
data()));
1045 Distance(p, Type<Span<int8_t>>(L::Partial(0, 0, 0).Slice<0>(p)).
data()));
1048 Distance(p, Type<Span<int32_t>>(L::Partial(0, 0, 0).Slice<1>(p)).
data()));
1051 p, Type<Span<Int128>>(L::Partial(0, 0, 0).Slice<2>(p)).
data()));
1054 Distance(p, Type<Span<int8_t>>(L::Partial(1, 0, 0).Slice<0>(p)).
data()));
1057 Distance(p, Type<Span<int32_t>>(L::Partial(1, 0, 0).Slice<1>(p)).
data()));
1060 p, Type<Span<Int128>>(L::Partial(1, 0, 0).Slice<2>(p)).
data()));
1063 Distance(p, Type<Span<int8_t>>(L::Partial(5, 3, 1).Slice<0>(p)).
data()));
1066 p, Type<Span<Int128>>(L::Partial(5, 3, 1).Slice<2>(p)).
data()));
1069 Distance(p, Type<Span<int32_t>>(L::Partial(5, 3, 1).Slice<1>(p)).
data()));
1070 EXPECT_EQ(0, Distance(p, Type<Span<int8_t>>(L(5, 3, 1).Slice<0>(p)).
data()));
1072 Distance(p, Type<Span<Int128>>(L(5, 3, 1).Slice<2>(p)).
data()));
1073 EXPECT_EQ(8, Distance(p, Type<Span<int32_t>>(L(5, 3, 1).Slice<1>(p)).
data()));
1077 TEST(Layout, MutableSliceByTypeData) {
1078 alignas(max_align_t)
unsigned char p[100];
1080 using L = Layout<int32_t>;
1083 Distance(p, Type<Span<int32_t>>(L::Partial(0).Slice<int32_t>(p)).
data()));
1086 Distance(p, Type<Span<int32_t>>(L::Partial(3).Slice<int32_t>(p)).
data()));
1087 EXPECT_EQ(0, Distance(p, Type<Span<int32_t>>(L(3).Slice<int32_t>(p)).
data()));
1090 using L = Layout<int8_t, int32_t, Int128>;
1092 0, Distance(p, Type<Span<int8_t>>(L::Partial(0).Slice<int8_t>(p)).
data()));
1094 0, Distance(p, Type<Span<int8_t>>(L::Partial(1).Slice<int8_t>(p)).
data()));
1096 0, Distance(p, Type<Span<int8_t>>(L::Partial(5).Slice<int8_t>(p)).
data()));
1099 Distance(p, Type<Span<int8_t>>(L::Partial(0, 0).Slice<int8_t>(p)).
data()));
1102 p, Type<Span<int32_t>>(L::Partial(0, 0).Slice<int32_t>(p)).
data()));
1105 Distance(p, Type<Span<int8_t>>(L::Partial(1, 0).Slice<int8_t>(p)).
data()));
1108 p, Type<Span<int32_t>>(L::Partial(1, 0).Slice<int32_t>(p)).
data()));
1111 Distance(p, Type<Span<int8_t>>(L::Partial(5, 3).Slice<int8_t>(p)).
data()));
1114 p, Type<Span<int32_t>>(L::Partial(5, 3).Slice<int32_t>(p)).
data()));
1117 p, Type<Span<int8_t>>(L::Partial(0, 0, 0).Slice<int8_t>(p)).
data()));
1121 p, Type<Span<int32_t>>(L::Partial(0, 0, 0).Slice<int32_t>(p)).
data()));
1126 Type<Span<Int128>>(L::Partial(0, 0, 0).Slice<Int128>(p)).
data()));
1129 p, Type<Span<int8_t>>(L::Partial(1, 0, 0).Slice<int8_t>(p)).
data()));
1133 p, Type<Span<int32_t>>(L::Partial(1, 0, 0).Slice<int32_t>(p)).
data()));
1138 Type<Span<Int128>>(L::Partial(1, 0, 0).Slice<Int128>(p)).
data()));
1141 p, Type<Span<int8_t>>(L::Partial(5, 3, 1).Slice<int8_t>(p)).
data()));
1146 Type<Span<Int128>>(L::Partial(5, 3, 1).Slice<Int128>(p)).
data()));
1150 p, Type<Span<int32_t>>(L::Partial(5, 3, 1).Slice<int32_t>(p)).
data()));
1152 Distance(p, Type<Span<int8_t>>(L(5, 3, 1).Slice<int8_t>(p)).
data()));
1155 Distance(p, Type<Span<Int128>>(L(5, 3, 1).Slice<Int128>(p)).
data()));
1157 8, Distance(p, Type<Span<int32_t>>(L(5, 3, 1).Slice<int32_t>(p)).
data()));
1161 MATCHER_P(IsSameSlice, slice,
"") {
1162 return arg.size() == slice.size() &&
arg.data() == slice.data();
1165 template <
typename... M>
1166 class TupleMatcher {
1170 template <
typename Tuple>
1171 bool MatchAndExplain(
const Tuple& p,
1172 testing::MatchResultListener* )
const {
1174 return MatchAndExplainImpl(
1180 void DescribeTo(::std::ostream* os)
const {}
1181 void DescribeNegationTo(::std::ostream* os)
const {}
1184 template <
typename Tuple,
size_t... Is>
1188 {
true, testing::SafeMatcherCast<
1189 const typename std::tuple_element<Is, Tuple>::type&>(
1191 .Matches(std::get<Is>(p))...});
1197 template <
typename... M>
1198 testing::PolymorphicMatcher<TupleMatcher<M...>> Tuple(M... matchers) {
1199 return testing::MakePolymorphicMatcher(
1200 TupleMatcher<M...>(
std::move(matchers)...));
1203 TEST(Layout, Slices) {
1204 alignas(max_align_t)
const unsigned char p[100] = {};
1205 using L = Layout<int8_t, int8_t, Int128>;
1207 const auto x = L::Partial();
1208 EXPECT_THAT(Type<std::tuple<>>(x.Slices(p)), Tuple());
1211 const auto x = L::Partial(1);
1212 EXPECT_THAT(Type<std::tuple<Span<const int8_t>>>(x.Slices(p)),
1213 Tuple(IsSameSlice(x.Slice<0>(p))));
1216 const auto x = L::Partial(1, 2);
1218 (Type<std::tuple<Span<const int8_t>, Span<const int8_t>>>(x.Slices(p))),
1219 Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p))));
1222 const auto x = L::Partial(1, 2, 3);
1223 EXPECT_THAT((Type<std::tuple<Span<const int8_t>, Span<const int8_t>,
1224 Span<const Int128>>>(x.Slices(p))),
1225 Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)),
1226 IsSameSlice(x.Slice<2>(p))));
1230 EXPECT_THAT((Type<std::tuple<Span<const int8_t>, Span<const int8_t>,
1231 Span<const Int128>>>(x.Slices(p))),
1232 Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)),
1233 IsSameSlice(x.Slice<2>(p))));
1237 TEST(Layout, MutableSlices) {
1238 alignas(max_align_t)
unsigned char p[100] = {};
1239 using L = Layout<int8_t, int8_t, Int128>;
1241 const auto x = L::Partial();
1242 EXPECT_THAT(Type<std::tuple<>>(x.Slices(p)), Tuple());
1245 const auto x = L::Partial(1);
1246 EXPECT_THAT(Type<std::tuple<Span<int8_t>>>(x.Slices(p)),
1247 Tuple(IsSameSlice(x.Slice<0>(p))));
1250 const auto x = L::Partial(1, 2);
1251 EXPECT_THAT((Type<std::tuple<Span<int8_t>, Span<int8_t>>>(x.Slices(p))),
1252 Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p))));
1255 const auto x = L::Partial(1, 2, 3);
1257 (Type<std::tuple<Span<int8_t>, Span<int8_t>, Span<Int128>>>(x.Slices(p))),
1258 Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)),
1259 IsSameSlice(x.Slice<2>(p))));
1264 (Type<std::tuple<Span<int8_t>, Span<int8_t>, Span<Int128>>>(x.Slices(p))),
1265 Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)),
1266 IsSameSlice(x.Slice<2>(p))));
1270 TEST(Layout, UnalignedTypes) {
1271 constexpr Layout<unsigned char, unsigned char, unsigned char> x(1, 2, 3);
1272 alignas(max_align_t)
unsigned char p[x.AllocSize() + 1];
1273 EXPECT_THAT(x.Pointers(p + 1), Tuple(p + 1, p + 2, p + 4));
1276 TEST(Layout, CustomAlignment) {
1277 constexpr Layout<unsigned char, Aligned<unsigned char, 8>> x(1, 2);
1278 alignas(max_align_t)
unsigned char p[x.AllocSize()];
1279 EXPECT_EQ(10, x.AllocSize());
1280 EXPECT_THAT(x.Pointers(p), Tuple(p + 0, p + 8));
1283 TEST(Layout, OverAligned) {
1284 constexpr
size_t M =
alignof(max_align_t);
1285 constexpr Layout<unsigned char, Aligned<unsigned char, 2 * M>> x(1, 3);
1286 alignas(2 * M)
unsigned char p[x.AllocSize()];
1287 EXPECT_EQ(2 * M + 3, x.AllocSize());
1288 EXPECT_THAT(x.Pointers(p), Tuple(p + 0, p + 2 * M));
1291 TEST(Layout, Alignment) {
1292 static_assert(Layout<int8_t>::Alignment() == 1,
"");
1293 static_assert(Layout<int32_t>::Alignment() == 4,
"");
1294 static_assert(Layout<Int64>::Alignment() == 8,
"");
1295 static_assert(Layout<Aligned<int8_t, 64>>::Alignment() == 64,
"");
1296 static_assert(Layout<int8_t, int32_t, Int64>::Alignment() == 8,
"");
1297 static_assert(Layout<int8_t, Int64, int32_t>::Alignment() == 8,
"");
1298 static_assert(Layout<int32_t, int8_t, Int64>::Alignment() == 8,
"");
1299 static_assert(Layout<int32_t, Int64, int8_t>::Alignment() == 8,
"");
1300 static_assert(Layout<Int64, int8_t, int32_t>::Alignment() == 8,
"");
1301 static_assert(Layout<Int64, int32_t, int8_t>::Alignment() == 8,
"");
1304 TEST(Layout, ConstexprPartial) {
1305 constexpr
size_t M =
alignof(max_align_t);
1306 constexpr Layout<unsigned char, Aligned<unsigned char, 2 * M>> x(1, 3);
1307 static_assert(x.Partial(1).template Offset<1>() == 2 * M,
"");
1315 void ExpectRegionPoisoned(
const unsigned char* p,
size_t n,
bool poisoned) {
1316 #ifdef ADDRESS_SANITIZER 1317 for (
size_t i = 0;
i !=
n; ++
i) {
1318 EXPECT_EQ(poisoned, __asan_address_is_poisoned(p +
i));
1324 void ExpectPoisoned(
const unsigned char (&
buf)[N],
1325 std::initializer_list<Region> reg) {
1327 for (
const Region& r : reg) {
1328 ExpectRegionPoisoned(
buf + prev, r.from - prev,
false);
1329 ExpectRegionPoisoned(
buf + r.from, r.to - r.from,
true);
1332 ExpectRegionPoisoned(
buf + prev, N - prev,
false);
1335 TEST(Layout, PoisonPadding) {
1336 using L = Layout<int8_t, Int64, int32_t, Int128>;
1338 constexpr
size_t n = L::Partial(1, 2, 3, 4).AllocSize();
1340 constexpr
auto x = L::Partial();
1341 alignas(max_align_t)
const unsigned char c[n] = {};
1343 EXPECT_EQ(x.Slices(c), x.Slices(c));
1344 ExpectPoisoned(c, {});
1347 constexpr
auto x = L::Partial(1);
1348 alignas(max_align_t)
const unsigned char c[n] = {};
1350 EXPECT_EQ(x.Slices(c), x.Slices(c));
1351 ExpectPoisoned(c, {{1, 8}});
1354 constexpr
auto x = L::Partial(1, 2);
1355 alignas(max_align_t)
const unsigned char c[n] = {};
1357 EXPECT_EQ(x.Slices(c), x.Slices(c));
1358 ExpectPoisoned(c, {{1, 8}});
1361 constexpr
auto x = L::Partial(1, 2, 3);
1362 alignas(max_align_t)
const unsigned char c[n] = {};
1364 EXPECT_EQ(x.Slices(c), x.Slices(c));
1365 ExpectPoisoned(c, {{1, 8}, {36, 40}});
1368 constexpr
auto x = L::Partial(1, 2, 3, 4);
1369 alignas(max_align_t)
const unsigned char c[n] = {};
1371 EXPECT_EQ(x.Slices(c), x.Slices(c));
1372 ExpectPoisoned(c, {{1, 8}, {36, 40}});
1375 constexpr L x(1, 2, 3, 4);
1376 alignas(max_align_t)
const unsigned char c[n] = {};
1378 EXPECT_EQ(x.Slices(c), x.Slices(c));
1379 ExpectPoisoned(c, {{1, 8}, {36, 40}});
1383 TEST(Layout, DebugString) {
1386 EXPECT_EQ(
"@0<signed char>(1)", x.DebugString());
1390 EXPECT_EQ(
"@0<signed char>(1)[1]; @4<int>(4)", x.DebugString());
1394 EXPECT_EQ(
"@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)",
1400 "@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)[3]; " 1402 Int128::Name() +
"(16)",
1408 "@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)[3]; " 1410 Int128::Name() +
"(16)[4]",
1414 constexpr Layout<int8_t, int32_t, int8_t, Int128> x(1, 2, 3, 4);
1416 "@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)[3]; " 1418 Int128::Name() +
"(16)[4]",
1423 TEST(Layout, CharTypes) {
1424 constexpr Layout<int32_t> x(1);
1425 alignas(max_align_t)
char c[x.AllocSize()] = {};
1426 alignas(max_align_t)
unsigned char uc[x.AllocSize()] = {};
1427 alignas(max_align_t)
signed char sc[x.AllocSize()] = {};
1428 alignas(max_align_t)
const char cc[x.AllocSize()] = {};
1429 alignas(max_align_t)
const unsigned char cuc[x.AllocSize()] = {};
1430 alignas(max_align_t)
const signed char csc[x.AllocSize()] = {};
1432 Type<int32_t*>(x.Pointer<0>(c));
1433 Type<int32_t*>(x.Pointer<0>(uc));
1434 Type<int32_t*>(x.Pointer<0>(sc));
1435 Type<const int32_t*>(x.Pointer<0>(cc));
1436 Type<const int32_t*>(x.Pointer<0>(cuc));
1437 Type<const int32_t*>(x.Pointer<0>(csc));
1439 Type<int32_t*>(x.Pointer<int32_t>(c));
1440 Type<int32_t*>(x.Pointer<int32_t>(uc));
1441 Type<int32_t*>(x.Pointer<int32_t>(sc));
1442 Type<const int32_t*>(x.Pointer<int32_t>(cc));
1443 Type<const int32_t*>(x.Pointer<int32_t>(cuc));
1444 Type<const int32_t*>(x.Pointer<int32_t>(csc));
1446 Type<std::tuple<int32_t*>>(x.Pointers(c));
1447 Type<std::tuple<int32_t*>>(x.Pointers(uc));
1448 Type<std::tuple<int32_t*>>(x.Pointers(sc));
1449 Type<std::tuple<const int32_t*>>(x.Pointers(cc));
1450 Type<std::tuple<const int32_t*>>(x.Pointers(cuc));
1451 Type<std::tuple<const int32_t*>>(x.Pointers(csc));
1453 Type<Span<int32_t>>(x.Slice<0>(c));
1454 Type<Span<int32_t>>(x.Slice<0>(uc));
1455 Type<Span<int32_t>>(x.Slice<0>(sc));
1456 Type<Span<const int32_t>>(x.Slice<0>(cc));
1457 Type<Span<const int32_t>>(x.Slice<0>(cuc));
1458 Type<Span<const int32_t>>(x.Slice<0>(csc));
1460 Type<std::tuple<Span<int32_t>>>(x.Slices(c));
1461 Type<std::tuple<Span<int32_t>>>(x.Slices(uc));
1462 Type<std::tuple<Span<int32_t>>>(x.Slices(sc));
1463 Type<std::tuple<Span<const int32_t>>>(x.Slices(cc));
1464 Type<std::tuple<Span<const int32_t>>>(x.Slices(cuc));
1465 Type<std::tuple<Span<const int32_t>>>(x.Slices(csc));
1468 TEST(Layout, ConstElementType) {
1469 constexpr Layout<const int32_t> x(1);
1470 alignas(int32_t)
char c[x.AllocSize()] = {};
1472 const int32_t* p =
reinterpret_cast<const int32_t*
>(cc);
1474 EXPECT_EQ(
alignof(int32_t), x.Alignment());
1476 EXPECT_EQ(0, x.Offset<0>());
1477 EXPECT_EQ(0, x.Offset<
const int32_t>());
1479 EXPECT_THAT(x.Offsets(), ElementsAre(0));
1481 EXPECT_EQ(1, x.Size<0>());
1482 EXPECT_EQ(1, x.Size<
const int32_t>());
1484 EXPECT_THAT(x.Sizes(), ElementsAre(1));
1486 EXPECT_EQ(
sizeof(int32_t), x.AllocSize());
1488 EXPECT_EQ(p, Type<const int32_t*>(x.Pointer<0>(c)));
1489 EXPECT_EQ(p, Type<const int32_t*>(x.Pointer<0>(cc)));
1491 EXPECT_EQ(p, Type<const int32_t*>(x.Pointer<
const int32_t>(c)));
1492 EXPECT_EQ(p, Type<const int32_t*>(x.Pointer<
const int32_t>(cc)));
1494 EXPECT_THAT(Type<std::tuple<const int32_t*>>(x.Pointers(c)), Tuple(p));
1495 EXPECT_THAT(Type<std::tuple<const int32_t*>>(x.Pointers(cc)), Tuple(p));
1497 EXPECT_THAT(Type<Span<const int32_t>>(x.Slice<0>(c)),
1498 IsSameSlice(Span<const int32_t>(p, 1)));
1499 EXPECT_THAT(Type<Span<const int32_t>>(x.Slice<0>(cc)),
1500 IsSameSlice(Span<const int32_t>(p, 1)));
1502 EXPECT_THAT(Type<Span<const int32_t>>(x.Slice<
const int32_t>(c)),
1503 IsSameSlice(Span<const int32_t>(p, 1)));
1504 EXPECT_THAT(Type<Span<const int32_t>>(x.Slice<
const int32_t>(cc)),
1505 IsSameSlice(Span<const int32_t>(p, 1)));
1507 EXPECT_THAT(Type<std::tuple<Span<const int32_t>>>(x.Slices(c)),
1508 Tuple(IsSameSlice(Span<const int32_t>(p, 1))));
1509 EXPECT_THAT(Type<std::tuple<Span<const int32_t>>>(x.Slices(cc)),
1510 Tuple(IsSameSlice(Span<const int32_t>(p, 1))));
1517 class CompactString {
1519 CompactString(
const char* s =
"") {
1520 const size_t size = strlen(s);
1523 const L layout(1, size + 1);
1526 p_.reset(
new unsigned char[layout.AllocSize()]);
1529 layout.PoisonPadding(
p_.get());
1532 *layout.Pointer<
size_t>(
p_.get()) = size;
1534 memcpy(layout.Pointer<
char>(
p_.get()), s, size + 1);
1537 size_t size()
const {
1539 return *L::Partial().Pointer<
size_t>(
p_.get());
1542 const char* c_str()
const {
1546 return L::Partial(1).Pointer<
char>(
p_.get());
1552 std::unique_ptr<unsigned char[]>
p_;
1555 TEST(CompactString, Works) {
1556 CompactString s =
"hello";
1557 EXPECT_EQ(5, s.size());
1558 EXPECT_STREQ(
"hello", s.c_str());
TEST(NotificationTest, SanityTest)
make_integer_sequence< size_t, N > make_index_sequence
std::tuple< M... > matchers_
#define ABSL_RAW_CHECK(condition, message)
bool operator==(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
static char data[kDataSize]
static constexpr PartialType< sizeof...(Sizes)> Partial(Sizes &&...sizes)
std::unique_ptr< unsigned char[]> p_
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept