tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

layout_test.cc (75816B)


      1 // 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>
     20 
     21 #include <cstdint>
     22 #include <cstring>
     23 #include <initializer_list>
     24 #include <memory>
     25 #include <ostream>
     26 #include <string>
     27 #include <tuple>
     28 #include <type_traits>
     29 
     30 #include "gmock/gmock.h"
     31 #include "gtest/gtest.h"
     32 #include "absl/base/config.h"
     33 #include "absl/log/check.h"
     34 #include "absl/types/span.h"
     35 #include "absl/utility/utility.h"
     36 
     37 namespace absl {
     38 ABSL_NAMESPACE_BEGIN
     39 namespace container_internal {
     40 namespace {
     41 
     42 using ::absl::Span;
     43 using ::testing::ElementsAre;
     44 
     45 size_t Distance(const void* from, const void* to) {
     46  CHECK_LE(from, to) << "Distance must be non-negative";
     47  return static_cast<const char*>(to) - static_cast<const char*>(from);
     48 }
     49 
     50 template <class Expected, class Actual>
     51 Expected Type(Actual val) {
     52  static_assert(std::is_same<Expected, Actual>(), "");
     53  return val;
     54 }
     55 
     56 // Helper classes to test different size and alignments.
     57 struct alignas(8) Int128 {
     58  uint64_t a, b;
     59  friend bool operator==(Int128 lhs, Int128 rhs) {
     60    return std::tie(lhs.a, lhs.b) == std::tie(rhs.a, rhs.b);
     61  }
     62 
     63  static std::string Name() {
     64    return internal_layout::adl_barrier::TypeName<Int128>();
     65  }
     66 };
     67 
     68 // int64_t is *not* 8-byte aligned on all platforms!
     69 struct alignas(8) Int64 {
     70  int64_t a;
     71  friend bool operator==(Int64 lhs, Int64 rhs) { return lhs.a == rhs.a; }
     72 };
     73 
     74 // Properties of types that this test relies on.
     75 static_assert(sizeof(int8_t) == 1, "");
     76 static_assert(alignof(int8_t) == 1, "");
     77 static_assert(sizeof(int16_t) == 2, "");
     78 static_assert(alignof(int16_t) == 2, "");
     79 static_assert(sizeof(int32_t) == 4, "");
     80 static_assert(alignof(int32_t) == 4, "");
     81 static_assert(sizeof(Int64) == 8, "");
     82 static_assert(alignof(Int64) == 8, "");
     83 static_assert(sizeof(Int128) == 16, "");
     84 static_assert(alignof(Int128) == 8, "");
     85 
     86 template <class Expected, class Actual>
     87 void SameType() {
     88  static_assert(std::is_same<Expected, Actual>(), "");
     89 }
     90 
     91 TEST(Layout, ElementType) {
     92  {
     93    using L = Layout<int32_t>;
     94    SameType<int32_t, L::ElementType<0>>();
     95    SameType<int32_t, decltype(L::Partial())::ElementType<0>>();
     96    SameType<int32_t, decltype(L::Partial(0))::ElementType<0>>();
     97  }
     98  {
     99    using L = Layout<int32_t, int32_t>;
    100    SameType<int32_t, L::ElementType<0>>();
    101    SameType<int32_t, L::ElementType<1>>();
    102    SameType<int32_t, decltype(L::Partial())::ElementType<0>>();
    103    SameType<int32_t, decltype(L::Partial())::ElementType<1>>();
    104    SameType<int32_t, decltype(L::Partial(0))::ElementType<0>>();
    105    SameType<int32_t, decltype(L::Partial(0))::ElementType<1>>();
    106  }
    107  {
    108    using L = Layout<int8_t, int32_t, Int128>;
    109    SameType<int8_t, L::ElementType<0>>();
    110    SameType<int32_t, L::ElementType<1>>();
    111    SameType<Int128, L::ElementType<2>>();
    112    SameType<int8_t, decltype(L::Partial())::ElementType<0>>();
    113    SameType<int8_t, decltype(L::Partial(0))::ElementType<0>>();
    114    SameType<int32_t, decltype(L::Partial(0))::ElementType<1>>();
    115    SameType<int8_t, decltype(L::Partial(0, 0))::ElementType<0>>();
    116    SameType<int32_t, decltype(L::Partial(0, 0))::ElementType<1>>();
    117    SameType<Int128, decltype(L::Partial(0, 0))::ElementType<2>>();
    118    SameType<int8_t, decltype(L::Partial(0, 0, 0))::ElementType<0>>();
    119    SameType<int32_t, decltype(L::Partial(0, 0, 0))::ElementType<1>>();
    120    SameType<Int128, decltype(L::Partial(0, 0, 0))::ElementType<2>>();
    121  }
    122 }
    123 
    124 TEST(Layout, ElementTypes) {
    125  {
    126    using L = Layout<int32_t>;
    127    SameType<std::tuple<int32_t>, L::ElementTypes>();
    128    SameType<std::tuple<int32_t>, decltype(L::Partial())::ElementTypes>();
    129    SameType<std::tuple<int32_t>, decltype(L::Partial(0))::ElementTypes>();
    130  }
    131  {
    132    using L = Layout<int32_t, int32_t>;
    133    SameType<std::tuple<int32_t, int32_t>, L::ElementTypes>();
    134    SameType<std::tuple<int32_t, int32_t>,
    135             decltype(L::Partial())::ElementTypes>();
    136    SameType<std::tuple<int32_t, int32_t>,
    137             decltype(L::Partial(0))::ElementTypes>();
    138  }
    139  {
    140    using L = Layout<int8_t, int32_t, Int128>;
    141    SameType<std::tuple<int8_t, int32_t, Int128>, L::ElementTypes>();
    142    SameType<std::tuple<int8_t, int32_t, Int128>,
    143             decltype(L::Partial())::ElementTypes>();
    144    SameType<std::tuple<int8_t, int32_t, Int128>,
    145             decltype(L::Partial(0))::ElementTypes>();
    146    SameType<std::tuple<int8_t, int32_t, Int128>,
    147             decltype(L::Partial(0, 0))::ElementTypes>();
    148    SameType<std::tuple<int8_t, int32_t, Int128>,
    149             decltype(L::Partial(0, 0, 0))::ElementTypes>();
    150  }
    151 }
    152 
    153 TEST(Layout, OffsetByIndex) {
    154  {
    155    using L = Layout<int32_t>;
    156    EXPECT_EQ(0, L::Partial().Offset<0>());
    157    EXPECT_EQ(0, L::Partial(3).Offset<0>());
    158    EXPECT_EQ(0, L(3).Offset<0>());
    159  }
    160  {
    161    using L = Layout<int32_t, int32_t>;
    162    EXPECT_EQ(0, L::Partial().Offset<0>());
    163    EXPECT_EQ(0, L::Partial(3).Offset<0>());
    164    EXPECT_EQ(12, L::Partial(3).Offset<1>());
    165    EXPECT_EQ(0, L::Partial(3, 5).Offset<0>());
    166    EXPECT_EQ(12, L::Partial(3, 5).Offset<1>());
    167    EXPECT_EQ(0, L(3, 5).Offset<0>());
    168    EXPECT_EQ(12, L(3, 5).Offset<1>());
    169  }
    170  {
    171    using L = Layout<int8_t, int32_t, Int128>;
    172    EXPECT_EQ(0, L::Partial().Offset<0>());
    173    EXPECT_EQ(0, L::Partial(0).Offset<0>());
    174    EXPECT_EQ(0, L::Partial(0).Offset<1>());
    175    EXPECT_EQ(0, L::Partial(1).Offset<0>());
    176    EXPECT_EQ(4, L::Partial(1).Offset<1>());
    177    EXPECT_EQ(0, L::Partial(5).Offset<0>());
    178    EXPECT_EQ(8, L::Partial(5).Offset<1>());
    179    EXPECT_EQ(0, L::Partial(0, 0).Offset<0>());
    180    EXPECT_EQ(0, L::Partial(0, 0).Offset<1>());
    181    EXPECT_EQ(0, L::Partial(0, 0).Offset<2>());
    182    EXPECT_EQ(0, L::Partial(1, 0).Offset<0>());
    183    EXPECT_EQ(4, L::Partial(1, 0).Offset<1>());
    184    EXPECT_EQ(8, L::Partial(1, 0).Offset<2>());
    185    EXPECT_EQ(0, L::Partial(5, 3).Offset<0>());
    186    EXPECT_EQ(8, L::Partial(5, 3).Offset<1>());
    187    EXPECT_EQ(24, L::Partial(5, 3).Offset<2>());
    188    EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<0>());
    189    EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<1>());
    190    EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<2>());
    191    EXPECT_EQ(0, L::Partial(1, 0, 0).Offset<0>());
    192    EXPECT_EQ(4, L::Partial(1, 0, 0).Offset<1>());
    193    EXPECT_EQ(8, L::Partial(1, 0, 0).Offset<2>());
    194    EXPECT_EQ(0, L::Partial(5, 3, 1).Offset<0>());
    195    EXPECT_EQ(24, L::Partial(5, 3, 1).Offset<2>());
    196    EXPECT_EQ(8, L::Partial(5, 3, 1).Offset<1>());
    197    EXPECT_EQ(0, L(5, 3, 1).Offset<0>());
    198    EXPECT_EQ(24, L(5, 3, 1).Offset<2>());
    199    EXPECT_EQ(8, L(5, 3, 1).Offset<1>());
    200  }
    201 }
    202 
    203 TEST(Layout, OffsetByType) {
    204  {
    205    using L = Layout<int32_t>;
    206    EXPECT_EQ(0, L::Partial().Offset<int32_t>());
    207    EXPECT_EQ(0, L::Partial(3).Offset<int32_t>());
    208    EXPECT_EQ(0, L(3).Offset<int32_t>());
    209  }
    210  {
    211    using L = Layout<int8_t, int32_t, Int128>;
    212    EXPECT_EQ(0, L::Partial().Offset<int8_t>());
    213    EXPECT_EQ(0, L::Partial(0).Offset<int8_t>());
    214    EXPECT_EQ(0, L::Partial(0).Offset<int32_t>());
    215    EXPECT_EQ(0, L::Partial(1).Offset<int8_t>());
    216    EXPECT_EQ(4, L::Partial(1).Offset<int32_t>());
    217    EXPECT_EQ(0, L::Partial(5).Offset<int8_t>());
    218    EXPECT_EQ(8, L::Partial(5).Offset<int32_t>());
    219    EXPECT_EQ(0, L::Partial(0, 0).Offset<int8_t>());
    220    EXPECT_EQ(0, L::Partial(0, 0).Offset<int32_t>());
    221    EXPECT_EQ(0, L::Partial(0, 0).Offset<Int128>());
    222    EXPECT_EQ(0, L::Partial(1, 0).Offset<int8_t>());
    223    EXPECT_EQ(4, L::Partial(1, 0).Offset<int32_t>());
    224    EXPECT_EQ(8, L::Partial(1, 0).Offset<Int128>());
    225    EXPECT_EQ(0, L::Partial(5, 3).Offset<int8_t>());
    226    EXPECT_EQ(8, L::Partial(5, 3).Offset<int32_t>());
    227    EXPECT_EQ(24, L::Partial(5, 3).Offset<Int128>());
    228    EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<int8_t>());
    229    EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<int32_t>());
    230    EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<Int128>());
    231    EXPECT_EQ(0, L::Partial(1, 0, 0).Offset<int8_t>());
    232    EXPECT_EQ(4, L::Partial(1, 0, 0).Offset<int32_t>());
    233    EXPECT_EQ(8, L::Partial(1, 0, 0).Offset<Int128>());
    234    EXPECT_EQ(0, L::Partial(5, 3, 1).Offset<int8_t>());
    235    EXPECT_EQ(24, L::Partial(5, 3, 1).Offset<Int128>());
    236    EXPECT_EQ(8, L::Partial(5, 3, 1).Offset<int32_t>());
    237    EXPECT_EQ(0, L(5, 3, 1).Offset<int8_t>());
    238    EXPECT_EQ(24, L(5, 3, 1).Offset<Int128>());
    239    EXPECT_EQ(8, L(5, 3, 1).Offset<int32_t>());
    240  }
    241 }
    242 
    243 TEST(Layout, Offsets) {
    244  {
    245    using L = Layout<int32_t>;
    246    EXPECT_THAT(L::Partial().Offsets(), ElementsAre(0));
    247    EXPECT_THAT(L::Partial(3).Offsets(), ElementsAre(0));
    248    EXPECT_THAT(L(3).Offsets(), ElementsAre(0));
    249  }
    250  {
    251    using L = Layout<int32_t, int32_t>;
    252    EXPECT_THAT(L::Partial().Offsets(), ElementsAre(0));
    253    EXPECT_THAT(L::Partial(3).Offsets(), ElementsAre(0, 12));
    254    EXPECT_THAT(L::Partial(3, 5).Offsets(), ElementsAre(0, 12));
    255    EXPECT_THAT(L(3, 5).Offsets(), ElementsAre(0, 12));
    256  }
    257  {
    258    using L = Layout<int8_t, int32_t, Int128>;
    259    EXPECT_THAT(L::Partial().Offsets(), ElementsAre(0));
    260    EXPECT_THAT(L::Partial(1).Offsets(), ElementsAre(0, 4));
    261    EXPECT_THAT(L::Partial(5).Offsets(), ElementsAre(0, 8));
    262    EXPECT_THAT(L::Partial(0, 0).Offsets(), ElementsAre(0, 0, 0));
    263    EXPECT_THAT(L::Partial(1, 0).Offsets(), ElementsAre(0, 4, 8));
    264    EXPECT_THAT(L::Partial(5, 3).Offsets(), ElementsAre(0, 8, 24));
    265    EXPECT_THAT(L::Partial(0, 0, 0).Offsets(), ElementsAre(0, 0, 0));
    266    EXPECT_THAT(L::Partial(1, 0, 0).Offsets(), ElementsAre(0, 4, 8));
    267    EXPECT_THAT(L::Partial(5, 3, 1).Offsets(), ElementsAre(0, 8, 24));
    268    EXPECT_THAT(L(5, 3, 1).Offsets(), ElementsAre(0, 8, 24));
    269  }
    270 }
    271 
    272 TEST(Layout, StaticOffsets) {
    273  using L = Layout<int8_t, int32_t, Int128>;
    274  {
    275    using SL = L::WithStaticSizes<>;
    276    EXPECT_THAT(SL::Partial().Offsets(), ElementsAre(0));
    277    EXPECT_THAT(SL::Partial(5).Offsets(), ElementsAre(0, 8));
    278    EXPECT_THAT(SL::Partial(5, 3, 1).Offsets(), ElementsAre(0, 8, 24));
    279    EXPECT_THAT(SL(5, 3, 1).Offsets(), ElementsAre(0, 8, 24));
    280  }
    281  {
    282    using SL = L::WithStaticSizes<5>;
    283    EXPECT_THAT(SL::Partial().Offsets(), ElementsAre(0, 8));
    284    EXPECT_THAT(SL::Partial(3).Offsets(), ElementsAre(0, 8, 24));
    285    EXPECT_THAT(SL::Partial(3, 1).Offsets(), ElementsAre(0, 8, 24));
    286    EXPECT_THAT(SL(3, 1).Offsets(), ElementsAre(0, 8, 24));
    287  }
    288  {
    289    using SL = L::WithStaticSizes<5, 3>;
    290    EXPECT_THAT(SL::Partial().Offsets(), ElementsAre(0, 8, 24));
    291    EXPECT_THAT(SL::Partial(1).Offsets(), ElementsAre(0, 8, 24));
    292    EXPECT_THAT(SL(1).Offsets(), ElementsAre(0, 8, 24));
    293  }
    294  {
    295    using SL = L::WithStaticSizes<5, 3, 1>;
    296    EXPECT_THAT(SL::Partial().Offsets(), ElementsAre(0, 8, 24));
    297    EXPECT_THAT(SL().Offsets(), ElementsAre(0, 8, 24));
    298  }
    299 }
    300 
    301 TEST(Layout, AllocSize) {
    302  {
    303    using L = Layout<int32_t>;
    304    EXPECT_EQ(0, L::Partial(0).AllocSize());
    305    EXPECT_EQ(12, L::Partial(3).AllocSize());
    306    EXPECT_EQ(12, L(3).AllocSize());
    307  }
    308  {
    309    using L = Layout<int32_t, int32_t>;
    310    EXPECT_EQ(32, L::Partial(3, 5).AllocSize());
    311    EXPECT_EQ(32, L(3, 5).AllocSize());
    312  }
    313  {
    314    using L = Layout<int8_t, int32_t, Int128>;
    315    EXPECT_EQ(0, L::Partial(0, 0, 0).AllocSize());
    316    EXPECT_EQ(8, L::Partial(1, 0, 0).AllocSize());
    317    EXPECT_EQ(8, L::Partial(0, 1, 0).AllocSize());
    318    EXPECT_EQ(16, L::Partial(0, 0, 1).AllocSize());
    319    EXPECT_EQ(24, L::Partial(1, 1, 1).AllocSize());
    320    EXPECT_EQ(136, L::Partial(3, 5, 7).AllocSize());
    321    EXPECT_EQ(136, L(3, 5, 7).AllocSize());
    322  }
    323 }
    324 
    325 TEST(Layout, StaticAllocSize) {
    326  using L = Layout<int8_t, int32_t, Int128>;
    327  {
    328    using SL = L::WithStaticSizes<>;
    329    EXPECT_EQ(136, SL::Partial(3, 5, 7).AllocSize());
    330    EXPECT_EQ(136, SL(3, 5, 7).AllocSize());
    331  }
    332  {
    333    using SL = L::WithStaticSizes<3>;
    334    EXPECT_EQ(136, SL::Partial(5, 7).AllocSize());
    335    EXPECT_EQ(136, SL(5, 7).AllocSize());
    336  }
    337  {
    338    using SL = L::WithStaticSizes<3, 5>;
    339    EXPECT_EQ(136, SL::Partial(7).AllocSize());
    340    EXPECT_EQ(136, SL(7).AllocSize());
    341  }
    342  {
    343    using SL = L::WithStaticSizes<3, 5, 7>;
    344    EXPECT_EQ(136, SL::Partial().AllocSize());
    345    EXPECT_EQ(136, SL().AllocSize());
    346  }
    347 }
    348 
    349 TEST(Layout, SizeByIndex) {
    350  {
    351    using L = Layout<int32_t>;
    352    EXPECT_EQ(0, L::Partial(0).Size<0>());
    353    EXPECT_EQ(3, L::Partial(3).Size<0>());
    354    EXPECT_EQ(3, L(3).Size<0>());
    355  }
    356  {
    357    using L = Layout<int32_t, int32_t>;
    358    EXPECT_EQ(0, L::Partial(0).Size<0>());
    359    EXPECT_EQ(3, L::Partial(3).Size<0>());
    360    EXPECT_EQ(3, L::Partial(3, 5).Size<0>());
    361    EXPECT_EQ(5, L::Partial(3, 5).Size<1>());
    362    EXPECT_EQ(3, L(3, 5).Size<0>());
    363    EXPECT_EQ(5, L(3, 5).Size<1>());
    364  }
    365  {
    366    using L = Layout<int8_t, int32_t, Int128>;
    367    EXPECT_EQ(3, L::Partial(3).Size<0>());
    368    EXPECT_EQ(3, L::Partial(3, 5).Size<0>());
    369    EXPECT_EQ(5, L::Partial(3, 5).Size<1>());
    370    EXPECT_EQ(3, L::Partial(3, 5, 7).Size<0>());
    371    EXPECT_EQ(5, L::Partial(3, 5, 7).Size<1>());
    372    EXPECT_EQ(7, L::Partial(3, 5, 7).Size<2>());
    373    EXPECT_EQ(3, L(3, 5, 7).Size<0>());
    374    EXPECT_EQ(5, L(3, 5, 7).Size<1>());
    375    EXPECT_EQ(7, L(3, 5, 7).Size<2>());
    376  }
    377 }
    378 
    379 TEST(Layout, SizeByType) {
    380  {
    381    using L = Layout<int32_t>;
    382    EXPECT_EQ(0, L::Partial(0).Size<int32_t>());
    383    EXPECT_EQ(3, L::Partial(3).Size<int32_t>());
    384    EXPECT_EQ(3, L(3).Size<int32_t>());
    385  }
    386  {
    387    using L = Layout<int8_t, int32_t, Int128>;
    388    EXPECT_EQ(3, L::Partial(3).Size<int8_t>());
    389    EXPECT_EQ(3, L::Partial(3, 5).Size<int8_t>());
    390    EXPECT_EQ(5, L::Partial(3, 5).Size<int32_t>());
    391    EXPECT_EQ(3, L::Partial(3, 5, 7).Size<int8_t>());
    392    EXPECT_EQ(5, L::Partial(3, 5, 7).Size<int32_t>());
    393    EXPECT_EQ(7, L::Partial(3, 5, 7).Size<Int128>());
    394    EXPECT_EQ(3, L(3, 5, 7).Size<int8_t>());
    395    EXPECT_EQ(5, L(3, 5, 7).Size<int32_t>());
    396    EXPECT_EQ(7, L(3, 5, 7).Size<Int128>());
    397  }
    398 }
    399 
    400 TEST(Layout, Sizes) {
    401  {
    402    using L = Layout<int32_t>;
    403    EXPECT_THAT(L::Partial().Sizes(), ElementsAre());
    404    EXPECT_THAT(L::Partial(3).Sizes(), ElementsAre(3));
    405    EXPECT_THAT(L(3).Sizes(), ElementsAre(3));
    406  }
    407  {
    408    using L = Layout<int32_t, int32_t>;
    409    EXPECT_THAT(L::Partial().Sizes(), ElementsAre());
    410    EXPECT_THAT(L::Partial(3).Sizes(), ElementsAre(3));
    411    EXPECT_THAT(L::Partial(3, 5).Sizes(), ElementsAre(3, 5));
    412    EXPECT_THAT(L(3, 5).Sizes(), ElementsAre(3, 5));
    413  }
    414  {
    415    using L = Layout<int8_t, int32_t, Int128>;
    416    EXPECT_THAT(L::Partial().Sizes(), ElementsAre());
    417    EXPECT_THAT(L::Partial(3).Sizes(), ElementsAre(3));
    418    EXPECT_THAT(L::Partial(3, 5).Sizes(), ElementsAre(3, 5));
    419    EXPECT_THAT(L::Partial(3, 5, 7).Sizes(), ElementsAre(3, 5, 7));
    420    EXPECT_THAT(L(3, 5, 7).Sizes(), ElementsAre(3, 5, 7));
    421  }
    422 }
    423 
    424 TEST(Layout, StaticSize) {
    425  using L = Layout<int8_t, int32_t, Int128>;
    426  {
    427    using SL = L::WithStaticSizes<>;
    428    EXPECT_THAT(SL::Partial().Sizes(), ElementsAre());
    429    EXPECT_THAT(SL::Partial(3).Size<0>(), 3);
    430    EXPECT_THAT(SL::Partial(3).Size<int8_t>(), 3);
    431    EXPECT_THAT(SL::Partial(3).Sizes(), ElementsAre(3));
    432    EXPECT_THAT(SL::Partial(3, 5, 7).Size<0>(), 3);
    433    EXPECT_THAT(SL::Partial(3, 5, 7).Size<int8_t>(), 3);
    434    EXPECT_THAT(SL::Partial(3, 5, 7).Size<2>(), 7);
    435    EXPECT_THAT(SL::Partial(3, 5, 7).Size<Int128>(), 7);
    436    EXPECT_THAT(SL::Partial(3, 5, 7).Sizes(), ElementsAre(3, 5, 7));
    437    EXPECT_THAT(SL(3, 5, 7).Size<0>(), 3);
    438    EXPECT_THAT(SL(3, 5, 7).Size<int8_t>(), 3);
    439    EXPECT_THAT(SL(3, 5, 7).Size<2>(), 7);
    440    EXPECT_THAT(SL(3, 5, 7).Size<Int128>(), 7);
    441    EXPECT_THAT(SL(3, 5, 7).Sizes(), ElementsAre(3, 5, 7));
    442  }
    443 }
    444 
    445 TEST(Layout, PointerByIndex) {
    446  alignas(max_align_t) const unsigned char p[100] = {0};
    447  {
    448    using L = Layout<int32_t>;
    449    EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L::Partial().Pointer<0>(p))));
    450    EXPECT_EQ(0,
    451              Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<0>(p))));
    452    EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L(3).Pointer<0>(p))));
    453  }
    454  {
    455    using L = Layout<int32_t, int32_t>;
    456    EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L::Partial().Pointer<0>(p))));
    457    EXPECT_EQ(0,
    458              Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<0>(p))));
    459    EXPECT_EQ(12,
    460              Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<1>(p))));
    461    EXPECT_EQ(
    462        0, Distance(p, Type<const int32_t*>(L::Partial(3, 5).Pointer<0>(p))));
    463    EXPECT_EQ(
    464        12, Distance(p, Type<const int32_t*>(L::Partial(3, 5).Pointer<1>(p))));
    465    EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L(3, 5).Pointer<0>(p))));
    466    EXPECT_EQ(12, Distance(p, Type<const int32_t*>(L(3, 5).Pointer<1>(p))));
    467  }
    468  {
    469    using L = Layout<int8_t, int32_t, Int128>;
    470    EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial().Pointer<0>(p))));
    471    EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial(0).Pointer<0>(p))));
    472    EXPECT_EQ(0,
    473              Distance(p, Type<const int32_t*>(L::Partial(0).Pointer<1>(p))));
    474    EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial(1).Pointer<0>(p))));
    475    EXPECT_EQ(4,
    476              Distance(p, Type<const int32_t*>(L::Partial(1).Pointer<1>(p))));
    477    EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial(5).Pointer<0>(p))));
    478    EXPECT_EQ(8,
    479              Distance(p, Type<const int32_t*>(L::Partial(5).Pointer<1>(p))));
    480    EXPECT_EQ(0,
    481              Distance(p, Type<const int8_t*>(L::Partial(0, 0).Pointer<0>(p))));
    482    EXPECT_EQ(
    483        0, Distance(p, Type<const int32_t*>(L::Partial(0, 0).Pointer<1>(p))));
    484    EXPECT_EQ(0,
    485              Distance(p, Type<const Int128*>(L::Partial(0, 0).Pointer<2>(p))));
    486    EXPECT_EQ(0,
    487              Distance(p, Type<const int8_t*>(L::Partial(1, 0).Pointer<0>(p))));
    488    EXPECT_EQ(
    489        4, Distance(p, Type<const int32_t*>(L::Partial(1, 0).Pointer<1>(p))));
    490    EXPECT_EQ(8,
    491              Distance(p, Type<const Int128*>(L::Partial(1, 0).Pointer<2>(p))));
    492    EXPECT_EQ(0,
    493              Distance(p, Type<const int8_t*>(L::Partial(5, 3).Pointer<0>(p))));
    494    EXPECT_EQ(
    495        8, Distance(p, Type<const int32_t*>(L::Partial(5, 3).Pointer<1>(p))));
    496    EXPECT_EQ(24,
    497              Distance(p, Type<const Int128*>(L::Partial(5, 3).Pointer<2>(p))));
    498    EXPECT_EQ(
    499        0, Distance(p, Type<const int8_t*>(L::Partial(0, 0, 0).Pointer<0>(p))));
    500    EXPECT_EQ(
    501        0,
    502        Distance(p, Type<const int32_t*>(L::Partial(0, 0, 0).Pointer<1>(p))));
    503    EXPECT_EQ(
    504        0, Distance(p, Type<const Int128*>(L::Partial(0, 0, 0).Pointer<2>(p))));
    505    EXPECT_EQ(
    506        0, Distance(p, Type<const int8_t*>(L::Partial(1, 0, 0).Pointer<0>(p))));
    507    EXPECT_EQ(
    508        4,
    509        Distance(p, Type<const int32_t*>(L::Partial(1, 0, 0).Pointer<1>(p))));
    510    EXPECT_EQ(
    511        8, Distance(p, Type<const Int128*>(L::Partial(1, 0, 0).Pointer<2>(p))));
    512    EXPECT_EQ(
    513        0, Distance(p, Type<const int8_t*>(L::Partial(5, 3, 1).Pointer<0>(p))));
    514    EXPECT_EQ(
    515        24,
    516        Distance(p, Type<const Int128*>(L::Partial(5, 3, 1).Pointer<2>(p))));
    517    EXPECT_EQ(
    518        8,
    519        Distance(p, Type<const int32_t*>(L::Partial(5, 3, 1).Pointer<1>(p))));
    520    EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L(5, 3, 1).Pointer<0>(p))));
    521    EXPECT_EQ(24, Distance(p, Type<const Int128*>(L(5, 3, 1).Pointer<2>(p))));
    522    EXPECT_EQ(8, Distance(p, Type<const int32_t*>(L(5, 3, 1).Pointer<1>(p))));
    523  }
    524 }
    525 
    526 TEST(Layout, PointerByType) {
    527  alignas(max_align_t) const unsigned char p[100] = {0};
    528  {
    529    using L = Layout<int32_t>;
    530    EXPECT_EQ(
    531        0, Distance(p, Type<const int32_t*>(L::Partial().Pointer<int32_t>(p))));
    532    EXPECT_EQ(
    533        0,
    534        Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<int32_t>(p))));
    535    EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L(3).Pointer<int32_t>(p))));
    536  }
    537  {
    538    using L = Layout<int8_t, int32_t, Int128>;
    539    EXPECT_EQ(
    540        0, Distance(p, Type<const int8_t*>(L::Partial().Pointer<int8_t>(p))));
    541    EXPECT_EQ(
    542        0, Distance(p, Type<const int8_t*>(L::Partial(0).Pointer<int8_t>(p))));
    543    EXPECT_EQ(
    544        0,
    545        Distance(p, Type<const int32_t*>(L::Partial(0).Pointer<int32_t>(p))));
    546    EXPECT_EQ(
    547        0, Distance(p, Type<const int8_t*>(L::Partial(1).Pointer<int8_t>(p))));
    548    EXPECT_EQ(
    549        4,
    550        Distance(p, Type<const int32_t*>(L::Partial(1).Pointer<int32_t>(p))));
    551    EXPECT_EQ(
    552        0, Distance(p, Type<const int8_t*>(L::Partial(5).Pointer<int8_t>(p))));
    553    EXPECT_EQ(
    554        8,
    555        Distance(p, Type<const int32_t*>(L::Partial(5).Pointer<int32_t>(p))));
    556    EXPECT_EQ(
    557        0,
    558        Distance(p, Type<const int8_t*>(L::Partial(0, 0).Pointer<int8_t>(p))));
    559    EXPECT_EQ(0, Distance(p, Type<const int32_t*>(
    560                                 L::Partial(0, 0).Pointer<int32_t>(p))));
    561    EXPECT_EQ(
    562        0,
    563        Distance(p, Type<const Int128*>(L::Partial(0, 0).Pointer<Int128>(p))));
    564    EXPECT_EQ(
    565        0,
    566        Distance(p, Type<const int8_t*>(L::Partial(1, 0).Pointer<int8_t>(p))));
    567    EXPECT_EQ(4, Distance(p, Type<const int32_t*>(
    568                                 L::Partial(1, 0).Pointer<int32_t>(p))));
    569    EXPECT_EQ(
    570        8,
    571        Distance(p, Type<const Int128*>(L::Partial(1, 0).Pointer<Int128>(p))));
    572    EXPECT_EQ(
    573        0,
    574        Distance(p, Type<const int8_t*>(L::Partial(5, 3).Pointer<int8_t>(p))));
    575    EXPECT_EQ(8, Distance(p, Type<const int32_t*>(
    576                                 L::Partial(5, 3).Pointer<int32_t>(p))));
    577    EXPECT_EQ(
    578        24,
    579        Distance(p, Type<const Int128*>(L::Partial(5, 3).Pointer<Int128>(p))));
    580    EXPECT_EQ(0, Distance(p, Type<const int8_t*>(
    581                                 L::Partial(0, 0, 0).Pointer<int8_t>(p))));
    582    EXPECT_EQ(0, Distance(p, Type<const int32_t*>(
    583                                 L::Partial(0, 0, 0).Pointer<int32_t>(p))));
    584    EXPECT_EQ(0, Distance(p, Type<const Int128*>(
    585                                 L::Partial(0, 0, 0).Pointer<Int128>(p))));
    586    EXPECT_EQ(0, Distance(p, Type<const int8_t*>(
    587                                 L::Partial(1, 0, 0).Pointer<int8_t>(p))));
    588    EXPECT_EQ(4, Distance(p, Type<const int32_t*>(
    589                                 L::Partial(1, 0, 0).Pointer<int32_t>(p))));
    590    EXPECT_EQ(8, Distance(p, Type<const Int128*>(
    591                                 L::Partial(1, 0, 0).Pointer<Int128>(p))));
    592    EXPECT_EQ(0, Distance(p, Type<const int8_t*>(
    593                                 L::Partial(5, 3, 1).Pointer<int8_t>(p))));
    594    EXPECT_EQ(24, Distance(p, Type<const Int128*>(
    595                                  L::Partial(5, 3, 1).Pointer<Int128>(p))));
    596    EXPECT_EQ(8, Distance(p, Type<const int32_t*>(
    597                                 L::Partial(5, 3, 1).Pointer<int32_t>(p))));
    598    EXPECT_EQ(24,
    599              Distance(p, Type<const Int128*>(L(5, 3, 1).Pointer<Int128>(p))));
    600    EXPECT_EQ(
    601        8, Distance(p, Type<const int32_t*>(L(5, 3, 1).Pointer<int32_t>(p))));
    602  }
    603 }
    604 
    605 TEST(Layout, MutablePointerByIndex) {
    606  alignas(max_align_t) unsigned char p[100] = {0};
    607  {
    608    using L = Layout<int32_t>;
    609    EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial().Pointer<0>(p))));
    610    EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(3).Pointer<0>(p))));
    611    EXPECT_EQ(0, Distance(p, Type<int32_t*>(L(3).Pointer<0>(p))));
    612  }
    613  {
    614    using L = Layout<int32_t, int32_t>;
    615    EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial().Pointer<0>(p))));
    616    EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(3).Pointer<0>(p))));
    617    EXPECT_EQ(12, Distance(p, Type<int32_t*>(L::Partial(3).Pointer<1>(p))));
    618    EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(3, 5).Pointer<0>(p))));
    619    EXPECT_EQ(12, Distance(p, Type<int32_t*>(L::Partial(3, 5).Pointer<1>(p))));
    620    EXPECT_EQ(0, Distance(p, Type<int32_t*>(L(3, 5).Pointer<0>(p))));
    621    EXPECT_EQ(12, Distance(p, Type<int32_t*>(L(3, 5).Pointer<1>(p))));
    622  }
    623  {
    624    using L = Layout<int8_t, int32_t, Int128>;
    625    EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial().Pointer<0>(p))));
    626    EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0).Pointer<0>(p))));
    627    EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(0).Pointer<1>(p))));
    628    EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1).Pointer<0>(p))));
    629    EXPECT_EQ(4, Distance(p, Type<int32_t*>(L::Partial(1).Pointer<1>(p))));
    630    EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5).Pointer<0>(p))));
    631    EXPECT_EQ(8, Distance(p, Type<int32_t*>(L::Partial(5).Pointer<1>(p))));
    632    EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0, 0).Pointer<0>(p))));
    633    EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(0, 0).Pointer<1>(p))));
    634    EXPECT_EQ(0, Distance(p, Type<Int128*>(L::Partial(0, 0).Pointer<2>(p))));
    635    EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1, 0).Pointer<0>(p))));
    636    EXPECT_EQ(4, Distance(p, Type<int32_t*>(L::Partial(1, 0).Pointer<1>(p))));
    637    EXPECT_EQ(8, Distance(p, Type<Int128*>(L::Partial(1, 0).Pointer<2>(p))));
    638    EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5, 3).Pointer<0>(p))));
    639    EXPECT_EQ(8, Distance(p, Type<int32_t*>(L::Partial(5, 3).Pointer<1>(p))));
    640    EXPECT_EQ(24, Distance(p, Type<Int128*>(L::Partial(5, 3).Pointer<2>(p))));
    641    EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0, 0, 0).Pointer<0>(p))));
    642    EXPECT_EQ(0,
    643              Distance(p, Type<int32_t*>(L::Partial(0, 0, 0).Pointer<1>(p))));
    644    EXPECT_EQ(0, Distance(p, Type<Int128*>(L::Partial(0, 0, 0).Pointer<2>(p))));
    645    EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1, 0, 0).Pointer<0>(p))));
    646    EXPECT_EQ(4,
    647              Distance(p, Type<int32_t*>(L::Partial(1, 0, 0).Pointer<1>(p))));
    648    EXPECT_EQ(8, Distance(p, Type<Int128*>(L::Partial(1, 0, 0).Pointer<2>(p))));
    649    EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5, 3, 1).Pointer<0>(p))));
    650    EXPECT_EQ(24,
    651              Distance(p, Type<Int128*>(L::Partial(5, 3, 1).Pointer<2>(p))));
    652    EXPECT_EQ(8,
    653              Distance(p, Type<int32_t*>(L::Partial(5, 3, 1).Pointer<1>(p))));
    654    EXPECT_EQ(0, Distance(p, Type<int8_t*>(L(5, 3, 1).Pointer<0>(p))));
    655    EXPECT_EQ(24, Distance(p, Type<Int128*>(L(5, 3, 1).Pointer<2>(p))));
    656    EXPECT_EQ(8, Distance(p, Type<int32_t*>(L(5, 3, 1).Pointer<1>(p))));
    657  }
    658 }
    659 
    660 TEST(Layout, MutablePointerByType) {
    661  alignas(max_align_t) unsigned char p[100] = {0};
    662  {
    663    using L = Layout<int32_t>;
    664    EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial().Pointer<int32_t>(p))));
    665    EXPECT_EQ(0,
    666              Distance(p, Type<int32_t*>(L::Partial(3).Pointer<int32_t>(p))));
    667    EXPECT_EQ(0, Distance(p, Type<int32_t*>(L(3).Pointer<int32_t>(p))));
    668  }
    669  {
    670    using L = Layout<int8_t, int32_t, Int128>;
    671    EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial().Pointer<int8_t>(p))));
    672    EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0).Pointer<int8_t>(p))));
    673    EXPECT_EQ(0,
    674              Distance(p, Type<int32_t*>(L::Partial(0).Pointer<int32_t>(p))));
    675    EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1).Pointer<int8_t>(p))));
    676    EXPECT_EQ(4,
    677              Distance(p, Type<int32_t*>(L::Partial(1).Pointer<int32_t>(p))));
    678    EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5).Pointer<int8_t>(p))));
    679    EXPECT_EQ(8,
    680              Distance(p, Type<int32_t*>(L::Partial(5).Pointer<int32_t>(p))));
    681    EXPECT_EQ(0,
    682              Distance(p, Type<int8_t*>(L::Partial(0, 0).Pointer<int8_t>(p))));
    683    EXPECT_EQ(
    684        0, Distance(p, Type<int32_t*>(L::Partial(0, 0).Pointer<int32_t>(p))));
    685    EXPECT_EQ(0,
    686              Distance(p, Type<Int128*>(L::Partial(0, 0).Pointer<Int128>(p))));
    687    EXPECT_EQ(0,
    688              Distance(p, Type<int8_t*>(L::Partial(1, 0).Pointer<int8_t>(p))));
    689    EXPECT_EQ(
    690        4, Distance(p, Type<int32_t*>(L::Partial(1, 0).Pointer<int32_t>(p))));
    691    EXPECT_EQ(8,
    692              Distance(p, Type<Int128*>(L::Partial(1, 0).Pointer<Int128>(p))));
    693    EXPECT_EQ(0,
    694              Distance(p, Type<int8_t*>(L::Partial(5, 3).Pointer<int8_t>(p))));
    695    EXPECT_EQ(
    696        8, Distance(p, Type<int32_t*>(L::Partial(5, 3).Pointer<int32_t>(p))));
    697    EXPECT_EQ(24,
    698              Distance(p, Type<Int128*>(L::Partial(5, 3).Pointer<Int128>(p))));
    699    EXPECT_EQ(
    700        0, Distance(p, Type<int8_t*>(L::Partial(0, 0, 0).Pointer<int8_t>(p))));
    701    EXPECT_EQ(
    702        0,
    703        Distance(p, Type<int32_t*>(L::Partial(0, 0, 0).Pointer<int32_t>(p))));
    704    EXPECT_EQ(
    705        0, Distance(p, Type<Int128*>(L::Partial(0, 0, 0).Pointer<Int128>(p))));
    706    EXPECT_EQ(
    707        0, Distance(p, Type<int8_t*>(L::Partial(1, 0, 0).Pointer<int8_t>(p))));
    708    EXPECT_EQ(
    709        4,
    710        Distance(p, Type<int32_t*>(L::Partial(1, 0, 0).Pointer<int32_t>(p))));
    711    EXPECT_EQ(
    712        8, Distance(p, Type<Int128*>(L::Partial(1, 0, 0).Pointer<Int128>(p))));
    713    EXPECT_EQ(
    714        0, Distance(p, Type<int8_t*>(L::Partial(5, 3, 1).Pointer<int8_t>(p))));
    715    EXPECT_EQ(
    716        24, Distance(p, Type<Int128*>(L::Partial(5, 3, 1).Pointer<Int128>(p))));
    717    EXPECT_EQ(
    718        8,
    719        Distance(p, Type<int32_t*>(L::Partial(5, 3, 1).Pointer<int32_t>(p))));
    720    EXPECT_EQ(0, Distance(p, Type<int8_t*>(L(5, 3, 1).Pointer<int8_t>(p))));
    721    EXPECT_EQ(24, Distance(p, Type<Int128*>(L(5, 3, 1).Pointer<Int128>(p))));
    722    EXPECT_EQ(8, Distance(p, Type<int32_t*>(L(5, 3, 1).Pointer<int32_t>(p))));
    723  }
    724 }
    725 
    726 TEST(Layout, Pointers) {
    727  alignas(max_align_t) const unsigned char p[100] = {0};
    728  using L = Layout<int8_t, int8_t, Int128>;
    729  {
    730    const auto x = L::Partial();
    731    EXPECT_EQ(std::make_tuple(x.Pointer<0>(p)),
    732              Type<std::tuple<const int8_t*>>(x.Pointers(p)));
    733  }
    734  {
    735    const auto x = L::Partial(1);
    736    EXPECT_EQ(std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p)),
    737              (Type<std::tuple<const int8_t*, const int8_t*>>(x.Pointers(p))));
    738  }
    739  {
    740    const auto x = L::Partial(1, 2);
    741    EXPECT_EQ(
    742        std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
    743        (Type<std::tuple<const int8_t*, const int8_t*, const Int128*>>(
    744            x.Pointers(p))));
    745  }
    746  {
    747    const auto x = L::Partial(1, 2, 3);
    748    EXPECT_EQ(
    749        std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
    750        (Type<std::tuple<const int8_t*, const int8_t*, const Int128*>>(
    751            x.Pointers(p))));
    752  }
    753  {
    754    const L x(1, 2, 3);
    755    EXPECT_EQ(
    756        std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
    757        (Type<std::tuple<const int8_t*, const int8_t*, const Int128*>>(
    758            x.Pointers(p))));
    759  }
    760 }
    761 
    762 TEST(Layout, MutablePointers) {
    763  alignas(max_align_t) unsigned char p[100] = {0};
    764  using L = Layout<int8_t, int8_t, Int128>;
    765  {
    766    const auto x = L::Partial();
    767    EXPECT_EQ(std::make_tuple(x.Pointer<0>(p)),
    768              Type<std::tuple<int8_t*>>(x.Pointers(p)));
    769  }
    770  {
    771    const auto x = L::Partial(1);
    772    EXPECT_EQ(std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p)),
    773              (Type<std::tuple<int8_t*, int8_t*>>(x.Pointers(p))));
    774  }
    775  {
    776    const auto x = L::Partial(1, 2);
    777    EXPECT_EQ(
    778        std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
    779        (Type<std::tuple<int8_t*, int8_t*, Int128*>>(x.Pointers(p))));
    780  }
    781  {
    782    const auto x = L::Partial(1, 2, 3);
    783    EXPECT_EQ(
    784        std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
    785        (Type<std::tuple<int8_t*, int8_t*, Int128*>>(x.Pointers(p))));
    786  }
    787  {
    788    const L x(1, 2, 3);
    789    EXPECT_EQ(
    790        std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
    791        (Type<std::tuple<int8_t*, int8_t*, Int128*>>(x.Pointers(p))));
    792  }
    793 }
    794 
    795 TEST(Layout, StaticPointers) {
    796  alignas(max_align_t) const unsigned char p[100] = {0};
    797  using L = Layout<int8_t, int8_t, Int128>;
    798  {
    799    const auto x = L::WithStaticSizes<>::Partial();
    800    EXPECT_EQ(std::make_tuple(x.Pointer<0>(p)),
    801              Type<std::tuple<const int8_t*>>(x.Pointers(p)));
    802  }
    803  {
    804    const auto x = L::WithStaticSizes<>::Partial(1);
    805    EXPECT_EQ(std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p)),
    806              (Type<std::tuple<const int8_t*, const int8_t*>>(x.Pointers(p))));
    807  }
    808  {
    809    const auto x = L::WithStaticSizes<1>::Partial();
    810    EXPECT_EQ(std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p)),
    811              (Type<std::tuple<const int8_t*, const int8_t*>>(x.Pointers(p))));
    812  }
    813  {
    814    const auto x = L::WithStaticSizes<>::Partial(1, 2, 3);
    815    EXPECT_EQ(
    816        std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
    817        (Type<std::tuple<const int8_t*, const int8_t*, const Int128*>>(
    818            x.Pointers(p))));
    819  }
    820  {
    821    const auto x = L::WithStaticSizes<1>::Partial(2, 3);
    822    EXPECT_EQ(
    823        std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
    824        (Type<std::tuple<const int8_t*, const int8_t*, const Int128*>>(
    825            x.Pointers(p))));
    826  }
    827  {
    828    const auto x = L::WithStaticSizes<1, 2>::Partial(3);
    829    EXPECT_EQ(
    830        std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
    831        (Type<std::tuple<const int8_t*, const int8_t*, const Int128*>>(
    832            x.Pointers(p))));
    833  }
    834  {
    835    const auto x = L::WithStaticSizes<1, 2, 3>::Partial();
    836    EXPECT_EQ(
    837        std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
    838        (Type<std::tuple<const int8_t*, const int8_t*, const Int128*>>(
    839            x.Pointers(p))));
    840  }
    841  {
    842    const L::WithStaticSizes<1, 2, 3> x;
    843    EXPECT_EQ(
    844        std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
    845        (Type<std::tuple<const int8_t*, const int8_t*, const Int128*>>(
    846            x.Pointers(p))));
    847  }
    848 }
    849 
    850 TEST(Layout, SliceByIndexSize) {
    851  alignas(max_align_t) const unsigned char p[100] = {0};
    852  {
    853    using L = Layout<int32_t>;
    854    EXPECT_EQ(0, L::Partial(0).Slice<0>(p).size());
    855    EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size());
    856    EXPECT_EQ(3, L(3).Slice<0>(p).size());
    857  }
    858  {
    859    using L = Layout<int32_t, int32_t>;
    860    EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size());
    861    EXPECT_EQ(5, L::Partial(3, 5).Slice<1>(p).size());
    862    EXPECT_EQ(5, L(3, 5).Slice<1>(p).size());
    863  }
    864  {
    865    using L = Layout<int8_t, int32_t, Int128>;
    866    EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size());
    867    EXPECT_EQ(3, L::Partial(3, 5).Slice<0>(p).size());
    868    EXPECT_EQ(5, L::Partial(3, 5).Slice<1>(p).size());
    869    EXPECT_EQ(3, L::Partial(3, 5, 7).Slice<0>(p).size());
    870    EXPECT_EQ(5, L::Partial(3, 5, 7).Slice<1>(p).size());
    871    EXPECT_EQ(7, L::Partial(3, 5, 7).Slice<2>(p).size());
    872    EXPECT_EQ(3, L(3, 5, 7).Slice<0>(p).size());
    873    EXPECT_EQ(5, L(3, 5, 7).Slice<1>(p).size());
    874    EXPECT_EQ(7, L(3, 5, 7).Slice<2>(p).size());
    875  }
    876 }
    877 
    878 TEST(Layout, SliceByTypeSize) {
    879  alignas(max_align_t) const unsigned char p[100] = {0};
    880  {
    881    using L = Layout<int32_t>;
    882    EXPECT_EQ(0, L::Partial(0).Slice<int32_t>(p).size());
    883    EXPECT_EQ(3, L::Partial(3).Slice<int32_t>(p).size());
    884    EXPECT_EQ(3, L(3).Slice<int32_t>(p).size());
    885  }
    886  {
    887    using L = Layout<int8_t, int32_t, Int128>;
    888    EXPECT_EQ(3, L::Partial(3).Slice<int8_t>(p).size());
    889    EXPECT_EQ(3, L::Partial(3, 5).Slice<int8_t>(p).size());
    890    EXPECT_EQ(5, L::Partial(3, 5).Slice<int32_t>(p).size());
    891    EXPECT_EQ(3, L::Partial(3, 5, 7).Slice<int8_t>(p).size());
    892    EXPECT_EQ(5, L::Partial(3, 5, 7).Slice<int32_t>(p).size());
    893    EXPECT_EQ(7, L::Partial(3, 5, 7).Slice<Int128>(p).size());
    894    EXPECT_EQ(3, L(3, 5, 7).Slice<int8_t>(p).size());
    895    EXPECT_EQ(5, L(3, 5, 7).Slice<int32_t>(p).size());
    896    EXPECT_EQ(7, L(3, 5, 7).Slice<Int128>(p).size());
    897  }
    898 }
    899 TEST(Layout, MutableSliceByIndexSize) {
    900  alignas(max_align_t) unsigned char p[100] = {0};
    901  {
    902    using L = Layout<int32_t>;
    903    EXPECT_EQ(0, L::Partial(0).Slice<0>(p).size());
    904    EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size());
    905    EXPECT_EQ(3, L(3).Slice<0>(p).size());
    906  }
    907  {
    908    using L = Layout<int32_t, int32_t>;
    909    EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size());
    910    EXPECT_EQ(5, L::Partial(3, 5).Slice<1>(p).size());
    911    EXPECT_EQ(5, L(3, 5).Slice<1>(p).size());
    912  }
    913  {
    914    using L = Layout<int8_t, int32_t, Int128>;
    915    EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size());
    916    EXPECT_EQ(3, L::Partial(3, 5).Slice<0>(p).size());
    917    EXPECT_EQ(5, L::Partial(3, 5).Slice<1>(p).size());
    918    EXPECT_EQ(3, L::Partial(3, 5, 7).Slice<0>(p).size());
    919    EXPECT_EQ(5, L::Partial(3, 5, 7).Slice<1>(p).size());
    920    EXPECT_EQ(7, L::Partial(3, 5, 7).Slice<2>(p).size());
    921    EXPECT_EQ(3, L(3, 5, 7).Slice<0>(p).size());
    922    EXPECT_EQ(5, L(3, 5, 7).Slice<1>(p).size());
    923    EXPECT_EQ(7, L(3, 5, 7).Slice<2>(p).size());
    924  }
    925 }
    926 
    927 TEST(Layout, MutableSliceByTypeSize) {
    928  alignas(max_align_t) unsigned char p[100] = {0};
    929  {
    930    using L = Layout<int32_t>;
    931    EXPECT_EQ(0, L::Partial(0).Slice<int32_t>(p).size());
    932    EXPECT_EQ(3, L::Partial(3).Slice<int32_t>(p).size());
    933    EXPECT_EQ(3, L(3).Slice<int32_t>(p).size());
    934  }
    935  {
    936    using L = Layout<int8_t, int32_t, Int128>;
    937    EXPECT_EQ(3, L::Partial(3).Slice<int8_t>(p).size());
    938    EXPECT_EQ(3, L::Partial(3, 5).Slice<int8_t>(p).size());
    939    EXPECT_EQ(5, L::Partial(3, 5).Slice<int32_t>(p).size());
    940    EXPECT_EQ(3, L::Partial(3, 5, 7).Slice<int8_t>(p).size());
    941    EXPECT_EQ(5, L::Partial(3, 5, 7).Slice<int32_t>(p).size());
    942    EXPECT_EQ(7, L::Partial(3, 5, 7).Slice<Int128>(p).size());
    943    EXPECT_EQ(3, L(3, 5, 7).Slice<int8_t>(p).size());
    944    EXPECT_EQ(5, L(3, 5, 7).Slice<int32_t>(p).size());
    945    EXPECT_EQ(7, L(3, 5, 7).Slice<Int128>(p).size());
    946  }
    947 }
    948 
    949 TEST(Layout, StaticSliceSize) {
    950  alignas(max_align_t) const unsigned char cp[100] = {0};
    951  alignas(max_align_t) unsigned char p[100] = {0};
    952  using L = Layout<int8_t, int32_t, Int128>;
    953  using SL = L::WithStaticSizes<3, 5>;
    954 
    955  EXPECT_EQ(3, SL::Partial().Slice<0>(cp).size());
    956  EXPECT_EQ(3, SL::Partial().Slice<int8_t>(cp).size());
    957  EXPECT_EQ(3, SL::Partial(7).Slice<0>(cp).size());
    958  EXPECT_EQ(3, SL::Partial(7).Slice<int8_t>(cp).size());
    959 
    960  EXPECT_EQ(5, SL::Partial().Slice<1>(cp).size());
    961  EXPECT_EQ(5, SL::Partial().Slice<int32_t>(cp).size());
    962  EXPECT_EQ(5, SL::Partial(7).Slice<1>(cp).size());
    963  EXPECT_EQ(5, SL::Partial(7).Slice<int32_t>(cp).size());
    964 
    965  EXPECT_EQ(7, SL::Partial(7).Slice<2>(cp).size());
    966  EXPECT_EQ(7, SL::Partial(7).Slice<Int128>(cp).size());
    967 
    968  EXPECT_EQ(3, SL::Partial().Slice<0>(p).size());
    969  EXPECT_EQ(3, SL::Partial().Slice<int8_t>(p).size());
    970  EXPECT_EQ(3, SL::Partial(7).Slice<0>(p).size());
    971  EXPECT_EQ(3, SL::Partial(7).Slice<int8_t>(p).size());
    972 
    973  EXPECT_EQ(5, SL::Partial().Slice<1>(p).size());
    974  EXPECT_EQ(5, SL::Partial().Slice<int32_t>(p).size());
    975  EXPECT_EQ(5, SL::Partial(7).Slice<1>(p).size());
    976  EXPECT_EQ(5, SL::Partial(7).Slice<int32_t>(p).size());
    977 
    978  EXPECT_EQ(7, SL::Partial(7).Slice<2>(p).size());
    979  EXPECT_EQ(7, SL::Partial(7).Slice<Int128>(p).size());
    980 }
    981 
    982 TEST(Layout, SliceByIndexData) {
    983  alignas(max_align_t) const unsigned char p[100] = {0};
    984  {
    985    using L = Layout<int32_t>;
    986    EXPECT_EQ(
    987        0, Distance(
    988               p, Type<Span<const int32_t>>(L::Partial(0).Slice<0>(p)).data()));
    989    EXPECT_EQ(
    990        0, Distance(
    991               p, Type<Span<const int32_t>>(L::Partial(3).Slice<0>(p)).data()));
    992    EXPECT_EQ(0,
    993              Distance(p, Type<Span<const int32_t>>(L(3).Slice<0>(p)).data()));
    994  }
    995  {
    996    using L = Layout<int32_t, int32_t>;
    997    EXPECT_EQ(
    998        0, Distance(
    999               p, Type<Span<const int32_t>>(L::Partial(3).Slice<0>(p)).data()));
   1000    EXPECT_EQ(
   1001        0,
   1002        Distance(
   1003            p, Type<Span<const int32_t>>(L::Partial(3, 5).Slice<0>(p)).data()));
   1004    EXPECT_EQ(
   1005        12,
   1006        Distance(
   1007            p, Type<Span<const int32_t>>(L::Partial(3, 5).Slice<1>(p)).data()));
   1008    EXPECT_EQ(
   1009        0, Distance(p, Type<Span<const int32_t>>(L(3, 5).Slice<0>(p)).data()));
   1010    EXPECT_EQ(
   1011        12, Distance(p, Type<Span<const int32_t>>(L(3, 5).Slice<1>(p)).data()));
   1012  }
   1013  {
   1014    using L = Layout<int8_t, int32_t, Int128>;
   1015    EXPECT_EQ(
   1016        0, Distance(
   1017               p, Type<Span<const int8_t>>(L::Partial(0).Slice<0>(p)).data()));
   1018    EXPECT_EQ(
   1019        0, Distance(
   1020               p, Type<Span<const int8_t>>(L::Partial(1).Slice<0>(p)).data()));
   1021    EXPECT_EQ(
   1022        0, Distance(
   1023               p, Type<Span<const int8_t>>(L::Partial(5).Slice<0>(p)).data()));
   1024    EXPECT_EQ(
   1025        0,
   1026        Distance(
   1027            p, Type<Span<const int8_t>>(L::Partial(0, 0).Slice<0>(p)).data()));
   1028    EXPECT_EQ(
   1029        0,
   1030        Distance(
   1031            p, Type<Span<const int32_t>>(L::Partial(0, 0).Slice<1>(p)).data()));
   1032    EXPECT_EQ(
   1033        0,
   1034        Distance(
   1035            p, Type<Span<const int8_t>>(L::Partial(1, 0).Slice<0>(p)).data()));
   1036    EXPECT_EQ(
   1037        4,
   1038        Distance(
   1039            p, Type<Span<const int32_t>>(L::Partial(1, 0).Slice<1>(p)).data()));
   1040    EXPECT_EQ(
   1041        0,
   1042        Distance(
   1043            p, Type<Span<const int8_t>>(L::Partial(5, 3).Slice<0>(p)).data()));
   1044    EXPECT_EQ(
   1045        8,
   1046        Distance(
   1047            p, Type<Span<const int32_t>>(L::Partial(5, 3).Slice<1>(p)).data()));
   1048    EXPECT_EQ(
   1049        0,
   1050        Distance(
   1051            p,
   1052            Type<Span<const int8_t>>(L::Partial(0, 0, 0).Slice<0>(p)).data()));
   1053    EXPECT_EQ(
   1054        0,
   1055        Distance(
   1056            p,
   1057            Type<Span<const int32_t>>(L::Partial(0, 0, 0).Slice<1>(p)).data()));
   1058    EXPECT_EQ(
   1059        0,
   1060        Distance(
   1061            p,
   1062            Type<Span<const Int128>>(L::Partial(0, 0, 0).Slice<2>(p)).data()));
   1063    EXPECT_EQ(
   1064        0,
   1065        Distance(
   1066            p,
   1067            Type<Span<const int8_t>>(L::Partial(1, 0, 0).Slice<0>(p)).data()));
   1068    EXPECT_EQ(
   1069        4,
   1070        Distance(
   1071            p,
   1072            Type<Span<const int32_t>>(L::Partial(1, 0, 0).Slice<1>(p)).data()));
   1073    EXPECT_EQ(
   1074        8,
   1075        Distance(
   1076            p,
   1077            Type<Span<const Int128>>(L::Partial(1, 0, 0).Slice<2>(p)).data()));
   1078    EXPECT_EQ(
   1079        0,
   1080        Distance(
   1081            p,
   1082            Type<Span<const int8_t>>(L::Partial(5, 3, 1).Slice<0>(p)).data()));
   1083    EXPECT_EQ(
   1084        24,
   1085        Distance(
   1086            p,
   1087            Type<Span<const Int128>>(L::Partial(5, 3, 1).Slice<2>(p)).data()));
   1088    EXPECT_EQ(
   1089        8,
   1090        Distance(
   1091            p,
   1092            Type<Span<const int32_t>>(L::Partial(5, 3, 1).Slice<1>(p)).data()));
   1093    EXPECT_EQ(
   1094        0,
   1095        Distance(p, Type<Span<const int8_t>>(L(5, 3, 1).Slice<0>(p)).data()));
   1096    EXPECT_EQ(
   1097        24,
   1098        Distance(p, Type<Span<const Int128>>(L(5, 3, 1).Slice<2>(p)).data()));
   1099    EXPECT_EQ(
   1100        8,
   1101        Distance(p, Type<Span<const int32_t>>(L(5, 3, 1).Slice<1>(p)).data()));
   1102  }
   1103 }
   1104 
   1105 TEST(Layout, SliceByTypeData) {
   1106  alignas(max_align_t) const unsigned char p[100] = {0};
   1107  {
   1108    using L = Layout<int32_t>;
   1109    EXPECT_EQ(
   1110        0,
   1111        Distance(
   1112            p,
   1113            Type<Span<const int32_t>>(L::Partial(0).Slice<int32_t>(p)).data()));
   1114    EXPECT_EQ(
   1115        0,
   1116        Distance(
   1117            p,
   1118            Type<Span<const int32_t>>(L::Partial(3).Slice<int32_t>(p)).data()));
   1119    EXPECT_EQ(
   1120        0,
   1121        Distance(p, Type<Span<const int32_t>>(L(3).Slice<int32_t>(p)).data()));
   1122  }
   1123  {
   1124    using L = Layout<int8_t, int32_t, Int128>;
   1125    EXPECT_EQ(
   1126        0,
   1127        Distance(
   1128            p,
   1129            Type<Span<const int8_t>>(L::Partial(0).Slice<int8_t>(p)).data()));
   1130    EXPECT_EQ(
   1131        0,
   1132        Distance(
   1133            p,
   1134            Type<Span<const int8_t>>(L::Partial(1).Slice<int8_t>(p)).data()));
   1135    EXPECT_EQ(
   1136        0,
   1137        Distance(
   1138            p,
   1139            Type<Span<const int8_t>>(L::Partial(5).Slice<int8_t>(p)).data()));
   1140    EXPECT_EQ(
   1141        0,
   1142        Distance(p, Type<Span<const int8_t>>(L::Partial(0, 0).Slice<int8_t>(p))
   1143                        .data()));
   1144    EXPECT_EQ(0, Distance(p, Type<Span<const int32_t>>(
   1145                                 L::Partial(0, 0).Slice<int32_t>(p))
   1146                                 .data()));
   1147    EXPECT_EQ(
   1148        0,
   1149        Distance(p, Type<Span<const int8_t>>(L::Partial(1, 0).Slice<int8_t>(p))
   1150                        .data()));
   1151    EXPECT_EQ(4, Distance(p, Type<Span<const int32_t>>(
   1152                                 L::Partial(1, 0).Slice<int32_t>(p))
   1153                                 .data()));
   1154    EXPECT_EQ(
   1155        0,
   1156        Distance(p, Type<Span<const int8_t>>(L::Partial(5, 3).Slice<int8_t>(p))
   1157                        .data()));
   1158    EXPECT_EQ(8, Distance(p, Type<Span<const int32_t>>(
   1159                                 L::Partial(5, 3).Slice<int32_t>(p))
   1160                                 .data()));
   1161    EXPECT_EQ(0, Distance(p, Type<Span<const int8_t>>(
   1162                                 L::Partial(0, 0, 0).Slice<int8_t>(p))
   1163                                 .data()));
   1164    EXPECT_EQ(0, Distance(p, Type<Span<const int32_t>>(
   1165                                 L::Partial(0, 0, 0).Slice<int32_t>(p))
   1166                                 .data()));
   1167    EXPECT_EQ(0, Distance(p, Type<Span<const Int128>>(
   1168                                 L::Partial(0, 0, 0).Slice<Int128>(p))
   1169                                 .data()));
   1170    EXPECT_EQ(0, Distance(p, Type<Span<const int8_t>>(
   1171                                 L::Partial(1, 0, 0).Slice<int8_t>(p))
   1172                                 .data()));
   1173    EXPECT_EQ(4, Distance(p, Type<Span<const int32_t>>(
   1174                                 L::Partial(1, 0, 0).Slice<int32_t>(p))
   1175                                 .data()));
   1176    EXPECT_EQ(8, Distance(p, Type<Span<const Int128>>(
   1177                                 L::Partial(1, 0, 0).Slice<Int128>(p))
   1178                                 .data()));
   1179    EXPECT_EQ(0, Distance(p, Type<Span<const int8_t>>(
   1180                                 L::Partial(5, 3, 1).Slice<int8_t>(p))
   1181                                 .data()));
   1182    EXPECT_EQ(24, Distance(p, Type<Span<const Int128>>(
   1183                                  L::Partial(5, 3, 1).Slice<Int128>(p))
   1184                                  .data()));
   1185    EXPECT_EQ(8, Distance(p, Type<Span<const int32_t>>(
   1186                                 L::Partial(5, 3, 1).Slice<int32_t>(p))
   1187                                 .data()));
   1188    EXPECT_EQ(
   1189        0,
   1190        Distance(p,
   1191                 Type<Span<const int8_t>>(L(5, 3, 1).Slice<int8_t>(p)).data()));
   1192    EXPECT_EQ(
   1193        24,
   1194        Distance(p,
   1195                 Type<Span<const Int128>>(L(5, 3, 1).Slice<Int128>(p)).data()));
   1196    EXPECT_EQ(
   1197        8,
   1198        Distance(
   1199            p, Type<Span<const int32_t>>(L(5, 3, 1).Slice<int32_t>(p)).data()));
   1200  }
   1201 }
   1202 
   1203 TEST(Layout, MutableSliceByIndexData) {
   1204  alignas(max_align_t) unsigned char p[100] = {0};
   1205  {
   1206    using L = Layout<int32_t>;
   1207    EXPECT_EQ(
   1208        0, Distance(p, Type<Span<int32_t>>(L::Partial(0).Slice<0>(p)).data()));
   1209    EXPECT_EQ(
   1210        0, Distance(p, Type<Span<int32_t>>(L::Partial(3).Slice<0>(p)).data()));
   1211    EXPECT_EQ(0, Distance(p, Type<Span<int32_t>>(L(3).Slice<0>(p)).data()));
   1212  }
   1213  {
   1214    using L = Layout<int32_t, int32_t>;
   1215    EXPECT_EQ(
   1216        0, Distance(p, Type<Span<int32_t>>(L::Partial(3).Slice<0>(p)).data()));
   1217    EXPECT_EQ(
   1218        0,
   1219        Distance(p, Type<Span<int32_t>>(L::Partial(3, 5).Slice<0>(p)).data()));
   1220    EXPECT_EQ(
   1221        12,
   1222        Distance(p, Type<Span<int32_t>>(L::Partial(3, 5).Slice<1>(p)).data()));
   1223    EXPECT_EQ(0, Distance(p, Type<Span<int32_t>>(L(3, 5).Slice<0>(p)).data()));
   1224    EXPECT_EQ(12, Distance(p, Type<Span<int32_t>>(L(3, 5).Slice<1>(p)).data()));
   1225  }
   1226  {
   1227    using L = Layout<int8_t, int32_t, Int128>;
   1228    EXPECT_EQ(
   1229        0, Distance(p, Type<Span<int8_t>>(L::Partial(0).Slice<0>(p)).data()));
   1230    EXPECT_EQ(
   1231        0, Distance(p, Type<Span<int8_t>>(L::Partial(1).Slice<0>(p)).data()));
   1232    EXPECT_EQ(
   1233        0, Distance(p, Type<Span<int8_t>>(L::Partial(5).Slice<0>(p)).data()));
   1234    EXPECT_EQ(
   1235        0,
   1236        Distance(p, Type<Span<int8_t>>(L::Partial(0, 0).Slice<0>(p)).data()));
   1237    EXPECT_EQ(
   1238        0,
   1239        Distance(p, Type<Span<int32_t>>(L::Partial(0, 0).Slice<1>(p)).data()));
   1240    EXPECT_EQ(
   1241        0,
   1242        Distance(p, Type<Span<int8_t>>(L::Partial(1, 0).Slice<0>(p)).data()));
   1243    EXPECT_EQ(
   1244        4,
   1245        Distance(p, Type<Span<int32_t>>(L::Partial(1, 0).Slice<1>(p)).data()));
   1246    EXPECT_EQ(
   1247        0,
   1248        Distance(p, Type<Span<int8_t>>(L::Partial(5, 3).Slice<0>(p)).data()));
   1249    EXPECT_EQ(
   1250        8,
   1251        Distance(p, Type<Span<int32_t>>(L::Partial(5, 3).Slice<1>(p)).data()));
   1252    EXPECT_EQ(
   1253        0, Distance(
   1254               p, Type<Span<int8_t>>(L::Partial(0, 0, 0).Slice<0>(p)).data()));
   1255    EXPECT_EQ(
   1256        0, Distance(
   1257               p, Type<Span<int32_t>>(L::Partial(0, 0, 0).Slice<1>(p)).data()));
   1258    EXPECT_EQ(
   1259        0, Distance(
   1260               p, Type<Span<Int128>>(L::Partial(0, 0, 0).Slice<2>(p)).data()));
   1261    EXPECT_EQ(
   1262        0, Distance(
   1263               p, Type<Span<int8_t>>(L::Partial(1, 0, 0).Slice<0>(p)).data()));
   1264    EXPECT_EQ(
   1265        4, Distance(
   1266               p, Type<Span<int32_t>>(L::Partial(1, 0, 0).Slice<1>(p)).data()));
   1267    EXPECT_EQ(
   1268        8, Distance(
   1269               p, Type<Span<Int128>>(L::Partial(1, 0, 0).Slice<2>(p)).data()));
   1270    EXPECT_EQ(
   1271        0, Distance(
   1272               p, Type<Span<int8_t>>(L::Partial(5, 3, 1).Slice<0>(p)).data()));
   1273    EXPECT_EQ(
   1274        24, Distance(
   1275                p, Type<Span<Int128>>(L::Partial(5, 3, 1).Slice<2>(p)).data()));
   1276    EXPECT_EQ(
   1277        8, Distance(
   1278               p, Type<Span<int32_t>>(L::Partial(5, 3, 1).Slice<1>(p)).data()));
   1279    EXPECT_EQ(0,
   1280              Distance(p, Type<Span<int8_t>>(L(5, 3, 1).Slice<0>(p)).data()));
   1281    EXPECT_EQ(24,
   1282              Distance(p, Type<Span<Int128>>(L(5, 3, 1).Slice<2>(p)).data()));
   1283    EXPECT_EQ(8,
   1284              Distance(p, Type<Span<int32_t>>(L(5, 3, 1).Slice<1>(p)).data()));
   1285  }
   1286 }
   1287 
   1288 TEST(Layout, MutableSliceByTypeData) {
   1289  alignas(max_align_t) unsigned char p[100] = {0};
   1290  {
   1291    using L = Layout<int32_t>;
   1292    EXPECT_EQ(
   1293        0, Distance(
   1294               p, Type<Span<int32_t>>(L::Partial(0).Slice<int32_t>(p)).data()));
   1295    EXPECT_EQ(
   1296        0, Distance(
   1297               p, Type<Span<int32_t>>(L::Partial(3).Slice<int32_t>(p)).data()));
   1298    EXPECT_EQ(0,
   1299              Distance(p, Type<Span<int32_t>>(L(3).Slice<int32_t>(p)).data()));
   1300  }
   1301  {
   1302    using L = Layout<int8_t, int32_t, Int128>;
   1303    EXPECT_EQ(
   1304        0,
   1305        Distance(p, Type<Span<int8_t>>(L::Partial(0).Slice<int8_t>(p)).data()));
   1306    EXPECT_EQ(
   1307        0,
   1308        Distance(p, Type<Span<int8_t>>(L::Partial(1).Slice<int8_t>(p)).data()));
   1309    EXPECT_EQ(
   1310        0,
   1311        Distance(p, Type<Span<int8_t>>(L::Partial(5).Slice<int8_t>(p)).data()));
   1312    EXPECT_EQ(
   1313        0,
   1314        Distance(p,
   1315                 Type<Span<int8_t>>(L::Partial(0, 0).Slice<int8_t>(p)).data()));
   1316    EXPECT_EQ(
   1317        0,
   1318        Distance(
   1319            p, Type<Span<int32_t>>(L::Partial(0, 0).Slice<int32_t>(p)).data()));
   1320    EXPECT_EQ(
   1321        0,
   1322        Distance(p,
   1323                 Type<Span<int8_t>>(L::Partial(1, 0).Slice<int8_t>(p)).data()));
   1324    EXPECT_EQ(
   1325        4,
   1326        Distance(
   1327            p, Type<Span<int32_t>>(L::Partial(1, 0).Slice<int32_t>(p)).data()));
   1328    EXPECT_EQ(
   1329        0,
   1330        Distance(p,
   1331                 Type<Span<int8_t>>(L::Partial(5, 3).Slice<int8_t>(p)).data()));
   1332    EXPECT_EQ(
   1333        8,
   1334        Distance(
   1335            p, Type<Span<int32_t>>(L::Partial(5, 3).Slice<int32_t>(p)).data()));
   1336    EXPECT_EQ(
   1337        0,
   1338        Distance(
   1339            p,
   1340            Type<Span<int8_t>>(L::Partial(0, 0, 0).Slice<int8_t>(p)).data()));
   1341    EXPECT_EQ(
   1342        0,
   1343        Distance(
   1344            p,
   1345            Type<Span<int32_t>>(L::Partial(0, 0, 0).Slice<int32_t>(p)).data()));
   1346    EXPECT_EQ(
   1347        0,
   1348        Distance(
   1349            p,
   1350            Type<Span<Int128>>(L::Partial(0, 0, 0).Slice<Int128>(p)).data()));
   1351    EXPECT_EQ(
   1352        0,
   1353        Distance(
   1354            p,
   1355            Type<Span<int8_t>>(L::Partial(1, 0, 0).Slice<int8_t>(p)).data()));
   1356    EXPECT_EQ(
   1357        4,
   1358        Distance(
   1359            p,
   1360            Type<Span<int32_t>>(L::Partial(1, 0, 0).Slice<int32_t>(p)).data()));
   1361    EXPECT_EQ(
   1362        8,
   1363        Distance(
   1364            p,
   1365            Type<Span<Int128>>(L::Partial(1, 0, 0).Slice<Int128>(p)).data()));
   1366    EXPECT_EQ(
   1367        0,
   1368        Distance(
   1369            p,
   1370            Type<Span<int8_t>>(L::Partial(5, 3, 1).Slice<int8_t>(p)).data()));
   1371    EXPECT_EQ(
   1372        24,
   1373        Distance(
   1374            p,
   1375            Type<Span<Int128>>(L::Partial(5, 3, 1).Slice<Int128>(p)).data()));
   1376    EXPECT_EQ(
   1377        8,
   1378        Distance(
   1379            p,
   1380            Type<Span<int32_t>>(L::Partial(5, 3, 1).Slice<int32_t>(p)).data()));
   1381    EXPECT_EQ(
   1382        0, Distance(p, Type<Span<int8_t>>(L(5, 3, 1).Slice<int8_t>(p)).data()));
   1383    EXPECT_EQ(
   1384        24,
   1385        Distance(p, Type<Span<Int128>>(L(5, 3, 1).Slice<Int128>(p)).data()));
   1386    EXPECT_EQ(
   1387        8,
   1388        Distance(p, Type<Span<int32_t>>(L(5, 3, 1).Slice<int32_t>(p)).data()));
   1389  }
   1390 }
   1391 
   1392 TEST(Layout, StaticSliceData) {
   1393  alignas(max_align_t) const unsigned char cp[100] = {0};
   1394  alignas(max_align_t) unsigned char p[100] = {0};
   1395  using L = Layout<int8_t, int32_t, Int128>;
   1396  using SL = L::WithStaticSizes<3, 5>;
   1397 
   1398  EXPECT_EQ(0, Distance(cp, SL::Partial().Slice<0>(cp).data()));
   1399  EXPECT_EQ(0, Distance(cp, SL::Partial().Slice<int8_t>(cp).data()));
   1400  EXPECT_EQ(0, Distance(cp, SL::Partial(7).Slice<0>(cp).data()));
   1401  EXPECT_EQ(0, Distance(cp, SL::Partial(7).Slice<int8_t>(cp).data()));
   1402 
   1403  EXPECT_EQ(4, Distance(cp, SL::Partial().Slice<1>(cp).data()));
   1404  EXPECT_EQ(4, Distance(cp, SL::Partial().Slice<int32_t>(cp).data()));
   1405  EXPECT_EQ(4, Distance(cp, SL::Partial(7).Slice<1>(cp).data()));
   1406  EXPECT_EQ(4, Distance(cp, SL::Partial(7).Slice<int32_t>(cp).data()));
   1407 
   1408  EXPECT_EQ(24, Distance(cp, SL::Partial(7).Slice<2>(cp).data()));
   1409  EXPECT_EQ(24, Distance(cp, SL::Partial(7).Slice<Int128>(cp).data()));
   1410 
   1411  EXPECT_EQ(0, Distance(p, SL::Partial().Slice<0>(p).data()));
   1412  EXPECT_EQ(0, Distance(p, SL::Partial().Slice<int8_t>(p).data()));
   1413  EXPECT_EQ(0, Distance(p, SL::Partial(7).Slice<0>(p).data()));
   1414  EXPECT_EQ(0, Distance(p, SL::Partial(7).Slice<int8_t>(p).data()));
   1415 
   1416  EXPECT_EQ(4, Distance(p, SL::Partial().Slice<1>(p).data()));
   1417  EXPECT_EQ(4, Distance(p, SL::Partial().Slice<int32_t>(p).data()));
   1418  EXPECT_EQ(4, Distance(p, SL::Partial(7).Slice<1>(p).data()));
   1419  EXPECT_EQ(4, Distance(p, SL::Partial(7).Slice<int32_t>(p).data()));
   1420 
   1421  EXPECT_EQ(24, Distance(p, SL::Partial(7).Slice<2>(p).data()));
   1422  EXPECT_EQ(24, Distance(p, SL::Partial(7).Slice<Int128>(p).data()));
   1423 }
   1424 
   1425 MATCHER_P(IsSameSlice, slice, "") {
   1426  return arg.size() == slice.size() && arg.data() == slice.data();
   1427 }
   1428 
   1429 template <typename... M>
   1430 class TupleMatcher {
   1431 public:
   1432  explicit TupleMatcher(M... matchers) : matchers_(std::move(matchers)...) {}
   1433 
   1434  template <typename Tuple>
   1435  bool MatchAndExplain(const Tuple& p,
   1436                       testing::MatchResultListener* /* listener */) const {
   1437    static_assert(std::tuple_size<Tuple>::value == sizeof...(M), "");
   1438    return MatchAndExplainImpl(
   1439        p, absl::make_index_sequence<std::tuple_size<Tuple>::value>{});
   1440  }
   1441 
   1442  // For the matcher concept. Left empty as we don't really need the diagnostics
   1443  // right now.
   1444  void DescribeTo(::std::ostream* os) const {}
   1445  void DescribeNegationTo(::std::ostream* os) const {}
   1446 
   1447 private:
   1448  template <typename Tuple, size_t... Is>
   1449  bool MatchAndExplainImpl(const Tuple& p, absl::index_sequence<Is...>) const {
   1450    // Using std::min as a simple variadic "and".
   1451    return std::min(
   1452        {true, testing::SafeMatcherCast<
   1453                   const typename std::tuple_element<Is, Tuple>::type&>(
   1454                   std::get<Is>(matchers_))
   1455                   .Matches(std::get<Is>(p))...});
   1456  }
   1457 
   1458  std::tuple<M...> matchers_;
   1459 };
   1460 
   1461 template <typename... M>
   1462 testing::PolymorphicMatcher<TupleMatcher<M...>> Tuple(M... matchers) {
   1463  return testing::MakePolymorphicMatcher(
   1464      TupleMatcher<M...>(std::move(matchers)...));
   1465 }
   1466 
   1467 TEST(Layout, Slices) {
   1468  alignas(max_align_t) const unsigned char p[100] = {0};
   1469  using L = Layout<int8_t, int8_t, Int128>;
   1470  {
   1471    const auto x = L::Partial();
   1472    EXPECT_THAT(Type<std::tuple<>>(x.Slices(p)), Tuple());
   1473  }
   1474  {
   1475    const auto x = L::Partial(1);
   1476    EXPECT_THAT(Type<std::tuple<Span<const int8_t>>>(x.Slices(p)),
   1477                Tuple(IsSameSlice(x.Slice<0>(p))));
   1478  }
   1479  {
   1480    const auto x = L::Partial(1, 2);
   1481    EXPECT_THAT(
   1482        (Type<std::tuple<Span<const int8_t>, Span<const int8_t>>>(x.Slices(p))),
   1483        Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p))));
   1484  }
   1485  {
   1486    const auto x = L::Partial(1, 2, 3);
   1487    EXPECT_THAT((Type<std::tuple<Span<const int8_t>, Span<const int8_t>,
   1488                                 Span<const Int128>>>(x.Slices(p))),
   1489                Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)),
   1490                      IsSameSlice(x.Slice<2>(p))));
   1491  }
   1492  {
   1493    const L x(1, 2, 3);
   1494    EXPECT_THAT((Type<std::tuple<Span<const int8_t>, Span<const int8_t>,
   1495                                 Span<const Int128>>>(x.Slices(p))),
   1496                Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)),
   1497                      IsSameSlice(x.Slice<2>(p))));
   1498  }
   1499 }
   1500 
   1501 TEST(Layout, MutableSlices) {
   1502  alignas(max_align_t) unsigned char p[100] = {0};
   1503  using L = Layout<int8_t, int8_t, Int128>;
   1504  {
   1505    const auto x = L::Partial();
   1506    EXPECT_THAT(Type<std::tuple<>>(x.Slices(p)), Tuple());
   1507  }
   1508  {
   1509    const auto x = L::Partial(1);
   1510    EXPECT_THAT(Type<std::tuple<Span<int8_t>>>(x.Slices(p)),
   1511                Tuple(IsSameSlice(x.Slice<0>(p))));
   1512  }
   1513  {
   1514    const auto x = L::Partial(1, 2);
   1515    EXPECT_THAT((Type<std::tuple<Span<int8_t>, Span<int8_t>>>(x.Slices(p))),
   1516                Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p))));
   1517  }
   1518  {
   1519    const auto x = L::Partial(1, 2, 3);
   1520    EXPECT_THAT((Type<std::tuple<Span<int8_t>, Span<int8_t>, Span<Int128>>>(
   1521                    x.Slices(p))),
   1522                Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)),
   1523                      IsSameSlice(x.Slice<2>(p))));
   1524  }
   1525  {
   1526    const L x(1, 2, 3);
   1527    EXPECT_THAT((Type<std::tuple<Span<int8_t>, Span<int8_t>, Span<Int128>>>(
   1528                    x.Slices(p))),
   1529                Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)),
   1530                      IsSameSlice(x.Slice<2>(p))));
   1531  }
   1532 }
   1533 
   1534 TEST(Layout, StaticSlices) {
   1535  alignas(max_align_t) const unsigned char cp[100] = {0};
   1536  alignas(max_align_t) unsigned char p[100] = {0};
   1537  using SL = Layout<int8_t, int8_t, Int128>::WithStaticSizes<1, 2>;
   1538  {
   1539    const auto x = SL::Partial();
   1540    EXPECT_THAT(
   1541        (Type<std::tuple<Span<const int8_t>, Span<const int8_t>>>(
   1542            x.Slices(cp))),
   1543        Tuple(IsSameSlice(x.Slice<0>(cp)), IsSameSlice(x.Slice<1>(cp))));
   1544    EXPECT_THAT((Type<std::tuple<Span<int8_t>, Span<int8_t>>>(x.Slices(p))),
   1545                Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p))));
   1546  }
   1547  {
   1548    const auto x = SL::Partial(3);
   1549    EXPECT_THAT((Type<std::tuple<Span<const int8_t>, Span<const int8_t>,
   1550                                 Span<const Int128>>>(x.Slices(cp))),
   1551                Tuple(IsSameSlice(x.Slice<0>(cp)), IsSameSlice(x.Slice<1>(cp)),
   1552                      IsSameSlice(x.Slice<2>(cp))));
   1553    EXPECT_THAT((Type<std::tuple<Span<int8_t>, Span<int8_t>, Span<Int128>>>(
   1554                    x.Slices(p))),
   1555                Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)),
   1556                      IsSameSlice(x.Slice<2>(p))));
   1557  }
   1558  {
   1559    const SL x(3);
   1560    EXPECT_THAT((Type<std::tuple<Span<const int8_t>, Span<const int8_t>,
   1561                                 Span<const Int128>>>(x.Slices(cp))),
   1562                Tuple(IsSameSlice(x.Slice<0>(cp)), IsSameSlice(x.Slice<1>(cp)),
   1563                      IsSameSlice(x.Slice<2>(cp))));
   1564    EXPECT_THAT((Type<std::tuple<Span<int8_t>, Span<int8_t>, Span<Int128>>>(
   1565                    x.Slices(p))),
   1566                Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)),
   1567                      IsSameSlice(x.Slice<2>(p))));
   1568  }
   1569 }
   1570 
   1571 TEST(Layout, UnalignedTypes) {
   1572  constexpr Layout<unsigned char, unsigned char, unsigned char> x(1, 2, 3);
   1573  alignas(max_align_t) unsigned char p[x.AllocSize() + 1];
   1574  EXPECT_THAT(x.Pointers(p + 1), Tuple(p + 1, p + 2, p + 4));
   1575 }
   1576 
   1577 TEST(Layout, CustomAlignment) {
   1578  constexpr Layout<unsigned char, Aligned<unsigned char, 8>> x(1, 2);
   1579  alignas(max_align_t) unsigned char p[x.AllocSize()];
   1580  EXPECT_EQ(10, x.AllocSize());
   1581  EXPECT_THAT(x.Pointers(p), Tuple(p + 0, p + 8));
   1582 }
   1583 
   1584 TEST(Layout, OverAligned) {
   1585  constexpr size_t M = alignof(max_align_t);
   1586  constexpr Layout<unsigned char, Aligned<unsigned char, 2 * M>> x(1, 3);
   1587 #ifdef __GNUC__
   1588  // Using __attribute__ ((aligned ())) instead of alignas to bypass a gcc bug:
   1589  // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89357
   1590  __attribute__((aligned(2 * M))) unsigned char p[x.AllocSize()];
   1591 #else
   1592  alignas(2 * M) unsigned char p[x.AllocSize()];
   1593 #endif
   1594  EXPECT_EQ(2 * M + 3, x.AllocSize());
   1595  EXPECT_THAT(x.Pointers(p), Tuple(p + 0, p + 2 * M));
   1596 }
   1597 
   1598 TEST(Layout, Alignment) {
   1599  static_assert(Layout<int8_t>::Alignment() == 1, "");
   1600  static_assert(Layout<int32_t>::Alignment() == 4, "");
   1601  static_assert(Layout<Int64>::Alignment() == 8, "");
   1602  static_assert(Layout<Aligned<int8_t, 64>>::Alignment() == 64, "");
   1603  static_assert(Layout<int8_t, int32_t, Int64>::Alignment() == 8, "");
   1604  static_assert(Layout<int8_t, Int64, int32_t>::Alignment() == 8, "");
   1605  static_assert(Layout<int32_t, int8_t, Int64>::Alignment() == 8, "");
   1606  static_assert(Layout<int32_t, Int64, int8_t>::Alignment() == 8, "");
   1607  static_assert(Layout<Int64, int8_t, int32_t>::Alignment() == 8, "");
   1608  static_assert(Layout<Int64, int32_t, int8_t>::Alignment() == 8, "");
   1609  static_assert(Layout<Int64, int32_t, int8_t>::Alignment() == 8, "");
   1610  static_assert(
   1611      Layout<Aligned<int8_t, 64>>::WithStaticSizes<>::Alignment() == 64, "");
   1612  static_assert(
   1613      Layout<Aligned<int8_t, 64>>::WithStaticSizes<2>::Alignment() == 64, "");
   1614 }
   1615 
   1616 TEST(Layout, StaticAlignment) {
   1617  static_assert(Layout<int8_t>::WithStaticSizes<>::Alignment() == 1, "");
   1618  static_assert(Layout<int8_t>::WithStaticSizes<0>::Alignment() == 1, "");
   1619  static_assert(Layout<int8_t>::WithStaticSizes<7>::Alignment() == 1, "");
   1620  static_assert(Layout<int32_t>::WithStaticSizes<>::Alignment() == 4, "");
   1621  static_assert(Layout<int32_t>::WithStaticSizes<0>::Alignment() == 4, "");
   1622  static_assert(Layout<int32_t>::WithStaticSizes<3>::Alignment() == 4, "");
   1623  static_assert(
   1624      Layout<Aligned<int8_t, 64>>::WithStaticSizes<>::Alignment() == 64, "");
   1625  static_assert(
   1626      Layout<Aligned<int8_t, 64>>::WithStaticSizes<0>::Alignment() == 64, "");
   1627  static_assert(
   1628      Layout<Aligned<int8_t, 64>>::WithStaticSizes<2>::Alignment() == 64, "");
   1629  static_assert(
   1630      Layout<int32_t, Int64, int8_t>::WithStaticSizes<>::Alignment() == 8, "");
   1631  static_assert(
   1632      Layout<int32_t, Int64, int8_t>::WithStaticSizes<0, 0, 0>::Alignment() ==
   1633          8,
   1634      "");
   1635  static_assert(
   1636      Layout<int32_t, Int64, int8_t>::WithStaticSizes<1, 1, 1>::Alignment() ==
   1637          8,
   1638      "");
   1639 }
   1640 
   1641 TEST(Layout, ConstexprPartial) {
   1642  constexpr size_t M = alignof(max_align_t);
   1643  constexpr Layout<unsigned char, Aligned<unsigned char, 2 * M>> x(1, 3);
   1644  static_assert(x.Partial(1).template Offset<1>() == 2 * M, "");
   1645 }
   1646 
   1647 TEST(Layout, StaticConstexpr) {
   1648  constexpr size_t M = alignof(max_align_t);
   1649  using L = Layout<unsigned char, Aligned<unsigned char, 2 * M>>;
   1650  using SL = L::WithStaticSizes<1, 3>;
   1651  constexpr SL x;
   1652  static_assert(x.Offset<1>() == 2 * M, "");
   1653 }
   1654 
   1655 // [from, to)
   1656 struct Region {
   1657  size_t from;
   1658  size_t to;
   1659 };
   1660 
   1661 void ExpectRegionPoisoned(const unsigned char* p, size_t n, bool poisoned) {
   1662 #ifdef ABSL_HAVE_ADDRESS_SANITIZER
   1663  for (size_t i = 0; i != n; ++i) {
   1664    EXPECT_EQ(poisoned, __asan_address_is_poisoned(p + i));
   1665  }
   1666 #endif
   1667 }
   1668 
   1669 template <size_t N>
   1670 void ExpectPoisoned(const unsigned char (&buf)[N],
   1671                    std::initializer_list<Region> reg) {
   1672  size_t prev = 0;
   1673  for (const Region& r : reg) {
   1674    ExpectRegionPoisoned(buf + prev, r.from - prev, false);
   1675    ExpectRegionPoisoned(buf + r.from, r.to - r.from, true);
   1676    prev = r.to;
   1677  }
   1678  ExpectRegionPoisoned(buf + prev, N - prev, false);
   1679 }
   1680 
   1681 TEST(Layout, PoisonPadding) {
   1682  using L = Layout<int8_t, Int64, int32_t, Int128>;
   1683 
   1684  constexpr size_t n = L::Partial(1, 2, 3, 4).AllocSize();
   1685  {
   1686    constexpr auto x = L::Partial();
   1687    alignas(max_align_t) const unsigned char c[n] = {};
   1688    x.PoisonPadding(c);
   1689    EXPECT_EQ(x.Slices(c), x.Slices(c));
   1690    ExpectPoisoned(c, {});
   1691  }
   1692  {
   1693    constexpr auto x = L::Partial(1);
   1694    alignas(max_align_t) const unsigned char c[n] = {};
   1695    x.PoisonPadding(c);
   1696    EXPECT_EQ(x.Slices(c), x.Slices(c));
   1697    ExpectPoisoned(c, {{1, 8}});
   1698  }
   1699  {
   1700    constexpr auto x = L::Partial(1, 2);
   1701    alignas(max_align_t) const unsigned char c[n] = {};
   1702    x.PoisonPadding(c);
   1703    EXPECT_EQ(x.Slices(c), x.Slices(c));
   1704    ExpectPoisoned(c, {{1, 8}});
   1705  }
   1706  {
   1707    constexpr auto x = L::Partial(1, 2, 3);
   1708    alignas(max_align_t) const unsigned char c[n] = {};
   1709    x.PoisonPadding(c);
   1710    EXPECT_EQ(x.Slices(c), x.Slices(c));
   1711    ExpectPoisoned(c, {{1, 8}, {36, 40}});
   1712  }
   1713  {
   1714    constexpr auto x = L::Partial(1, 2, 3, 4);
   1715    alignas(max_align_t) const unsigned char c[n] = {};
   1716    x.PoisonPadding(c);
   1717    EXPECT_EQ(x.Slices(c), x.Slices(c));
   1718    ExpectPoisoned(c, {{1, 8}, {36, 40}});
   1719  }
   1720  {
   1721    constexpr L x(1, 2, 3, 4);
   1722    alignas(max_align_t) const unsigned char c[n] = {};
   1723    x.PoisonPadding(c);
   1724    EXPECT_EQ(x.Slices(c), x.Slices(c));
   1725    ExpectPoisoned(c, {{1, 8}, {36, 40}});
   1726  }
   1727 }
   1728 
   1729 TEST(Layout, StaticPoisonPadding) {
   1730  using L = Layout<int8_t, Int64, int32_t, Int128>;
   1731  using SL = L::WithStaticSizes<1, 2>;
   1732 
   1733  constexpr size_t n = L::Partial(1, 2, 3, 4).AllocSize();
   1734  {
   1735    constexpr auto x = SL::Partial();
   1736    alignas(max_align_t) const unsigned char c[n] = {};
   1737    x.PoisonPadding(c);
   1738    EXPECT_EQ(x.Slices(c), x.Slices(c));
   1739    ExpectPoisoned(c, {{1, 8}});
   1740  }
   1741  {
   1742    constexpr auto x = SL::Partial(3);
   1743    alignas(max_align_t) const unsigned char c[n] = {};
   1744    x.PoisonPadding(c);
   1745    EXPECT_EQ(x.Slices(c), x.Slices(c));
   1746    ExpectPoisoned(c, {{1, 8}, {36, 40}});
   1747  }
   1748  {
   1749    constexpr auto x = SL::Partial(3, 4);
   1750    alignas(max_align_t) const unsigned char c[n] = {};
   1751    x.PoisonPadding(c);
   1752    EXPECT_EQ(x.Slices(c), x.Slices(c));
   1753    ExpectPoisoned(c, {{1, 8}, {36, 40}});
   1754  }
   1755  {
   1756    constexpr SL x(3, 4);
   1757    alignas(max_align_t) const unsigned char c[n] = {};
   1758    x.PoisonPadding(c);
   1759    EXPECT_EQ(x.Slices(c), x.Slices(c));
   1760    ExpectPoisoned(c, {{1, 8}, {36, 40}});
   1761  }
   1762 }
   1763 
   1764 TEST(Layout, DebugString) {
   1765  {
   1766    constexpr auto x = Layout<int8_t, int32_t, int8_t, Int128>::Partial();
   1767    EXPECT_EQ("@0<signed char>(1)", x.DebugString());
   1768  }
   1769  {
   1770    constexpr auto x = Layout<int8_t, int32_t, int8_t, Int128>::Partial(1);
   1771    EXPECT_EQ("@0<signed char>(1)[1]; @4<int>(4)", x.DebugString());
   1772  }
   1773  {
   1774    constexpr auto x = Layout<int8_t, int32_t, int8_t, Int128>::Partial(1, 2);
   1775    EXPECT_EQ("@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)",
   1776              x.DebugString());
   1777  }
   1778  {
   1779    constexpr auto x =
   1780        Layout<int8_t, int32_t, int8_t, Int128>::Partial(1, 2, 3);
   1781    EXPECT_EQ(
   1782        "@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)[3]; "
   1783        "@16" +
   1784            Int128::Name() + "(16)",
   1785        x.DebugString());
   1786  }
   1787  {
   1788    constexpr auto x =
   1789        Layout<int8_t, int32_t, int8_t, Int128>::Partial(1, 2, 3, 4);
   1790    EXPECT_EQ(
   1791        "@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)[3]; "
   1792        "@16" +
   1793            Int128::Name() + "(16)[4]",
   1794        x.DebugString());
   1795  }
   1796  {
   1797    constexpr Layout<int8_t, int32_t, int8_t, Int128> x(1, 2, 3, 4);
   1798    EXPECT_EQ(
   1799        "@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)[3]; "
   1800        "@16" +
   1801            Int128::Name() + "(16)[4]",
   1802        x.DebugString());
   1803  }
   1804 }
   1805 
   1806 TEST(Layout, StaticDebugString) {
   1807  {
   1808    constexpr auto x =
   1809        Layout<int8_t, int32_t, int8_t, Int128>::WithStaticSizes<>::Partial();
   1810    EXPECT_EQ("@0<signed char>(1)", x.DebugString());
   1811  }
   1812  {
   1813    constexpr auto x =
   1814        Layout<int8_t, int32_t, int8_t, Int128>::WithStaticSizes<>::Partial(1);
   1815    EXPECT_EQ("@0<signed char>(1)[1]; @4<int>(4)", x.DebugString());
   1816  }
   1817  {
   1818    constexpr auto x =
   1819        Layout<int8_t, int32_t, int8_t, Int128>::WithStaticSizes<1>::Partial();
   1820    EXPECT_EQ("@0<signed char>(1)[1]; @4<int>(4)", x.DebugString());
   1821  }
   1822  {
   1823    constexpr auto x =
   1824        Layout<int8_t, int32_t, int8_t, Int128>::WithStaticSizes<>::Partial(1,
   1825                                                                            2);
   1826    EXPECT_EQ("@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)",
   1827              x.DebugString());
   1828  }
   1829  {
   1830    constexpr auto x =
   1831        Layout<int8_t, int32_t, int8_t, Int128>::WithStaticSizes<1>::Partial(2);
   1832    EXPECT_EQ("@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)",
   1833              x.DebugString());
   1834  }
   1835  {
   1836    constexpr auto x = Layout<int8_t, int32_t, int8_t,
   1837                              Int128>::WithStaticSizes<1, 2>::Partial();
   1838    EXPECT_EQ("@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)",
   1839              x.DebugString());
   1840  }
   1841  {
   1842    constexpr auto x = Layout<int8_t, int32_t, int8_t,
   1843                              Int128>::WithStaticSizes<1, 2, 3, 4>::Partial();
   1844    EXPECT_EQ(
   1845        "@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)[3]; "
   1846        "@16" +
   1847            Int128::Name() + "(16)[4]",
   1848        x.DebugString());
   1849  }
   1850  {
   1851    constexpr Layout<int8_t, int32_t, int8_t, Int128>::WithStaticSizes<1, 2, 3,
   1852                                                                       4>
   1853        x;
   1854    EXPECT_EQ(
   1855        "@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)[3]; "
   1856        "@16" +
   1857            Int128::Name() + "(16)[4]",
   1858        x.DebugString());
   1859  }
   1860 }
   1861 
   1862 TEST(Layout, CharTypes) {
   1863  constexpr Layout<int32_t> x(1);
   1864  alignas(max_align_t) char c[x.AllocSize()] = {};
   1865  alignas(max_align_t) unsigned char uc[x.AllocSize()] = {};
   1866  alignas(max_align_t) signed char sc[x.AllocSize()] = {};
   1867  alignas(max_align_t) const char cc[x.AllocSize()] = {};
   1868  alignas(max_align_t) const unsigned char cuc[x.AllocSize()] = {};
   1869  alignas(max_align_t) const signed char csc[x.AllocSize()] = {};
   1870 
   1871  Type<int32_t*>(x.Pointer<0>(c));
   1872  Type<int32_t*>(x.Pointer<0>(uc));
   1873  Type<int32_t*>(x.Pointer<0>(sc));
   1874  Type<const int32_t*>(x.Pointer<0>(cc));
   1875  Type<const int32_t*>(x.Pointer<0>(cuc));
   1876  Type<const int32_t*>(x.Pointer<0>(csc));
   1877 
   1878  Type<int32_t*>(x.Pointer<int32_t>(c));
   1879  Type<int32_t*>(x.Pointer<int32_t>(uc));
   1880  Type<int32_t*>(x.Pointer<int32_t>(sc));
   1881  Type<const int32_t*>(x.Pointer<int32_t>(cc));
   1882  Type<const int32_t*>(x.Pointer<int32_t>(cuc));
   1883  Type<const int32_t*>(x.Pointer<int32_t>(csc));
   1884 
   1885  Type<std::tuple<int32_t*>>(x.Pointers(c));
   1886  Type<std::tuple<int32_t*>>(x.Pointers(uc));
   1887  Type<std::tuple<int32_t*>>(x.Pointers(sc));
   1888  Type<std::tuple<const int32_t*>>(x.Pointers(cc));
   1889  Type<std::tuple<const int32_t*>>(x.Pointers(cuc));
   1890  Type<std::tuple<const int32_t*>>(x.Pointers(csc));
   1891 
   1892  Type<Span<int32_t>>(x.Slice<0>(c));
   1893  Type<Span<int32_t>>(x.Slice<0>(uc));
   1894  Type<Span<int32_t>>(x.Slice<0>(sc));
   1895  Type<Span<const int32_t>>(x.Slice<0>(cc));
   1896  Type<Span<const int32_t>>(x.Slice<0>(cuc));
   1897  Type<Span<const int32_t>>(x.Slice<0>(csc));
   1898 
   1899  Type<std::tuple<Span<int32_t>>>(x.Slices(c));
   1900  Type<std::tuple<Span<int32_t>>>(x.Slices(uc));
   1901  Type<std::tuple<Span<int32_t>>>(x.Slices(sc));
   1902  Type<std::tuple<Span<const int32_t>>>(x.Slices(cc));
   1903  Type<std::tuple<Span<const int32_t>>>(x.Slices(cuc));
   1904  Type<std::tuple<Span<const int32_t>>>(x.Slices(csc));
   1905 }
   1906 
   1907 TEST(Layout, ConstElementType) {
   1908  constexpr Layout<const int32_t> x(1);
   1909  alignas(int32_t) char c[x.AllocSize()] = {};
   1910  const char* cc = c;
   1911  const int32_t* p = reinterpret_cast<const int32_t*>(cc);
   1912 
   1913  EXPECT_EQ(alignof(int32_t), x.Alignment());
   1914 
   1915  EXPECT_EQ(0, x.Offset<0>());
   1916  EXPECT_EQ(0, x.Offset<const int32_t>());
   1917 
   1918  EXPECT_THAT(x.Offsets(), ElementsAre(0));
   1919 
   1920  EXPECT_EQ(1, x.Size<0>());
   1921  EXPECT_EQ(1, x.Size<const int32_t>());
   1922 
   1923  EXPECT_THAT(x.Sizes(), ElementsAre(1));
   1924 
   1925  EXPECT_EQ(sizeof(int32_t), x.AllocSize());
   1926 
   1927  EXPECT_EQ(p, Type<const int32_t*>(x.Pointer<0>(c)));
   1928  EXPECT_EQ(p, Type<const int32_t*>(x.Pointer<0>(cc)));
   1929 
   1930  EXPECT_EQ(p, Type<const int32_t*>(x.Pointer<const int32_t>(c)));
   1931  EXPECT_EQ(p, Type<const int32_t*>(x.Pointer<const int32_t>(cc)));
   1932 
   1933  EXPECT_THAT(Type<std::tuple<const int32_t*>>(x.Pointers(c)), Tuple(p));
   1934  EXPECT_THAT(Type<std::tuple<const int32_t*>>(x.Pointers(cc)), Tuple(p));
   1935 
   1936  EXPECT_THAT(Type<Span<const int32_t>>(x.Slice<0>(c)),
   1937              IsSameSlice(Span<const int32_t>(p, 1)));
   1938  EXPECT_THAT(Type<Span<const int32_t>>(x.Slice<0>(cc)),
   1939              IsSameSlice(Span<const int32_t>(p, 1)));
   1940 
   1941  EXPECT_THAT(Type<Span<const int32_t>>(x.Slice<const int32_t>(c)),
   1942              IsSameSlice(Span<const int32_t>(p, 1)));
   1943  EXPECT_THAT(Type<Span<const int32_t>>(x.Slice<const int32_t>(cc)),
   1944              IsSameSlice(Span<const int32_t>(p, 1)));
   1945 
   1946  EXPECT_THAT(Type<std::tuple<Span<const int32_t>>>(x.Slices(c)),
   1947              Tuple(IsSameSlice(Span<const int32_t>(p, 1))));
   1948  EXPECT_THAT(Type<std::tuple<Span<const int32_t>>>(x.Slices(cc)),
   1949              Tuple(IsSameSlice(Span<const int32_t>(p, 1))));
   1950 }
   1951 
   1952 namespace example {
   1953 
   1954 // Immutable move-only string with sizeof equal to sizeof(void*). The string
   1955 // size and the characters are kept in the same heap allocation.
   1956 class CompactString {
   1957 public:
   1958  CompactString(const char* s = "") {  // NOLINT
   1959    const size_t size = strlen(s);
   1960    // size_t[1], followed by char[size + 1].
   1961    // This statement doesn't allocate memory.
   1962    const L layout(1, size + 1);
   1963    // AllocSize() tells us how much memory we need to allocate for all our
   1964    // data.
   1965    p_.reset(new unsigned char[layout.AllocSize()]);
   1966    // If running under ASAN, mark the padding bytes, if any, to catch memory
   1967    // errors.
   1968    layout.PoisonPadding(p_.get());
   1969    // Store the size in the allocation.
   1970    // Pointer<size_t>() is a synonym for Pointer<0>().
   1971    *layout.Pointer<size_t>(p_.get()) = size;
   1972    // Store the characters in the allocation.
   1973    memcpy(layout.Pointer<char>(p_.get()), s, size + 1);
   1974  }
   1975 
   1976  size_t size() const {
   1977    // Equivalent to reinterpret_cast<size_t&>(*p).
   1978    return *L::Partial().Pointer<size_t>(p_.get());
   1979  }
   1980 
   1981  const char* c_str() const {
   1982    // Equivalent to reinterpret_cast<char*>(p.get() + sizeof(size_t)).
   1983    // The argument in Partial(1) specifies that we have size_t[1] in front of
   1984    // the characters.
   1985    return L::Partial(1).Pointer<char>(p_.get());
   1986  }
   1987 
   1988 private:
   1989  // Our heap allocation contains a size_t followed by an array of chars.
   1990  using L = Layout<size_t, char>;
   1991  std::unique_ptr<unsigned char[]> p_;
   1992 };
   1993 
   1994 TEST(CompactString, Works) {
   1995  CompactString s = "hello";
   1996  EXPECT_EQ(5, s.size());
   1997  EXPECT_STREQ("hello", s.c_str());
   1998 }
   1999 
   2000 // Same as the previous CompactString example, except we set the first array
   2001 // size to 1 statically, since we know it is always 1. This allows us to compute
   2002 // the offset of the character array at compile time.
   2003 class StaticCompactString {
   2004 public:
   2005  StaticCompactString(const char* s = "") {  // NOLINT
   2006    const size_t size = strlen(s);
   2007    const SL layout(size + 1);
   2008    p_.reset(new unsigned char[layout.AllocSize()]);
   2009    layout.PoisonPadding(p_.get());
   2010    *layout.Pointer<size_t>(p_.get()) = size;
   2011    memcpy(layout.Pointer<char>(p_.get()), s, size + 1);
   2012  }
   2013 
   2014  size_t size() const { return *SL::Partial().Pointer<size_t>(p_.get()); }
   2015 
   2016  const char* c_str() const { return SL::Partial().Pointer<char>(p_.get()); }
   2017 
   2018 private:
   2019  using SL = Layout<size_t, char>::WithStaticSizes<1>;
   2020  std::unique_ptr<unsigned char[]> p_;
   2021 };
   2022 
   2023 TEST(StaticCompactString, Works) {
   2024  StaticCompactString s = "hello";
   2025  EXPECT_EQ(5, s.size());
   2026  EXPECT_STREQ("hello", s.c_str());
   2027 }
   2028 
   2029 }  // namespace example
   2030 
   2031 }  // namespace
   2032 }  // namespace container_internal
   2033 ABSL_NAMESPACE_END
   2034 }  // namespace absl