15 #include "absl/container/internal/layout.h"
24 #include <type_traits>
26 #include "gmock/gmock.h"
27 #include "gtest/gtest.h"
28 #include "absl/base/config.h"
29 #include "absl/base/internal/raw_logging.h"
30 #include "absl/types/span.h"
34 namespace container_internal {
40 size_t Distance(
const void*
from,
const void*
to) {
42 return static_cast<const char*
>(
to) -
static_cast<const char*
>(
from);
45 template <
class Expected,
class Actual>
46 Expected
Type(Actual val) {
47 static_assert(std::is_same<Expected, Actual>(),
"");
52 struct alignas(8) Int128 {
54 friend bool operator==(Int128 lhs, Int128 rhs) {
55 return std::tie(lhs.a, lhs.b) == std::tie(rhs.a, rhs.b);
59 return internal_layout::adl_barrier::TypeName<Int128>();
64 struct alignas(8)
Int64 {
67 return lhs.a == rhs.a;
72 static_assert(
sizeof(
int8_t) == 1,
"");
73 static_assert(
alignof(
int8_t) == 1,
"");
74 static_assert(
sizeof(
int16_t) == 2,
"");
75 static_assert(
alignof(
int16_t) == 2,
"");
76 static_assert(
sizeof(
int32_t) == 4,
"");
77 static_assert(
alignof(
int32_t) == 4,
"");
78 static_assert(
sizeof(
Int64) == 8,
"");
79 static_assert(
alignof(
Int64) == 8,
"");
80 static_assert(
sizeof(Int128) == 16,
"");
81 static_assert(
alignof(Int128) == 8,
"");
83 template <
class Expected,
class Actual>
85 static_assert(std::is_same<Expected, Actual>(),
"");
88 TEST(Layout, ElementType) {
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>>();
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>>();
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>>();
121 TEST(Layout, ElementTypes) {
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>();
129 using L = Layout<int32_t, int32_t>;
130 SameType<std::tuple<int32_t, int32_t>, L::ElementTypes>();
131 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>();
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>();
150 TEST(Layout, OffsetByIndex) {
152 using L = Layout<int32_t>;
158 using L = Layout<int32_t, int32_t>;
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>());
168 using L = Layout<int8_t, int32_t, Int128>;
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>());
200 TEST(Layout, OffsetByType) {
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>());
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>());
240 TEST(Layout, Offsets) {
242 using L = Layout<int32_t>;
248 using L = Layout<int32_t, int32_t>;
255 using L = Layout<int8_t, int32_t, Int128>;
271 using L = Layout<int32_t>;
277 using L = Layout<int32_t, int32_t>;
282 using L = Layout<int8_t, int32_t, Int128>;
293 TEST(Layout, SizeByIndex) {
295 using L = Layout<int32_t>;
301 using L = Layout<int32_t, int32_t>;
304 EXPECT_EQ(3, L::Partial(3, 5).Size<0>());
305 EXPECT_EQ(5, L::Partial(3, 5).Size<1>());
310 using L = Layout<int8_t, int32_t, Int128>;
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>());
323 TEST(Layout, SizeByType) {
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>());
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>());
344 TEST(Layout, Sizes) {
346 using L = Layout<int32_t>;
352 using L = Layout<int32_t, int32_t>;
359 using L = Layout<int8_t, int32_t, Int128>;
368 TEST(Layout, PointerByIndex) {
369 alignas(max_align_t)
const unsigned char p[100] = {};
371 using L = Layout<int32_t>;
378 using L = Layout<int32_t, int32_t>;
392 using L = Layout<int8_t, int32_t, Int128>;
449 TEST(Layout, PointerByType) {
450 alignas(max_align_t)
const unsigned char p[100] = {};
452 using L = Layout<int32_t>;
461 using L = Layout<int8_t, int32_t, Int128>;
483 L::Partial(0, 0).Pointer<int32_t>(p))));
491 L::Partial(1, 0).Pointer<int32_t>(p))));
499 L::Partial(5, 3).Pointer<int32_t>(p))));
504 L::Partial(0, 0, 0).Pointer<int8_t>(p))));
506 L::Partial(0, 0, 0).Pointer<int32_t>(p))));
508 L::Partial(0, 0, 0).Pointer<Int128>(p))));
510 L::Partial(1, 0, 0).Pointer<int8_t>(p))));
512 L::Partial(1, 0, 0).Pointer<int32_t>(p))));
514 L::Partial(1, 0, 0).Pointer<Int128>(p))));
516 L::Partial(5, 3, 1).Pointer<int8_t>(p))));
518 L::Partial(5, 3, 1).Pointer<Int128>(p))));
520 L::Partial(5, 3, 1).Pointer<int32_t>(p))));
528 TEST(Layout, MutablePointerByIndex) {
529 alignas(max_align_t)
unsigned char p[100];
531 using L = Layout<int32_t>;
537 using L = Layout<int32_t, int32_t>;
547 using L = Layout<int8_t, int32_t, Int128>;
574 Distance(p,
Type<Int128*>(L::Partial(5, 3, 1).Pointer<2>(p))));
583 TEST(Layout, MutablePointerByType) {
584 alignas(max_align_t)
unsigned char p[100];
586 using L = Layout<int32_t>;
593 using L = Layout<int8_t, int32_t, Int128>;
605 Distance(p,
Type<int8_t*>(L::Partial(0, 0).Pointer<int8_t>(p))));
607 0, Distance(p,
Type<int32_t*>(L::Partial(0, 0).Pointer<int32_t>(p))));
609 Distance(p,
Type<Int128*>(L::Partial(0, 0).Pointer<Int128>(p))));
611 Distance(p,
Type<int8_t*>(L::Partial(1, 0).Pointer<int8_t>(p))));
613 4, Distance(p,
Type<int32_t*>(L::Partial(1, 0).Pointer<int32_t>(p))));
615 Distance(p,
Type<Int128*>(L::Partial(1, 0).Pointer<Int128>(p))));
617 Distance(p,
Type<int8_t*>(L::Partial(5, 3).Pointer<int8_t>(p))));
619 8, Distance(p,
Type<int32_t*>(L::Partial(5, 3).Pointer<int32_t>(p))));
621 Distance(p,
Type<Int128*>(L::Partial(5, 3).Pointer<Int128>(p))));
623 0, Distance(p,
Type<int8_t*>(L::Partial(0, 0, 0).Pointer<int8_t>(p))));
626 Distance(p,
Type<int32_t*>(L::Partial(0, 0, 0).Pointer<int32_t>(p))));
628 0, Distance(p,
Type<Int128*>(L::Partial(0, 0, 0).Pointer<Int128>(p))));
630 0, Distance(p,
Type<int8_t*>(L::Partial(1, 0, 0).Pointer<int8_t>(p))));
633 Distance(p,
Type<int32_t*>(L::Partial(1, 0, 0).Pointer<int32_t>(p))));
635 8, Distance(p,
Type<Int128*>(L::Partial(1, 0, 0).Pointer<Int128>(p))));
637 0, Distance(p,
Type<int8_t*>(L::Partial(5, 3, 1).Pointer<int8_t>(p))));
639 24, Distance(p,
Type<Int128*>(L::Partial(5, 3, 1).Pointer<Int128>(p))));
642 Distance(p,
Type<int32_t*>(L::Partial(5, 3, 1).Pointer<int32_t>(p))));
649 TEST(Layout, Pointers) {
650 alignas(max_align_t)
const unsigned char p[100] = {};
651 using L = Layout<int8_t, int8_t, Int128>;
653 const auto x = L::Partial();
655 Type<std::tuple<const int8_t*>>(
x.Pointers(p)));
658 const auto x = L::Partial(1);
660 (
Type<std::tuple<const int8_t*, const int8_t*>>(
x.Pointers(p))));
663 const auto x = L::Partial(1, 2);
666 (
Type<std::tuple<const int8_t*, const int8_t*, const Int128*>>(
670 const auto x = L::Partial(1, 2, 3);
673 (
Type<std::tuple<const int8_t*, const int8_t*, const Int128*>>(
680 (
Type<std::tuple<const int8_t*, const int8_t*, const Int128*>>(
685 TEST(Layout, MutablePointers) {
686 alignas(max_align_t)
unsigned char p[100];
687 using L = Layout<int8_t, int8_t, Int128>;
689 const auto x = L::Partial();
691 Type<std::tuple<int8_t*>>(
x.Pointers(p)));
694 const auto x = L::Partial(1);
696 (
Type<std::tuple<int8_t*, int8_t*>>(
x.Pointers(p))));
699 const auto x = L::Partial(1, 2);
702 (
Type<std::tuple<int8_t*, int8_t*, Int128*>>(
x.Pointers(p))));
705 const auto x = L::Partial(1, 2, 3);
708 (
Type<std::tuple<int8_t*, int8_t*, Int128*>>(
x.Pointers(p))));
714 (
Type<std::tuple<int8_t*, int8_t*, Int128*>>(
x.Pointers(p))));
718 TEST(Layout, SliceByIndexSize) {
719 alignas(max_align_t)
const unsigned char p[100] = {};
721 using L = Layout<int32_t>;
727 using L = Layout<int32_t, int32_t>;
733 using L = Layout<int8_t, int32_t, Int128>;
746 TEST(Layout, SliceByTypeSize) {
747 alignas(max_align_t)
const unsigned char p[100] = {};
749 using L = Layout<int32_t>;
755 using L = Layout<int8_t, int32_t, Int128>;
768 TEST(Layout, MutableSliceByIndexSize) {
769 alignas(max_align_t)
unsigned char p[100];
771 using L = Layout<int32_t>;
777 using L = Layout<int32_t, int32_t>;
783 using L = Layout<int8_t, int32_t, Int128>;
796 TEST(Layout, MutableSliceByTypeSize) {
797 alignas(max_align_t)
unsigned char p[100];
799 using L = Layout<int32_t>;
805 using L = Layout<int8_t, int32_t, Int128>;
818 TEST(Layout, SliceByIndexData) {
819 alignas(max_align_t)
const unsigned char p[100] = {};
821 using L = Layout<int32_t>;
832 using L = Layout<int32_t, int32_t>;
850 using L = Layout<int8_t, int32_t, Int128>;
941 TEST(Layout, SliceByTypeData) {
942 alignas(max_align_t)
const unsigned char p[100] = {};
944 using L = Layout<int32_t>;
960 using L = Layout<int8_t, int32_t, Int128>;
981 L::Partial(0, 0).Slice<int32_t>(p))
988 L::Partial(1, 0).Slice<int32_t>(p))
995 L::Partial(5, 3).Slice<int32_t>(p))
998 L::Partial(0, 0, 0).Slice<int8_t>(p))
1001 L::Partial(0, 0, 0).Slice<int32_t>(p))
1004 L::Partial(0, 0, 0).Slice<Int128>(p))
1007 L::Partial(1, 0, 0).Slice<int8_t>(p))
1010 L::Partial(1, 0, 0).Slice<int32_t>(p))
1013 L::Partial(1, 0, 0).Slice<Int128>(p))
1016 L::Partial(5, 3, 1).Slice<int8_t>(p))
1019 L::Partial(5, 3, 1).Slice<Int128>(p))
1022 L::Partial(5, 3, 1).Slice<int32_t>(p))
1039 TEST(Layout, MutableSliceByIndexData) {
1040 alignas(max_align_t)
unsigned char p[100];
1042 using L = Layout<int32_t>;
1050 using L = Layout<int32_t, int32_t>;
1063 using L = Layout<int8_t, int32_t, Int128>;
1124 TEST(Layout, MutableSliceByTypeData) {
1125 alignas(max_align_t)
unsigned char p[100];
1127 using L = Layout<int32_t>;
1138 using L = Layout<int8_t, int32_t, Int128>;
1232 template <
typename... M>
1233 class TupleMatcher {
1237 template <
typename Tuple>
1238 bool MatchAndExplain(
const Tuple& p,
1241 return MatchAndExplainImpl(
1247 void DescribeTo(::std::ostream* os)
const {}
1248 void DescribeNegationTo(::std::ostream* os)
const {}
1251 template <
typename Tuple,
size_t... Is>
1258 .
Matches(std::get<Is>(p))...});
1264 template <
typename... M>
1270 TEST(Layout, Slices) {
1271 alignas(max_align_t)
const unsigned char p[100] = {};
1272 using L = Layout<int8_t, int8_t, Int128>;
1274 const auto x = L::Partial();
1278 const auto x = L::Partial(1);
1280 Tuple(IsSameSlice(
x.Slice<0>(p))));
1283 const auto x = L::Partial(1, 2);
1286 Tuple(IsSameSlice(
x.Slice<0>(p)), IsSameSlice(
x.Slice<1>(p))));
1289 const auto x = L::Partial(1, 2, 3);
1292 Tuple(IsSameSlice(
x.Slice<0>(p)), IsSameSlice(
x.Slice<1>(p)),
1293 IsSameSlice(
x.Slice<2>(p))));
1299 Tuple(IsSameSlice(
x.Slice<0>(p)), IsSameSlice(
x.Slice<1>(p)),
1300 IsSameSlice(
x.Slice<2>(p))));
1304 TEST(Layout, MutableSlices) {
1305 alignas(max_align_t)
unsigned char p[100] = {};
1306 using L = Layout<int8_t, int8_t, Int128>;
1308 const auto x = L::Partial();
1312 const auto x = L::Partial(1);
1314 Tuple(IsSameSlice(
x.Slice<0>(p))));
1317 const auto x = L::Partial(1, 2);
1319 Tuple(IsSameSlice(
x.Slice<0>(p)), IsSameSlice(
x.Slice<1>(p))));
1322 const auto x = L::Partial(1, 2, 3);
1325 Tuple(IsSameSlice(
x.Slice<0>(p)), IsSameSlice(
x.Slice<1>(p)),
1326 IsSameSlice(
x.Slice<2>(p))));
1332 Tuple(IsSameSlice(
x.Slice<0>(p)), IsSameSlice(
x.Slice<1>(p)),
1333 IsSameSlice(
x.Slice<2>(p))));
1337 TEST(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));
1343 TEST(Layout, CustomAlignment) {
1344 constexpr Layout<unsigned char, Aligned<unsigned char, 8>>
x(1, 2);
1345 alignas(max_align_t)
unsigned char p[
x.AllocSize()];
1350 TEST(Layout, OverAligned) {
1351 constexpr
size_t M =
alignof(max_align_t);
1352 constexpr Layout<unsigned char, Aligned<unsigned char, 2 * M>>
x(1, 3);
1358 alignas(2 * M)
unsigned char p[
x.AllocSize()];
1364 TEST(Layout, Alignment) {
1365 static_assert(Layout<int8_t>::Alignment() == 1,
"");
1366 static_assert(Layout<int32_t>::Alignment() == 4,
"");
1367 static_assert(Layout<Int64>::Alignment() == 8,
"");
1368 static_assert(Layout<Aligned<int8_t, 64>>::Alignment() == 64,
"");
1369 static_assert(Layout<int8_t, int32_t, Int64>::Alignment() == 8,
"");
1370 static_assert(Layout<int8_t, Int64, int32_t>::Alignment() == 8,
"");
1371 static_assert(Layout<int32_t, int8_t, Int64>::Alignment() == 8,
"");
1372 static_assert(Layout<int32_t, Int64, int8_t>::Alignment() == 8,
"");
1373 static_assert(Layout<Int64, int8_t, int32_t>::Alignment() == 8,
"");
1374 static_assert(Layout<Int64, int32_t, int8_t>::Alignment() == 8,
"");
1377 TEST(Layout, ConstexprPartial) {
1378 constexpr
size_t M =
alignof(max_align_t);
1379 constexpr Layout<unsigned char, Aligned<unsigned char, 2 * M>>
x(1, 3);
1380 static_assert(
x.Partial(1).template Offset<1>() == 2 * M,
"");
1388 void ExpectRegionPoisoned(
const unsigned char* p,
size_t n,
bool poisoned) {
1389 #ifdef ABSL_HAVE_ADDRESS_SANITIZER
1390 for (
size_t i = 0;
i !=
n; ++
i) {
1391 EXPECT_EQ(poisoned, __asan_address_is_poisoned(
p +
i));
1397 void ExpectPoisoned(
const unsigned char (&
buf)[
N],
1398 std::initializer_list<Region> reg) {
1400 for (
const Region&
r : reg) {
1401 ExpectRegionPoisoned(
buf + prev,
r.from - prev,
false);
1402 ExpectRegionPoisoned(
buf +
r.from,
r.to -
r.from,
true);
1405 ExpectRegionPoisoned(
buf + prev,
N - prev,
false);
1408 TEST(Layout, PoisonPadding) {
1409 using L = Layout<int8_t, Int64, int32_t, Int128>;
1411 constexpr
size_t n = L::Partial(1, 2, 3, 4).AllocSize();
1413 constexpr
auto x = L::Partial();
1414 alignas(max_align_t)
const unsigned char c[n] = {};
1417 ExpectPoisoned(c, {});
1420 constexpr
auto x = L::Partial(1);
1421 alignas(max_align_t)
const unsigned char c[n] = {};
1424 ExpectPoisoned(c, {{1, 8}});
1427 constexpr
auto x = L::Partial(1, 2);
1428 alignas(max_align_t)
const unsigned char c[n] = {};
1431 ExpectPoisoned(c, {{1, 8}});
1434 constexpr
auto x = L::Partial(1, 2, 3);
1435 alignas(max_align_t)
const unsigned char c[n] = {};
1438 ExpectPoisoned(c, {{1, 8}, {36, 40}});
1441 constexpr
auto x = L::Partial(1, 2, 3, 4);
1442 alignas(max_align_t)
const unsigned char c[n] = {};
1445 ExpectPoisoned(c, {{1, 8}, {36, 40}});
1448 constexpr
L x(1, 2, 3, 4);
1449 alignas(max_align_t)
const unsigned char c[n] = {};
1452 ExpectPoisoned(c, {{1, 8}, {36, 40}});
1459 EXPECT_EQ(
"@0<signed char>(1)",
x.DebugString());
1463 EXPECT_EQ(
"@0<signed char>(1)[1]; @4<int>(4)",
x.DebugString());
1467 EXPECT_EQ(
"@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)",
1474 "@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)[3]; "
1476 Int128::Name() +
"(16)",
1483 "@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)[3]; "
1485 Int128::Name() +
"(16)[4]",
1489 constexpr Layout<int8_t, int32_t, int8_t, Int128>
x(1, 2, 3, 4);
1491 "@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)[3]; "
1493 Int128::Name() +
"(16)[4]",
1498 TEST(Layout, CharTypes) {
1499 constexpr Layout<int32_t>
x(1);
1500 alignas(max_align_t)
char c[
x.AllocSize()] = {};
1501 alignas(max_align_t)
unsigned char uc[
x.AllocSize()] = {};
1502 alignas(max_align_t)
signed char sc[
x.AllocSize()] = {};
1503 alignas(max_align_t)
const char cc[
x.AllocSize()] = {};
1504 alignas(max_align_t)
const unsigned char cuc[
x.AllocSize()] = {};
1505 alignas(max_align_t)
const signed char csc[
x.AllocSize()] = {};
1543 TEST(Layout, ConstElementType) {
1544 constexpr Layout<const int32_t>
x(1);
1545 alignas(
int32_t)
char c[
x.AllocSize()] = {};
1592 class CompactString {
1594 CompactString(
const char*
s =
"") {
1595 const size_t size = strlen(
s);
1601 p_.reset(
new unsigned char[
layout.AllocSize()]);
1612 size_t size()
const {
1617 const char*
c_str()
const {
1627 std::unique_ptr<unsigned char[]>
p_;
1630 TEST(CompactString, Works) {
1631 CompactString
s =
"hello";