diff options
author | Vincent Ambo <mail@tazj.in> | 2022-02-07T23·05+0300 |
---|---|---|
committer | clbot <clbot@tvl.fyi> | 2022-02-07T23·09+0000 |
commit | 5aa5d282eac56a21e74611c1cdbaa97bb5db2dca (patch) | |
tree | 8cc5dce8157a1470ff76719dd15d65f648a05522 /third_party/abseil_cpp/absl/container/internal/layout_test.cc | |
parent | a25675804c4f429fab5ee5201fe25e89865dfd13 (diff) |
chore(3p/abseil_cpp): unvendor abseil_cpp r/3786
we weren't actually using these sources anymore, okay? Change-Id: If701571d9716de308d3512e1eb22c35db0877a66 Reviewed-on: https://cl.tvl.fyi/c/depot/+/5248 Tested-by: BuildkiteCI Reviewed-by: grfn <grfn@gws.fyi> Autosubmit: tazjin <tazjin@tvl.su>
Diffstat (limited to 'third_party/abseil_cpp/absl/container/internal/layout_test.cc')
-rw-r--r-- | third_party/abseil_cpp/absl/container/internal/layout_test.cc | 1635 |
1 files changed, 0 insertions, 1635 deletions
diff --git a/third_party/abseil_cpp/absl/container/internal/layout_test.cc b/third_party/abseil_cpp/absl/container/internal/layout_test.cc deleted file mode 100644 index 1d7158ffc0b9..000000000000 --- a/third_party/abseil_cpp/absl/container/internal/layout_test.cc +++ /dev/null @@ -1,1635 +0,0 @@ -// Copyright 2018 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "absl/container/internal/layout.h" - -// We need ::max_align_t because some libstdc++ versions don't provide -// std::max_align_t -#include <stddef.h> - -#include <cstdint> -#include <memory> -#include <sstream> -#include <type_traits> - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "absl/base/config.h" -#include "absl/base/internal/raw_logging.h" -#include "absl/types/span.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace container_internal { -namespace { - -using ::absl::Span; -using ::testing::ElementsAre; - -size_t Distance(const void* from, const void* to) { - ABSL_RAW_CHECK(from <= to, "Distance must be non-negative"); - return static_cast<const char*>(to) - static_cast<const char*>(from); -} - -template <class Expected, class Actual> -Expected Type(Actual val) { - static_assert(std::is_same<Expected, Actual>(), ""); - return val; -} - -// Helper classes to test different size and alignments. -struct alignas(8) Int128 { - uint64_t a, b; - friend bool operator==(Int128 lhs, Int128 rhs) { - return std::tie(lhs.a, lhs.b) == std::tie(rhs.a, rhs.b); - } - - static std::string Name() { - return internal_layout::adl_barrier::TypeName<Int128>(); - } -}; - -// int64_t is *not* 8-byte aligned on all platforms! -struct alignas(8) Int64 { - int64_t a; - friend bool operator==(Int64 lhs, Int64 rhs) { - return lhs.a == rhs.a; - } -}; - -// Properties of types that this test relies on. -static_assert(sizeof(int8_t) == 1, ""); -static_assert(alignof(int8_t) == 1, ""); -static_assert(sizeof(int16_t) == 2, ""); -static_assert(alignof(int16_t) == 2, ""); -static_assert(sizeof(int32_t) == 4, ""); -static_assert(alignof(int32_t) == 4, ""); -static_assert(sizeof(Int64) == 8, ""); -static_assert(alignof(Int64) == 8, ""); -static_assert(sizeof(Int128) == 16, ""); -static_assert(alignof(Int128) == 8, ""); - -template <class Expected, class Actual> -void SameType() { - static_assert(std::is_same<Expected, Actual>(), ""); -} - -TEST(Layout, ElementType) { - { - using L = Layout<int32_t>; - SameType<int32_t, L::ElementType<0>>(); - SameType<int32_t, decltype(L::Partial())::ElementType<0>>(); - SameType<int32_t, decltype(L::Partial(0))::ElementType<0>>(); - } - { - using L = Layout<int32_t, int32_t>; - SameType<int32_t, L::ElementType<0>>(); - SameType<int32_t, L::ElementType<1>>(); - SameType<int32_t, decltype(L::Partial())::ElementType<0>>(); - SameType<int32_t, decltype(L::Partial())::ElementType<1>>(); - SameType<int32_t, decltype(L::Partial(0))::ElementType<0>>(); - SameType<int32_t, decltype(L::Partial(0))::ElementType<1>>(); - } - { - using L = Layout<int8_t, int32_t, Int128>; - SameType<int8_t, L::ElementType<0>>(); - SameType<int32_t, L::ElementType<1>>(); - SameType<Int128, L::ElementType<2>>(); - SameType<int8_t, decltype(L::Partial())::ElementType<0>>(); - SameType<int8_t, decltype(L::Partial(0))::ElementType<0>>(); - SameType<int32_t, decltype(L::Partial(0))::ElementType<1>>(); - SameType<int8_t, decltype(L::Partial(0, 0))::ElementType<0>>(); - SameType<int32_t, decltype(L::Partial(0, 0))::ElementType<1>>(); - SameType<Int128, decltype(L::Partial(0, 0))::ElementType<2>>(); - SameType<int8_t, decltype(L::Partial(0, 0, 0))::ElementType<0>>(); - SameType<int32_t, decltype(L::Partial(0, 0, 0))::ElementType<1>>(); - SameType<Int128, decltype(L::Partial(0, 0, 0))::ElementType<2>>(); - } -} - -TEST(Layout, ElementTypes) { - { - using L = Layout<int32_t>; - SameType<std::tuple<int32_t>, L::ElementTypes>(); - SameType<std::tuple<int32_t>, decltype(L::Partial())::ElementTypes>(); - SameType<std::tuple<int32_t>, decltype(L::Partial(0))::ElementTypes>(); - } - { - using L = Layout<int32_t, int32_t>; - SameType<std::tuple<int32_t, int32_t>, L::ElementTypes>(); - SameType<std::tuple<int32_t, int32_t>, - decltype(L::Partial())::ElementTypes>(); - SameType<std::tuple<int32_t, int32_t>, - decltype(L::Partial(0))::ElementTypes>(); - } - { - using L = Layout<int8_t, int32_t, Int128>; - SameType<std::tuple<int8_t, int32_t, Int128>, L::ElementTypes>(); - SameType<std::tuple<int8_t, int32_t, Int128>, - decltype(L::Partial())::ElementTypes>(); - SameType<std::tuple<int8_t, int32_t, Int128>, - decltype(L::Partial(0))::ElementTypes>(); - SameType<std::tuple<int8_t, int32_t, Int128>, - decltype(L::Partial(0, 0))::ElementTypes>(); - SameType<std::tuple<int8_t, int32_t, Int128>, - decltype(L::Partial(0, 0, 0))::ElementTypes>(); - } -} - -TEST(Layout, OffsetByIndex) { - { - using L = Layout<int32_t>; - EXPECT_EQ(0, L::Partial().Offset<0>()); - EXPECT_EQ(0, L::Partial(3).Offset<0>()); - EXPECT_EQ(0, L(3).Offset<0>()); - } - { - using L = Layout<int32_t, int32_t>; - EXPECT_EQ(0, L::Partial().Offset<0>()); - EXPECT_EQ(0, L::Partial(3).Offset<0>()); - EXPECT_EQ(12, L::Partial(3).Offset<1>()); - EXPECT_EQ(0, L::Partial(3, 5).Offset<0>()); - EXPECT_EQ(12, L::Partial(3, 5).Offset<1>()); - EXPECT_EQ(0, L(3, 5).Offset<0>()); - EXPECT_EQ(12, L(3, 5).Offset<1>()); - } - { - using L = Layout<int8_t, int32_t, Int128>; - EXPECT_EQ(0, L::Partial().Offset<0>()); - EXPECT_EQ(0, L::Partial(0).Offset<0>()); - EXPECT_EQ(0, L::Partial(0).Offset<1>()); - EXPECT_EQ(0, L::Partial(1).Offset<0>()); - EXPECT_EQ(4, L::Partial(1).Offset<1>()); - EXPECT_EQ(0, L::Partial(5).Offset<0>()); - EXPECT_EQ(8, L::Partial(5).Offset<1>()); - EXPECT_EQ(0, L::Partial(0, 0).Offset<0>()); - EXPECT_EQ(0, L::Partial(0, 0).Offset<1>()); - EXPECT_EQ(0, L::Partial(0, 0).Offset<2>()); - EXPECT_EQ(0, L::Partial(1, 0).Offset<0>()); - EXPECT_EQ(4, L::Partial(1, 0).Offset<1>()); - EXPECT_EQ(8, L::Partial(1, 0).Offset<2>()); - EXPECT_EQ(0, L::Partial(5, 3).Offset<0>()); - EXPECT_EQ(8, L::Partial(5, 3).Offset<1>()); - EXPECT_EQ(24, L::Partial(5, 3).Offset<2>()); - EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<0>()); - EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<1>()); - EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<2>()); - EXPECT_EQ(0, L::Partial(1, 0, 0).Offset<0>()); - EXPECT_EQ(4, L::Partial(1, 0, 0).Offset<1>()); - EXPECT_EQ(8, L::Partial(1, 0, 0).Offset<2>()); - EXPECT_EQ(0, L::Partial(5, 3, 1).Offset<0>()); - EXPECT_EQ(24, L::Partial(5, 3, 1).Offset<2>()); - EXPECT_EQ(8, L::Partial(5, 3, 1).Offset<1>()); - EXPECT_EQ(0, L(5, 3, 1).Offset<0>()); - EXPECT_EQ(24, L(5, 3, 1).Offset<2>()); - EXPECT_EQ(8, L(5, 3, 1).Offset<1>()); - } -} - -TEST(Layout, OffsetByType) { - { - using L = Layout<int32_t>; - EXPECT_EQ(0, L::Partial().Offset<int32_t>()); - EXPECT_EQ(0, L::Partial(3).Offset<int32_t>()); - EXPECT_EQ(0, L(3).Offset<int32_t>()); - } - { - using L = Layout<int8_t, int32_t, Int128>; - EXPECT_EQ(0, L::Partial().Offset<int8_t>()); - EXPECT_EQ(0, L::Partial(0).Offset<int8_t>()); - EXPECT_EQ(0, L::Partial(0).Offset<int32_t>()); - EXPECT_EQ(0, L::Partial(1).Offset<int8_t>()); - EXPECT_EQ(4, L::Partial(1).Offset<int32_t>()); - EXPECT_EQ(0, L::Partial(5).Offset<int8_t>()); - EXPECT_EQ(8, L::Partial(5).Offset<int32_t>()); - EXPECT_EQ(0, L::Partial(0, 0).Offset<int8_t>()); - EXPECT_EQ(0, L::Partial(0, 0).Offset<int32_t>()); - EXPECT_EQ(0, L::Partial(0, 0).Offset<Int128>()); - EXPECT_EQ(0, L::Partial(1, 0).Offset<int8_t>()); - EXPECT_EQ(4, L::Partial(1, 0).Offset<int32_t>()); - EXPECT_EQ(8, L::Partial(1, 0).Offset<Int128>()); - EXPECT_EQ(0, L::Partial(5, 3).Offset<int8_t>()); - EXPECT_EQ(8, L::Partial(5, 3).Offset<int32_t>()); - EXPECT_EQ(24, L::Partial(5, 3).Offset<Int128>()); - EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<int8_t>()); - EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<int32_t>()); - EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<Int128>()); - EXPECT_EQ(0, L::Partial(1, 0, 0).Offset<int8_t>()); - EXPECT_EQ(4, L::Partial(1, 0, 0).Offset<int32_t>()); - EXPECT_EQ(8, L::Partial(1, 0, 0).Offset<Int128>()); - EXPECT_EQ(0, L::Partial(5, 3, 1).Offset<int8_t>()); - EXPECT_EQ(24, L::Partial(5, 3, 1).Offset<Int128>()); - EXPECT_EQ(8, L::Partial(5, 3, 1).Offset<int32_t>()); - EXPECT_EQ(0, L(5, 3, 1).Offset<int8_t>()); - EXPECT_EQ(24, L(5, 3, 1).Offset<Int128>()); - EXPECT_EQ(8, L(5, 3, 1).Offset<int32_t>()); - } -} - -TEST(Layout, Offsets) { - { - using L = Layout<int32_t>; - EXPECT_THAT(L::Partial().Offsets(), ElementsAre(0)); - EXPECT_THAT(L::Partial(3).Offsets(), ElementsAre(0)); - EXPECT_THAT(L(3).Offsets(), ElementsAre(0)); - } - { - using L = Layout<int32_t, int32_t>; - EXPECT_THAT(L::Partial().Offsets(), ElementsAre(0)); - EXPECT_THAT(L::Partial(3).Offsets(), ElementsAre(0, 12)); - EXPECT_THAT(L::Partial(3, 5).Offsets(), ElementsAre(0, 12)); - EXPECT_THAT(L(3, 5).Offsets(), ElementsAre(0, 12)); - } - { - using L = Layout<int8_t, int32_t, Int128>; - EXPECT_THAT(L::Partial().Offsets(), ElementsAre(0)); - EXPECT_THAT(L::Partial(1).Offsets(), ElementsAre(0, 4)); - EXPECT_THAT(L::Partial(5).Offsets(), ElementsAre(0, 8)); - EXPECT_THAT(L::Partial(0, 0).Offsets(), ElementsAre(0, 0, 0)); - EXPECT_THAT(L::Partial(1, 0).Offsets(), ElementsAre(0, 4, 8)); - EXPECT_THAT(L::Partial(5, 3).Offsets(), ElementsAre(0, 8, 24)); - EXPECT_THAT(L::Partial(0, 0, 0).Offsets(), ElementsAre(0, 0, 0)); - EXPECT_THAT(L::Partial(1, 0, 0).Offsets(), ElementsAre(0, 4, 8)); - EXPECT_THAT(L::Partial(5, 3, 1).Offsets(), ElementsAre(0, 8, 24)); - EXPECT_THAT(L(5, 3, 1).Offsets(), ElementsAre(0, 8, 24)); - } -} - -TEST(Layout, AllocSize) { - { - using L = Layout<int32_t>; - EXPECT_EQ(0, L::Partial(0).AllocSize()); - EXPECT_EQ(12, L::Partial(3).AllocSize()); - EXPECT_EQ(12, L(3).AllocSize()); - } - { - using L = Layout<int32_t, int32_t>; - EXPECT_EQ(32, L::Partial(3, 5).AllocSize()); - EXPECT_EQ(32, L(3, 5).AllocSize()); - } - { - using L = Layout<int8_t, int32_t, Int128>; - EXPECT_EQ(0, L::Partial(0, 0, 0).AllocSize()); - EXPECT_EQ(8, L::Partial(1, 0, 0).AllocSize()); - EXPECT_EQ(8, L::Partial(0, 1, 0).AllocSize()); - EXPECT_EQ(16, L::Partial(0, 0, 1).AllocSize()); - EXPECT_EQ(24, L::Partial(1, 1, 1).AllocSize()); - EXPECT_EQ(136, L::Partial(3, 5, 7).AllocSize()); - EXPECT_EQ(136, L(3, 5, 7).AllocSize()); - } -} - -TEST(Layout, SizeByIndex) { - { - using L = Layout<int32_t>; - EXPECT_EQ(0, L::Partial(0).Size<0>()); - EXPECT_EQ(3, L::Partial(3).Size<0>()); - EXPECT_EQ(3, L(3).Size<0>()); - } - { - using L = Layout<int32_t, int32_t>; - EXPECT_EQ(0, L::Partial(0).Size<0>()); - EXPECT_EQ(3, L::Partial(3).Size<0>()); - EXPECT_EQ(3, L::Partial(3, 5).Size<0>()); - EXPECT_EQ(5, L::Partial(3, 5).Size<1>()); - EXPECT_EQ(3, L(3, 5).Size<0>()); - EXPECT_EQ(5, L(3, 5).Size<1>()); - } - { - using L = Layout<int8_t, int32_t, Int128>; - EXPECT_EQ(3, L::Partial(3).Size<0>()); - EXPECT_EQ(3, L::Partial(3, 5).Size<0>()); - EXPECT_EQ(5, L::Partial(3, 5).Size<1>()); - EXPECT_EQ(3, L::Partial(3, 5, 7).Size<0>()); - EXPECT_EQ(5, L::Partial(3, 5, 7).Size<1>()); - EXPECT_EQ(7, L::Partial(3, 5, 7).Size<2>()); - EXPECT_EQ(3, L(3, 5, 7).Size<0>()); - EXPECT_EQ(5, L(3, 5, 7).Size<1>()); - EXPECT_EQ(7, L(3, 5, 7).Size<2>()); - } -} - -TEST(Layout, SizeByType) { - { - using L = Layout<int32_t>; - EXPECT_EQ(0, L::Partial(0).Size<int32_t>()); - EXPECT_EQ(3, L::Partial(3).Size<int32_t>()); - EXPECT_EQ(3, L(3).Size<int32_t>()); - } - { - using L = Layout<int8_t, int32_t, Int128>; - EXPECT_EQ(3, L::Partial(3).Size<int8_t>()); - EXPECT_EQ(3, L::Partial(3, 5).Size<int8_t>()); - EXPECT_EQ(5, L::Partial(3, 5).Size<int32_t>()); - EXPECT_EQ(3, L::Partial(3, 5, 7).Size<int8_t>()); - EXPECT_EQ(5, L::Partial(3, 5, 7).Size<int32_t>()); - EXPECT_EQ(7, L::Partial(3, 5, 7).Size<Int128>()); - EXPECT_EQ(3, L(3, 5, 7).Size<int8_t>()); - EXPECT_EQ(5, L(3, 5, 7).Size<int32_t>()); - EXPECT_EQ(7, L(3, 5, 7).Size<Int128>()); - } -} - -TEST(Layout, Sizes) { - { - using L = Layout<int32_t>; - EXPECT_THAT(L::Partial().Sizes(), ElementsAre()); - EXPECT_THAT(L::Partial(3).Sizes(), ElementsAre(3)); - EXPECT_THAT(L(3).Sizes(), ElementsAre(3)); - } - { - using L = Layout<int32_t, int32_t>; - EXPECT_THAT(L::Partial().Sizes(), ElementsAre()); - EXPECT_THAT(L::Partial(3).Sizes(), ElementsAre(3)); - EXPECT_THAT(L::Partial(3, 5).Sizes(), ElementsAre(3, 5)); - EXPECT_THAT(L(3, 5).Sizes(), ElementsAre(3, 5)); - } - { - using L = Layout<int8_t, int32_t, Int128>; - EXPECT_THAT(L::Partial().Sizes(), ElementsAre()); - EXPECT_THAT(L::Partial(3).Sizes(), ElementsAre(3)); - EXPECT_THAT(L::Partial(3, 5).Sizes(), ElementsAre(3, 5)); - EXPECT_THAT(L::Partial(3, 5, 7).Sizes(), ElementsAre(3, 5, 7)); - EXPECT_THAT(L(3, 5, 7).Sizes(), ElementsAre(3, 5, 7)); - } -} - -TEST(Layout, PointerByIndex) { - alignas(max_align_t) const unsigned char p[100] = {}; - { - using L = Layout<int32_t>; - EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L::Partial().Pointer<0>(p)))); - EXPECT_EQ(0, - Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<0>(p)))); - EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L(3).Pointer<0>(p)))); - } - { - using L = Layout<int32_t, int32_t>; - EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L::Partial().Pointer<0>(p)))); - EXPECT_EQ(0, - Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<0>(p)))); - EXPECT_EQ(12, - Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<1>(p)))); - EXPECT_EQ( - 0, Distance(p, Type<const int32_t*>(L::Partial(3, 5).Pointer<0>(p)))); - EXPECT_EQ( - 12, Distance(p, Type<const int32_t*>(L::Partial(3, 5).Pointer<1>(p)))); - EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L(3, 5).Pointer<0>(p)))); - EXPECT_EQ(12, Distance(p, Type<const int32_t*>(L(3, 5).Pointer<1>(p)))); - } - { - using L = Layout<int8_t, int32_t, Int128>; - EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial().Pointer<0>(p)))); - EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial(0).Pointer<0>(p)))); - EXPECT_EQ(0, - Distance(p, Type<const int32_t*>(L::Partial(0).Pointer<1>(p)))); - EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial(1).Pointer<0>(p)))); - EXPECT_EQ(4, - Distance(p, Type<const int32_t*>(L::Partial(1).Pointer<1>(p)))); - EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial(5).Pointer<0>(p)))); - EXPECT_EQ(8, - Distance(p, Type<const int32_t*>(L::Partial(5).Pointer<1>(p)))); - EXPECT_EQ(0, - Distance(p, Type<const int8_t*>(L::Partial(0, 0).Pointer<0>(p)))); - EXPECT_EQ( - 0, Distance(p, Type<const int32_t*>(L::Partial(0, 0).Pointer<1>(p)))); - EXPECT_EQ(0, - Distance(p, Type<const Int128*>(L::Partial(0, 0).Pointer<2>(p)))); - EXPECT_EQ(0, - Distance(p, Type<const int8_t*>(L::Partial(1, 0).Pointer<0>(p)))); - EXPECT_EQ( - 4, Distance(p, Type<const int32_t*>(L::Partial(1, 0).Pointer<1>(p)))); - EXPECT_EQ(8, - Distance(p, Type<const Int128*>(L::Partial(1, 0).Pointer<2>(p)))); - EXPECT_EQ(0, - Distance(p, Type<const int8_t*>(L::Partial(5, 3).Pointer<0>(p)))); - EXPECT_EQ( - 8, Distance(p, Type<const int32_t*>(L::Partial(5, 3).Pointer<1>(p)))); - EXPECT_EQ(24, - Distance(p, Type<const Int128*>(L::Partial(5, 3).Pointer<2>(p)))); - EXPECT_EQ( - 0, Distance(p, Type<const int8_t*>(L::Partial(0, 0, 0).Pointer<0>(p)))); - EXPECT_EQ( - 0, - Distance(p, Type<const int32_t*>(L::Partial(0, 0, 0).Pointer<1>(p)))); - EXPECT_EQ( - 0, Distance(p, Type<const Int128*>(L::Partial(0, 0, 0).Pointer<2>(p)))); - EXPECT_EQ( - 0, Distance(p, Type<const int8_t*>(L::Partial(1, 0, 0).Pointer<0>(p)))); - EXPECT_EQ( - 4, - Distance(p, Type<const int32_t*>(L::Partial(1, 0, 0).Pointer<1>(p)))); - EXPECT_EQ( - 8, Distance(p, Type<const Int128*>(L::Partial(1, 0, 0).Pointer<2>(p)))); - EXPECT_EQ( - 0, Distance(p, Type<const int8_t*>(L::Partial(5, 3, 1).Pointer<0>(p)))); - EXPECT_EQ( - 24, - Distance(p, Type<const Int128*>(L::Partial(5, 3, 1).Pointer<2>(p)))); - EXPECT_EQ( - 8, - Distance(p, Type<const int32_t*>(L::Partial(5, 3, 1).Pointer<1>(p)))); - EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L(5, 3, 1).Pointer<0>(p)))); - EXPECT_EQ(24, Distance(p, Type<const Int128*>(L(5, 3, 1).Pointer<2>(p)))); - EXPECT_EQ(8, Distance(p, Type<const int32_t*>(L(5, 3, 1).Pointer<1>(p)))); - } -} - -TEST(Layout, PointerByType) { - alignas(max_align_t) const unsigned char p[100] = {}; - { - using L = Layout<int32_t>; - EXPECT_EQ( - 0, Distance(p, Type<const int32_t*>(L::Partial().Pointer<int32_t>(p)))); - EXPECT_EQ( - 0, - Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<int32_t>(p)))); - EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L(3).Pointer<int32_t>(p)))); - } - { - using L = Layout<int8_t, int32_t, Int128>; - EXPECT_EQ( - 0, Distance(p, Type<const int8_t*>(L::Partial().Pointer<int8_t>(p)))); - EXPECT_EQ( - 0, Distance(p, Type<const int8_t*>(L::Partial(0).Pointer<int8_t>(p)))); - EXPECT_EQ( - 0, - Distance(p, Type<const int32_t*>(L::Partial(0).Pointer<int32_t>(p)))); - EXPECT_EQ( - 0, Distance(p, Type<const int8_t*>(L::Partial(1).Pointer<int8_t>(p)))); - EXPECT_EQ( - 4, - Distance(p, Type<const int32_t*>(L::Partial(1).Pointer<int32_t>(p)))); - EXPECT_EQ( - 0, Distance(p, Type<const int8_t*>(L::Partial(5).Pointer<int8_t>(p)))); - EXPECT_EQ( - 8, - Distance(p, Type<const int32_t*>(L::Partial(5).Pointer<int32_t>(p)))); - EXPECT_EQ( - 0, - Distance(p, Type<const int8_t*>(L::Partial(0, 0).Pointer<int8_t>(p)))); - EXPECT_EQ(0, Distance(p, Type<const int32_t*>( - L::Partial(0, 0).Pointer<int32_t>(p)))); - EXPECT_EQ( - 0, - Distance(p, Type<const Int128*>(L::Partial(0, 0).Pointer<Int128>(p)))); - EXPECT_EQ( - 0, - Distance(p, Type<const int8_t*>(L::Partial(1, 0).Pointer<int8_t>(p)))); - EXPECT_EQ(4, Distance(p, Type<const int32_t*>( - L::Partial(1, 0).Pointer<int32_t>(p)))); - EXPECT_EQ( - 8, - Distance(p, Type<const Int128*>(L::Partial(1, 0).Pointer<Int128>(p)))); - EXPECT_EQ( - 0, - Distance(p, Type<const int8_t*>(L::Partial(5, 3).Pointer<int8_t>(p)))); - EXPECT_EQ(8, Distance(p, Type<const int32_t*>( - L::Partial(5, 3).Pointer<int32_t>(p)))); - EXPECT_EQ( - 24, - Distance(p, Type<const Int128*>(L::Partial(5, 3).Pointer<Int128>(p)))); - EXPECT_EQ(0, Distance(p, Type<const int8_t*>( - L::Partial(0, 0, 0).Pointer<int8_t>(p)))); - EXPECT_EQ(0, Distance(p, Type<const int32_t*>( - L::Partial(0, 0, 0).Pointer<int32_t>(p)))); - EXPECT_EQ(0, Distance(p, Type<const Int128*>( - L::Partial(0, 0, 0).Pointer<Int128>(p)))); - EXPECT_EQ(0, Distance(p, Type<const int8_t*>( - L::Partial(1, 0, 0).Pointer<int8_t>(p)))); - EXPECT_EQ(4, Distance(p, Type<const int32_t*>( - L::Partial(1, 0, 0).Pointer<int32_t>(p)))); - EXPECT_EQ(8, Distance(p, Type<const Int128*>( - L::Partial(1, 0, 0).Pointer<Int128>(p)))); - EXPECT_EQ(0, Distance(p, Type<const int8_t*>( - L::Partial(5, 3, 1).Pointer<int8_t>(p)))); - EXPECT_EQ(24, Distance(p, Type<const Int128*>( - L::Partial(5, 3, 1).Pointer<Int128>(p)))); - EXPECT_EQ(8, Distance(p, Type<const int32_t*>( - L::Partial(5, 3, 1).Pointer<int32_t>(p)))); - EXPECT_EQ(24, - Distance(p, Type<const Int128*>(L(5, 3, 1).Pointer<Int128>(p)))); - EXPECT_EQ( - 8, Distance(p, Type<const int32_t*>(L(5, 3, 1).Pointer<int32_t>(p)))); - } -} - -TEST(Layout, MutablePointerByIndex) { - alignas(max_align_t) unsigned char p[100]; - { - using L = Layout<int32_t>; - EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial().Pointer<0>(p)))); - EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(3).Pointer<0>(p)))); - EXPECT_EQ(0, Distance(p, Type<int32_t*>(L(3).Pointer<0>(p)))); - } - { - using L = Layout<int32_t, int32_t>; - EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial().Pointer<0>(p)))); - EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(3).Pointer<0>(p)))); - EXPECT_EQ(12, Distance(p, Type<int32_t*>(L::Partial(3).Pointer<1>(p)))); - EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(3, 5).Pointer<0>(p)))); - EXPECT_EQ(12, Distance(p, Type<int32_t*>(L::Partial(3, 5).Pointer<1>(p)))); - EXPECT_EQ(0, Distance(p, Type<int32_t*>(L(3, 5).Pointer<0>(p)))); - EXPECT_EQ(12, Distance(p, Type<int32_t*>(L(3, 5).Pointer<1>(p)))); - } - { - using L = Layout<int8_t, int32_t, Int128>; - EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial().Pointer<0>(p)))); - EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0).Pointer<0>(p)))); - EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(0).Pointer<1>(p)))); - EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1).Pointer<0>(p)))); - EXPECT_EQ(4, Distance(p, Type<int32_t*>(L::Partial(1).Pointer<1>(p)))); - EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5).Pointer<0>(p)))); - EXPECT_EQ(8, Distance(p, Type<int32_t*>(L::Partial(5).Pointer<1>(p)))); - EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0, 0).Pointer<0>(p)))); - EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(0, 0).Pointer<1>(p)))); - EXPECT_EQ(0, Distance(p, Type<Int128*>(L::Partial(0, 0).Pointer<2>(p)))); - EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1, 0).Pointer<0>(p)))); - EXPECT_EQ(4, Distance(p, Type<int32_t*>(L::Partial(1, 0).Pointer<1>(p)))); - EXPECT_EQ(8, Distance(p, Type<Int128*>(L::Partial(1, 0).Pointer<2>(p)))); - EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5, 3).Pointer<0>(p)))); - EXPECT_EQ(8, Distance(p, Type<int32_t*>(L::Partial(5, 3).Pointer<1>(p)))); - EXPECT_EQ(24, Distance(p, Type<Int128*>(L::Partial(5, 3).Pointer<2>(p)))); - EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0, 0, 0).Pointer<0>(p)))); - EXPECT_EQ(0, - Distance(p, Type<int32_t*>(L::Partial(0, 0, 0).Pointer<1>(p)))); - EXPECT_EQ(0, Distance(p, Type<Int128*>(L::Partial(0, 0, 0).Pointer<2>(p)))); - EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1, 0, 0).Pointer<0>(p)))); - EXPECT_EQ(4, - Distance(p, Type<int32_t*>(L::Partial(1, 0, 0).Pointer<1>(p)))); - EXPECT_EQ(8, Distance(p, Type<Int128*>(L::Partial(1, 0, 0).Pointer<2>(p)))); - EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5, 3, 1).Pointer<0>(p)))); - EXPECT_EQ(24, - Distance(p, Type<Int128*>(L::Partial(5, 3, 1).Pointer<2>(p)))); - EXPECT_EQ(8, - Distance(p, Type<int32_t*>(L::Partial(5, 3, 1).Pointer<1>(p)))); - EXPECT_EQ(0, Distance(p, Type<int8_t*>(L(5, 3, 1).Pointer<0>(p)))); - EXPECT_EQ(24, Distance(p, Type<Int128*>(L(5, 3, 1).Pointer<2>(p)))); - EXPECT_EQ(8, Distance(p, Type<int32_t*>(L(5, 3, 1).Pointer<1>(p)))); - } -} - -TEST(Layout, MutablePointerByType) { - alignas(max_align_t) unsigned char p[100]; - { - using L = Layout<int32_t>; - EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial().Pointer<int32_t>(p)))); - EXPECT_EQ(0, - Distance(p, Type<int32_t*>(L::Partial(3).Pointer<int32_t>(p)))); - EXPECT_EQ(0, Distance(p, Type<int32_t*>(L(3).Pointer<int32_t>(p)))); - } - { - using L = Layout<int8_t, int32_t, Int128>; - EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial().Pointer<int8_t>(p)))); - EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0).Pointer<int8_t>(p)))); - EXPECT_EQ(0, - Distance(p, Type<int32_t*>(L::Partial(0).Pointer<int32_t>(p)))); - EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1).Pointer<int8_t>(p)))); - EXPECT_EQ(4, - Distance(p, Type<int32_t*>(L::Partial(1).Pointer<int32_t>(p)))); - EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5).Pointer<int8_t>(p)))); - EXPECT_EQ(8, - Distance(p, Type<int32_t*>(L::Partial(5).Pointer<int32_t>(p)))); - EXPECT_EQ(0, - Distance(p, Type<int8_t*>(L::Partial(0, 0).Pointer<int8_t>(p)))); - EXPECT_EQ( - 0, Distance(p, Type<int32_t*>(L::Partial(0, 0).Pointer<int32_t>(p)))); - EXPECT_EQ(0, - Distance(p, Type<Int128*>(L::Partial(0, 0).Pointer<Int128>(p)))); - EXPECT_EQ(0, - Distance(p, Type<int8_t*>(L::Partial(1, 0).Pointer<int8_t>(p)))); - EXPECT_EQ( - 4, Distance(p, Type<int32_t*>(L::Partial(1, 0).Pointer<int32_t>(p)))); - EXPECT_EQ(8, - Distance(p, Type<Int128*>(L::Partial(1, 0).Pointer<Int128>(p)))); - EXPECT_EQ(0, - Distance(p, Type<int8_t*>(L::Partial(5, 3).Pointer<int8_t>(p)))); - EXPECT_EQ( - 8, Distance(p, Type<int32_t*>(L::Partial(5, 3).Pointer<int32_t>(p)))); - EXPECT_EQ(24, - Distance(p, Type<Int128*>(L::Partial(5, 3).Pointer<Int128>(p)))); - EXPECT_EQ( - 0, Distance(p, Type<int8_t*>(L::Partial(0, 0, 0).Pointer<int8_t>(p)))); - EXPECT_EQ( - 0, - Distance(p, Type<int32_t*>(L::Partial(0, 0, 0).Pointer<int32_t>(p)))); - EXPECT_EQ( - 0, Distance(p, Type<Int128*>(L::Partial(0, 0, 0).Pointer<Int128>(p)))); - EXPECT_EQ( - 0, Distance(p, Type<int8_t*>(L::Partial(1, 0, 0).Pointer<int8_t>(p)))); - EXPECT_EQ( - 4, - Distance(p, Type<int32_t*>(L::Partial(1, 0, 0).Pointer<int32_t>(p)))); - EXPECT_EQ( - 8, Distance(p, Type<Int128*>(L::Partial(1, 0, 0).Pointer<Int128>(p)))); - EXPECT_EQ( - 0, Distance(p, Type<int8_t*>(L::Partial(5, 3, 1).Pointer<int8_t>(p)))); - EXPECT_EQ( - 24, Distance(p, Type<Int128*>(L::Partial(5, 3, 1).Pointer<Int128>(p)))); - EXPECT_EQ( - 8, - Distance(p, Type<int32_t*>(L::Partial(5, 3, 1).Pointer<int32_t>(p)))); - EXPECT_EQ(0, Distance(p, Type<int8_t*>(L(5, 3, 1).Pointer<int8_t>(p)))); - EXPECT_EQ(24, Distance(p, Type<Int128*>(L(5, 3, 1).Pointer<Int128>(p)))); - EXPECT_EQ(8, Distance(p, Type<int32_t*>(L(5, 3, 1).Pointer<int32_t>(p)))); - } -} - -TEST(Layout, Pointers) { - alignas(max_align_t) const unsigned char p[100] = {}; - using L = Layout<int8_t, int8_t, Int128>; - { - const auto x = L::Partial(); - EXPECT_EQ(std::make_tuple(x.Pointer<0>(p)), - Type<std::tuple<const int8_t*>>(x.Pointers(p))); - } - { - const auto x = L::Partial(1); - EXPECT_EQ(std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p)), - (Type<std::tuple<const int8_t*, const int8_t*>>(x.Pointers(p)))); - } - { - const auto x = L::Partial(1, 2); - EXPECT_EQ( - std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)), - (Type<std::tuple<const int8_t*, const int8_t*, const Int128*>>( - x.Pointers(p)))); - } - { - const auto x = L::Partial(1, 2, 3); - EXPECT_EQ( - std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)), - (Type<std::tuple<const int8_t*, const int8_t*, const Int128*>>( - x.Pointers(p)))); - } - { - const L x(1, 2, 3); - EXPECT_EQ( - std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)), - (Type<std::tuple<const int8_t*, const int8_t*, const Int128*>>( - x.Pointers(p)))); - } -} - -TEST(Layout, MutablePointers) { - alignas(max_align_t) unsigned char p[100]; - using L = Layout<int8_t, int8_t, Int128>; - { - const auto x = L::Partial(); - EXPECT_EQ(std::make_tuple(x.Pointer<0>(p)), - Type<std::tuple<int8_t*>>(x.Pointers(p))); - } - { - const auto x = L::Partial(1); - EXPECT_EQ(std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p)), - (Type<std::tuple<int8_t*, int8_t*>>(x.Pointers(p)))); - } - { - const auto x = L::Partial(1, 2); - EXPECT_EQ( - std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)), - (Type<std::tuple<int8_t*, int8_t*, Int128*>>(x.Pointers(p)))); - } - { - const auto x = L::Partial(1, 2, 3); - EXPECT_EQ( - std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)), - (Type<std::tuple<int8_t*, int8_t*, Int128*>>(x.Pointers(p)))); - } - { - const L x(1, 2, 3); - EXPECT_EQ( - std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)), - (Type<std::tuple<int8_t*, int8_t*, Int128*>>(x.Pointers(p)))); - } -} - -TEST(Layout, SliceByIndexSize) { - alignas(max_align_t) const unsigned char p[100] = {}; - { - using L = Layout<int32_t>; - EXPECT_EQ(0, L::Partial(0).Slice<0>(p).size()); - EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size()); - EXPECT_EQ(3, L(3).Slice<0>(p).size()); - } - { - using L = Layout<int32_t, int32_t>; - EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size()); - EXPECT_EQ(5, L::Partial(3, 5).Slice<1>(p).size()); - EXPECT_EQ(5, L(3, 5).Slice<1>(p).size()); - } - { - using L = Layout<int8_t, int32_t, Int128>; - EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size()); - EXPECT_EQ(3, L::Partial(3, 5).Slice<0>(p).size()); - EXPECT_EQ(5, L::Partial(3, 5).Slice<1>(p).size()); - EXPECT_EQ(3, L::Partial(3, 5, 7).Slice<0>(p).size()); - EXPECT_EQ(5, L::Partial(3, 5, 7).Slice<1>(p).size()); - EXPECT_EQ(7, L::Partial(3, 5, 7).Slice<2>(p).size()); - EXPECT_EQ(3, L(3, 5, 7).Slice<0>(p).size()); - EXPECT_EQ(5, L(3, 5, 7).Slice<1>(p).size()); - EXPECT_EQ(7, L(3, 5, 7).Slice<2>(p).size()); - } -} - -TEST(Layout, SliceByTypeSize) { - alignas(max_align_t) const unsigned char p[100] = {}; - { - using L = Layout<int32_t>; - EXPECT_EQ(0, L::Partial(0).Slice<int32_t>(p).size()); - EXPECT_EQ(3, L::Partial(3).Slice<int32_t>(p).size()); - EXPECT_EQ(3, L(3).Slice<int32_t>(p).size()); - } - { - using L = Layout<int8_t, int32_t, Int128>; - EXPECT_EQ(3, L::Partial(3).Slice<int8_t>(p).size()); - EXPECT_EQ(3, L::Partial(3, 5).Slice<int8_t>(p).size()); - EXPECT_EQ(5, L::Partial(3, 5).Slice<int32_t>(p).size()); - EXPECT_EQ(3, L::Partial(3, 5, 7).Slice<int8_t>(p).size()); - EXPECT_EQ(5, L::Partial(3, 5, 7).Slice<int32_t>(p).size()); - EXPECT_EQ(7, L::Partial(3, 5, 7).Slice<Int128>(p).size()); - EXPECT_EQ(3, L(3, 5, 7).Slice<int8_t>(p).size()); - EXPECT_EQ(5, L(3, 5, 7).Slice<int32_t>(p).size()); - EXPECT_EQ(7, L(3, 5, 7).Slice<Int128>(p).size()); - } -} - -TEST(Layout, MutableSliceByIndexSize) { - alignas(max_align_t) unsigned char p[100]; - { - using L = Layout<int32_t>; - EXPECT_EQ(0, L::Partial(0).Slice<0>(p).size()); - EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size()); - EXPECT_EQ(3, L(3).Slice<0>(p).size()); - } - { - using L = Layout<int32_t, int32_t>; - EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size()); - EXPECT_EQ(5, L::Partial(3, 5).Slice<1>(p).size()); - EXPECT_EQ(5, L(3, 5).Slice<1>(p).size()); - } - { - using L = Layout<int8_t, int32_t, Int128>; - EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size()); - EXPECT_EQ(3, L::Partial(3, 5).Slice<0>(p).size()); - EXPECT_EQ(5, L::Partial(3, 5).Slice<1>(p).size()); - EXPECT_EQ(3, L::Partial(3, 5, 7).Slice<0>(p).size()); - EXPECT_EQ(5, L::Partial(3, 5, 7).Slice<1>(p).size()); - EXPECT_EQ(7, L::Partial(3, 5, 7).Slice<2>(p).size()); - EXPECT_EQ(3, L(3, 5, 7).Slice<0>(p).size()); - EXPECT_EQ(5, L(3, 5, 7).Slice<1>(p).size()); - EXPECT_EQ(7, L(3, 5, 7).Slice<2>(p).size()); - } -} - -TEST(Layout, MutableSliceByTypeSize) { - alignas(max_align_t) unsigned char p[100]; - { - using L = Layout<int32_t>; - EXPECT_EQ(0, L::Partial(0).Slice<int32_t>(p).size()); - EXPECT_EQ(3, L::Partial(3).Slice<int32_t>(p).size()); - EXPECT_EQ(3, L(3).Slice<int32_t>(p).size()); - } - { - using L = Layout<int8_t, int32_t, Int128>; - EXPECT_EQ(3, L::Partial(3).Slice<int8_t>(p).size()); - EXPECT_EQ(3, L::Partial(3, 5).Slice<int8_t>(p).size()); - EXPECT_EQ(5, L::Partial(3, 5).Slice<int32_t>(p).size()); - EXPECT_EQ(3, L::Partial(3, 5, 7).Slice<int8_t>(p).size()); - EXPECT_EQ(5, L::Partial(3, 5, 7).Slice<int32_t>(p).size()); - EXPECT_EQ(7, L::Partial(3, 5, 7).Slice<Int128>(p).size()); - EXPECT_EQ(3, L(3, 5, 7).Slice<int8_t>(p).size()); - EXPECT_EQ(5, L(3, 5, 7).Slice<int32_t>(p).size()); - EXPECT_EQ(7, L(3, 5, 7).Slice<Int128>(p).size()); - } -} - -TEST(Layout, SliceByIndexData) { - alignas(max_align_t) const unsigned char p[100] = {}; - { - using L = Layout<int32_t>; - EXPECT_EQ( - 0, Distance( - p, Type<Span<const int32_t>>(L::Partial(0).Slice<0>(p)).data())); - EXPECT_EQ( - 0, Distance( - p, Type<Span<const int32_t>>(L::Partial(3).Slice<0>(p)).data())); - EXPECT_EQ(0, - Distance(p, Type<Span<const int32_t>>(L(3).Slice<0>(p)).data())); - } - { - using L = Layout<int32_t, int32_t>; - EXPECT_EQ( - 0, Distance( - p, Type<Span<const int32_t>>(L::Partial(3).Slice<0>(p)).data())); - EXPECT_EQ( - 0, - Distance( - p, Type<Span<const int32_t>>(L::Partial(3, 5).Slice<0>(p)).data())); - EXPECT_EQ( - 12, - Distance( - p, Type<Span<const int32_t>>(L::Partial(3, 5).Slice<1>(p)).data())); - EXPECT_EQ( - 0, Distance(p, Type<Span<const int32_t>>(L(3, 5).Slice<0>(p)).data())); - EXPECT_EQ( - 12, Distance(p, Type<Span<const int32_t>>(L(3, 5).Slice<1>(p)).data())); - } - { - using L = Layout<int8_t, int32_t, Int128>; - EXPECT_EQ( - 0, Distance( - p, Type<Span<const int8_t>>(L::Partial(0).Slice<0>(p)).data())); - EXPECT_EQ( - 0, Distance( - p, Type<Span<const int8_t>>(L::Partial(1).Slice<0>(p)).data())); - EXPECT_EQ( - 0, Distance( - p, Type<Span<const int8_t>>(L::Partial(5).Slice<0>(p)).data())); - EXPECT_EQ( - 0, - Distance( - p, Type<Span<const int8_t>>(L::Partial(0, 0).Slice<0>(p)).data())); - EXPECT_EQ( - 0, - Distance( - p, Type<Span<const int32_t>>(L::Partial(0, 0).Slice<1>(p)).data())); - EXPECT_EQ( - 0, - Distance( - p, Type<Span<const int8_t>>(L::Partial(1, 0).Slice<0>(p)).data())); - EXPECT_EQ( - 4, - Distance( - p, Type<Span<const int32_t>>(L::Partial(1, 0).Slice<1>(p)).data())); - EXPECT_EQ( - 0, - Distance( - p, Type<Span<const int8_t>>(L::Partial(5, 3).Slice<0>(p)).data())); - EXPECT_EQ( - 8, - Distance( - p, Type<Span<const int32_t>>(L::Partial(5, 3).Slice<1>(p)).data())); - EXPECT_EQ( - 0, - Distance( - p, - Type<Span<const int8_t>>(L::Partial(0, 0, 0).Slice<0>(p)).data())); - EXPECT_EQ( - 0, - Distance( - p, - Type<Span<const int32_t>>(L::Partial(0, 0, 0).Slice<1>(p)).data())); - EXPECT_EQ( - 0, - Distance( - p, - Type<Span<const Int128>>(L::Partial(0, 0, 0).Slice<2>(p)).data())); - EXPECT_EQ( - 0, - Distance( - p, - Type<Span<const int8_t>>(L::Partial(1, 0, 0).Slice<0>(p)).data())); - EXPECT_EQ( - 4, - Distance( - p, - Type<Span<const int32_t>>(L::Partial(1, 0, 0).Slice<1>(p)).data())); - EXPECT_EQ( - 8, - Distance( - p, - Type<Span<const Int128>>(L::Partial(1, 0, 0).Slice<2>(p)).data())); - EXPECT_EQ( - 0, - Distance( - p, - Type<Span<const int8_t>>(L::Partial(5, 3, 1).Slice<0>(p)).data())); - EXPECT_EQ( - 24, - Distance( - p, - Type<Span<const Int128>>(L::Partial(5, 3, 1).Slice<2>(p)).data())); - EXPECT_EQ( - 8, - Distance( - p, - Type<Span<const int32_t>>(L::Partial(5, 3, 1).Slice<1>(p)).data())); - EXPECT_EQ( - 0, - Distance(p, Type<Span<const int8_t>>(L(5, 3, 1).Slice<0>(p)).data())); - EXPECT_EQ( - 24, - Distance(p, Type<Span<const Int128>>(L(5, 3, 1).Slice<2>(p)).data())); - EXPECT_EQ( - 8, - Distance(p, Type<Span<const int32_t>>(L(5, 3, 1).Slice<1>(p)).data())); - } -} - -TEST(Layout, SliceByTypeData) { - alignas(max_align_t) const unsigned char p[100] = {}; - { - using L = Layout<int32_t>; - EXPECT_EQ( - 0, - Distance( - p, - Type<Span<const int32_t>>(L::Partial(0).Slice<int32_t>(p)).data())); - EXPECT_EQ( - 0, - Distance( - p, - Type<Span<const int32_t>>(L::Partial(3).Slice<int32_t>(p)).data())); - EXPECT_EQ( - 0, - Distance(p, Type<Span<const int32_t>>(L(3).Slice<int32_t>(p)).data())); - } - { - using L = Layout<int8_t, int32_t, Int128>; - EXPECT_EQ( - 0, - Distance( - p, - Type<Span<const int8_t>>(L::Partial(0).Slice<int8_t>(p)).data())); - EXPECT_EQ( - 0, - Distance( - p, - Type<Span<const int8_t>>(L::Partial(1).Slice<int8_t>(p)).data())); - EXPECT_EQ( - 0, - Distance( - p, - Type<Span<const int8_t>>(L::Partial(5).Slice<int8_t>(p)).data())); - EXPECT_EQ( - 0, - Distance(p, Type<Span<const int8_t>>(L::Partial(0, 0).Slice<int8_t>(p)) - .data())); - EXPECT_EQ(0, Distance(p, Type<Span<const int32_t>>( - L::Partial(0, 0).Slice<int32_t>(p)) - .data())); - EXPECT_EQ( - 0, - Distance(p, Type<Span<const int8_t>>(L::Partial(1, 0).Slice<int8_t>(p)) - .data())); - EXPECT_EQ(4, Distance(p, Type<Span<const int32_t>>( - L::Partial(1, 0).Slice<int32_t>(p)) - .data())); - EXPECT_EQ( - 0, - Distance(p, Type<Span<const int8_t>>(L::Partial(5, 3).Slice<int8_t>(p)) - .data())); - EXPECT_EQ(8, Distance(p, Type<Span<const int32_t>>( - L::Partial(5, 3).Slice<int32_t>(p)) - .data())); - EXPECT_EQ(0, Distance(p, Type<Span<const int8_t>>( - L::Partial(0, 0, 0).Slice<int8_t>(p)) - .data())); - EXPECT_EQ(0, Distance(p, Type<Span<const int32_t>>( - L::Partial(0, 0, 0).Slice<int32_t>(p)) - .data())); - EXPECT_EQ(0, Distance(p, Type<Span<const Int128>>( - L::Partial(0, 0, 0).Slice<Int128>(p)) - .data())); - EXPECT_EQ(0, Distance(p, Type<Span<const int8_t>>( - L::Partial(1, 0, 0).Slice<int8_t>(p)) - .data())); - EXPECT_EQ(4, Distance(p, Type<Span<const int32_t>>( - L::Partial(1, 0, 0).Slice<int32_t>(p)) - .data())); - EXPECT_EQ(8, Distance(p, Type<Span<const Int128>>( - L::Partial(1, 0, 0).Slice<Int128>(p)) - .data())); - EXPECT_EQ(0, Distance(p, Type<Span<const int8_t>>( - L::Partial(5, 3, 1).Slice<int8_t>(p)) - .data())); - EXPECT_EQ(24, Distance(p, Type<Span<const Int128>>( - L::Partial(5, 3, 1).Slice<Int128>(p)) - .data())); - EXPECT_EQ(8, Distance(p, Type<Span<const int32_t>>( - L::Partial(5, 3, 1).Slice<int32_t>(p)) - .data())); - EXPECT_EQ( - 0, - Distance(p, - Type<Span<const int8_t>>(L(5, 3, 1).Slice<int8_t>(p)).data())); - EXPECT_EQ( - 24, - Distance(p, - Type<Span<const Int128>>(L(5, 3, 1).Slice<Int128>(p)).data())); - EXPECT_EQ( - 8, - Distance( - p, Type<Span<const int32_t>>(L(5, 3, 1).Slice<int32_t>(p)).data())); - } -} - -TEST(Layout, MutableSliceByIndexData) { - alignas(max_align_t) unsigned char p[100]; - { - using L = Layout<int32_t>; - EXPECT_EQ( - 0, Distance(p, Type<Span<int32_t>>(L::Partial(0).Slice<0>(p)).data())); - EXPECT_EQ( - 0, Distance(p, Type<Span<int32_t>>(L::Partial(3).Slice<0>(p)).data())); - EXPECT_EQ(0, Distance(p, Type<Span<int32_t>>(L(3).Slice<0>(p)).data())); - } - { - using L = Layout<int32_t, int32_t>; - EXPECT_EQ( - 0, Distance(p, Type<Span<int32_t>>(L::Partial(3).Slice<0>(p)).data())); - EXPECT_EQ( - 0, - Distance(p, Type<Span<int32_t>>(L::Partial(3, 5).Slice<0>(p)).data())); - EXPECT_EQ( - 12, - Distance(p, Type<Span<int32_t>>(L::Partial(3, 5).Slice<1>(p)).data())); - EXPECT_EQ(0, Distance(p, Type<Span<int32_t>>(L(3, 5).Slice<0>(p)).data())); - EXPECT_EQ(12, Distance(p, Type<Span<int32_t>>(L(3, 5).Slice<1>(p)).data())); - } - { - using L = Layout<int8_t, int32_t, Int128>; - EXPECT_EQ( - 0, Distance(p, Type<Span<int8_t>>(L::Partial(0).Slice<0>(p)).data())); - EXPECT_EQ( - 0, Distance(p, Type<Span<int8_t>>(L::Partial(1).Slice<0>(p)).data())); - EXPECT_EQ( - 0, Distance(p, Type<Span<int8_t>>(L::Partial(5).Slice<0>(p)).data())); - EXPECT_EQ( - 0, - Distance(p, Type<Span<int8_t>>(L::Partial(0, 0).Slice<0>(p)).data())); - EXPECT_EQ( - 0, - Distance(p, Type<Span<int32_t>>(L::Partial(0, 0).Slice<1>(p)).data())); - EXPECT_EQ( - 0, - Distance(p, Type<Span<int8_t>>(L::Partial(1, 0).Slice<0>(p)).data())); - EXPECT_EQ( - 4, - Distance(p, Type<Span<int32_t>>(L::Partial(1, 0).Slice<1>(p)).data())); - EXPECT_EQ( - 0, - Distance(p, Type<Span<int8_t>>(L::Partial(5, 3).Slice<0>(p)).data())); - EXPECT_EQ( - 8, - Distance(p, Type<Span<int32_t>>(L::Partial(5, 3).Slice<1>(p)).data())); - EXPECT_EQ( - 0, Distance( - p, Type<Span<int8_t>>(L::Partial(0, 0, 0).Slice<0>(p)).data())); - EXPECT_EQ( - 0, Distance( - p, Type<Span<int32_t>>(L::Partial(0, 0, 0).Slice<1>(p)).data())); - EXPECT_EQ( - 0, Distance( - p, Type<Span<Int128>>(L::Partial(0, 0, 0).Slice<2>(p)).data())); - EXPECT_EQ( - 0, Distance( - p, Type<Span<int8_t>>(L::Partial(1, 0, 0).Slice<0>(p)).data())); - EXPECT_EQ( - 4, Distance( - p, Type<Span<int32_t>>(L::Partial(1, 0, 0).Slice<1>(p)).data())); - EXPECT_EQ( - 8, Distance( - p, Type<Span<Int128>>(L::Partial(1, 0, 0).Slice<2>(p)).data())); - EXPECT_EQ( - 0, Distance( - p, Type<Span<int8_t>>(L::Partial(5, 3, 1).Slice<0>(p)).data())); - EXPECT_EQ( - 24, Distance( - p, Type<Span<Int128>>(L::Partial(5, 3, 1).Slice<2>(p)).data())); - EXPECT_EQ( - 8, Distance( - p, Type<Span<int32_t>>(L::Partial(5, 3, 1).Slice<1>(p)).data())); - EXPECT_EQ(0, - Distance(p, Type<Span<int8_t>>(L(5, 3, 1).Slice<0>(p)).data())); - EXPECT_EQ(24, - Distance(p, Type<Span<Int128>>(L(5, 3, 1).Slice<2>(p)).data())); - EXPECT_EQ(8, - Distance(p, Type<Span<int32_t>>(L(5, 3, 1).Slice<1>(p)).data())); - } -} - -TEST(Layout, MutableSliceByTypeData) { - alignas(max_align_t) unsigned char p[100]; - { - using L = Layout<int32_t>; - EXPECT_EQ( - 0, Distance( - p, Type<Span<int32_t>>(L::Partial(0).Slice<int32_t>(p)).data())); - EXPECT_EQ( - 0, Distance( - p, Type<Span<int32_t>>(L::Partial(3).Slice<int32_t>(p)).data())); - EXPECT_EQ(0, - Distance(p, Type<Span<int32_t>>(L(3).Slice<int32_t>(p)).data())); - } - { - using L = Layout<int8_t, int32_t, Int128>; - EXPECT_EQ( - 0, - Distance(p, Type<Span<int8_t>>(L::Partial(0).Slice<int8_t>(p)).data())); - EXPECT_EQ( - 0, - Distance(p, Type<Span<int8_t>>(L::Partial(1).Slice<int8_t>(p)).data())); - EXPECT_EQ( - 0, - Distance(p, Type<Span<int8_t>>(L::Partial(5).Slice<int8_t>(p)).data())); - EXPECT_EQ( - 0, - Distance(p, - Type<Span<int8_t>>(L::Partial(0, 0).Slice<int8_t>(p)).data())); - EXPECT_EQ( - 0, - Distance( - p, Type<Span<int32_t>>(L::Partial(0, 0).Slice<int32_t>(p)).data())); - EXPECT_EQ( - 0, - Distance(p, - Type<Span<int8_t>>(L::Partial(1, 0).Slice<int8_t>(p)).data())); - EXPECT_EQ( - 4, - Distance( - p, Type<Span<int32_t>>(L::Partial(1, 0).Slice<int32_t>(p)).data())); - EXPECT_EQ( - 0, - Distance(p, - Type<Span<int8_t>>(L::Partial(5, 3).Slice<int8_t>(p)).data())); - EXPECT_EQ( - 8, - Distance( - p, Type<Span<int32_t>>(L::Partial(5, 3).Slice<int32_t>(p)).data())); - EXPECT_EQ( - 0, - Distance( - p, - Type<Span<int8_t>>(L::Partial(0, 0, 0).Slice<int8_t>(p)).data())); - EXPECT_EQ( - 0, - Distance( - p, - Type<Span<int32_t>>(L::Partial(0, 0, 0).Slice<int32_t>(p)).data())); - EXPECT_EQ( - 0, - Distance( - p, - Type<Span<Int128>>(L::Partial(0, 0, 0).Slice<Int128>(p)).data())); - EXPECT_EQ( - 0, - Distance( - p, - Type<Span<int8_t>>(L::Partial(1, 0, 0).Slice<int8_t>(p)).data())); - EXPECT_EQ( - 4, - Distance( - p, - Type<Span<int32_t>>(L::Partial(1, 0, 0).Slice<int32_t>(p)).data())); - EXPECT_EQ( - 8, - Distance( - p, - Type<Span<Int128>>(L::Partial(1, 0, 0).Slice<Int128>(p)).data())); - EXPECT_EQ( - 0, - Distance( - p, - Type<Span<int8_t>>(L::Partial(5, 3, 1).Slice<int8_t>(p)).data())); - EXPECT_EQ( - 24, - Distance( - p, - Type<Span<Int128>>(L::Partial(5, 3, 1).Slice<Int128>(p)).data())); - EXPECT_EQ( - 8, - Distance( - p, - Type<Span<int32_t>>(L::Partial(5, 3, 1).Slice<int32_t>(p)).data())); - EXPECT_EQ( - 0, Distance(p, Type<Span<int8_t>>(L(5, 3, 1).Slice<int8_t>(p)).data())); - EXPECT_EQ( - 24, - Distance(p, Type<Span<Int128>>(L(5, 3, 1).Slice<Int128>(p)).data())); - EXPECT_EQ( - 8, - Distance(p, Type<Span<int32_t>>(L(5, 3, 1).Slice<int32_t>(p)).data())); - } -} - -MATCHER_P(IsSameSlice, slice, "") { - return arg.size() == slice.size() && arg.data() == slice.data(); -} - -template <typename... M> -class TupleMatcher { - public: - explicit TupleMatcher(M... matchers) : matchers_(std::move(matchers)...) {} - - template <typename Tuple> - bool MatchAndExplain(const Tuple& p, - testing::MatchResultListener* /* listener */) const { - static_assert(std::tuple_size<Tuple>::value == sizeof...(M), ""); - return MatchAndExplainImpl( - p, absl::make_index_sequence<std::tuple_size<Tuple>::value>{}); - } - - // For the matcher concept. Left empty as we don't really need the diagnostics - // right now. - void DescribeTo(::std::ostream* os) const {} - void DescribeNegationTo(::std::ostream* os) const {} - - private: - template <typename Tuple, size_t... Is> - bool MatchAndExplainImpl(const Tuple& p, absl::index_sequence<Is...>) const { - // Using std::min as a simple variadic "and". - return std::min( - {true, testing::SafeMatcherCast< - const typename std::tuple_element<Is, Tuple>::type&>( - std::get<Is>(matchers_)) - .Matches(std::get<Is>(p))...}); - } - - std::tuple<M...> matchers_; -}; - -template <typename... M> -testing::PolymorphicMatcher<TupleMatcher<M...>> Tuple(M... matchers) { - return testing::MakePolymorphicMatcher( - TupleMatcher<M...>(std::move(matchers)...)); -} - -TEST(Layout, Slices) { - alignas(max_align_t) const unsigned char p[100] = {}; - using L = Layout<int8_t, int8_t, Int128>; - { - const auto x = L::Partial(); - EXPECT_THAT(Type<std::tuple<>>(x.Slices(p)), Tuple()); - } - { - const auto x = L::Partial(1); - EXPECT_THAT(Type<std::tuple<Span<const int8_t>>>(x.Slices(p)), - Tuple(IsSameSlice(x.Slice<0>(p)))); - } - { - const auto x = L::Partial(1, 2); - EXPECT_THAT( - (Type<std::tuple<Span<const int8_t>, Span<const int8_t>>>(x.Slices(p))), - Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)))); - } - { - const auto x = L::Partial(1, 2, 3); - EXPECT_THAT((Type<std::tuple<Span<const int8_t>, Span<const int8_t>, - Span<const Int128>>>(x.Slices(p))), - Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)), - IsSameSlice(x.Slice<2>(p)))); - } - { - const L x(1, 2, 3); - EXPECT_THAT((Type<std::tuple<Span<const int8_t>, Span<const int8_t>, - Span<const Int128>>>(x.Slices(p))), - Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)), - IsSameSlice(x.Slice<2>(p)))); - } -} - -TEST(Layout, MutableSlices) { - alignas(max_align_t) unsigned char p[100] = {}; - using L = Layout<int8_t, int8_t, Int128>; - { - const auto x = L::Partial(); - EXPECT_THAT(Type<std::tuple<>>(x.Slices(p)), Tuple()); - } - { - const auto x = L::Partial(1); - EXPECT_THAT(Type<std::tuple<Span<int8_t>>>(x.Slices(p)), - Tuple(IsSameSlice(x.Slice<0>(p)))); - } - { - const auto x = L::Partial(1, 2); - EXPECT_THAT((Type<std::tuple<Span<int8_t>, Span<int8_t>>>(x.Slices(p))), - Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)))); - } - { - const auto x = L::Partial(1, 2, 3); - EXPECT_THAT((Type<std::tuple<Span<int8_t>, Span<int8_t>, Span<Int128>>>( - x.Slices(p))), - Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)), - IsSameSlice(x.Slice<2>(p)))); - } - { - const L x(1, 2, 3); - EXPECT_THAT((Type<std::tuple<Span<int8_t>, Span<int8_t>, Span<Int128>>>( - x.Slices(p))), - Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)), - IsSameSlice(x.Slice<2>(p)))); - } -} - -TEST(Layout, UnalignedTypes) { - constexpr Layout<unsigned char, unsigned char, unsigned char> x(1, 2, 3); - alignas(max_align_t) unsigned char p[x.AllocSize() + 1]; - EXPECT_THAT(x.Pointers(p + 1), Tuple(p + 1, p + 2, p + 4)); -} - -TEST(Layout, CustomAlignment) { - constexpr Layout<unsigned char, Aligned<unsigned char, 8>> x(1, 2); - alignas(max_align_t) unsigned char p[x.AllocSize()]; - EXPECT_EQ(10, x.AllocSize()); - EXPECT_THAT(x.Pointers(p), Tuple(p + 0, p + 8)); -} - -TEST(Layout, OverAligned) { - constexpr size_t M = alignof(max_align_t); - constexpr Layout<unsigned char, Aligned<unsigned char, 2 * M>> x(1, 3); - alignas(2 * M) unsigned char p[x.AllocSize()]; - EXPECT_EQ(2 * M + 3, x.AllocSize()); - EXPECT_THAT(x.Pointers(p), Tuple(p + 0, p + 2 * M)); -} - -TEST(Layout, Alignment) { - static_assert(Layout<int8_t>::Alignment() == 1, ""); - static_assert(Layout<int32_t>::Alignment() == 4, ""); - static_assert(Layout<Int64>::Alignment() == 8, ""); - static_assert(Layout<Aligned<int8_t, 64>>::Alignment() == 64, ""); - static_assert(Layout<int8_t, int32_t, Int64>::Alignment() == 8, ""); - static_assert(Layout<int8_t, Int64, int32_t>::Alignment() == 8, ""); - static_assert(Layout<int32_t, int8_t, Int64>::Alignment() == 8, ""); - static_assert(Layout<int32_t, Int64, int8_t>::Alignment() == 8, ""); - static_assert(Layout<Int64, int8_t, int32_t>::Alignment() == 8, ""); - static_assert(Layout<Int64, int32_t, int8_t>::Alignment() == 8, ""); -} - -TEST(Layout, ConstexprPartial) { - constexpr size_t M = alignof(max_align_t); - constexpr Layout<unsigned char, Aligned<unsigned char, 2 * M>> x(1, 3); - static_assert(x.Partial(1).template Offset<1>() == 2 * M, ""); -} -// [from, to) -struct Region { - size_t from; - size_t to; -}; - -void ExpectRegionPoisoned(const unsigned char* p, size_t n, bool poisoned) { -#ifdef ABSL_HAVE_ADDRESS_SANITIZER - for (size_t i = 0; i != n; ++i) { - EXPECT_EQ(poisoned, __asan_address_is_poisoned(p + i)); - } -#endif -} - -template <size_t N> -void ExpectPoisoned(const unsigned char (&buf)[N], - std::initializer_list<Region> reg) { - size_t prev = 0; - for (const Region& r : reg) { - ExpectRegionPoisoned(buf + prev, r.from - prev, false); - ExpectRegionPoisoned(buf + r.from, r.to - r.from, true); - prev = r.to; - } - ExpectRegionPoisoned(buf + prev, N - prev, false); -} - -TEST(Layout, PoisonPadding) { - using L = Layout<int8_t, Int64, int32_t, Int128>; - - constexpr size_t n = L::Partial(1, 2, 3, 4).AllocSize(); - { - constexpr auto x = L::Partial(); - alignas(max_align_t) const unsigned char c[n] = {}; - x.PoisonPadding(c); - EXPECT_EQ(x.Slices(c), x.Slices(c)); - ExpectPoisoned(c, {}); - } - { - constexpr auto x = L::Partial(1); - alignas(max_align_t) const unsigned char c[n] = {}; - x.PoisonPadding(c); - EXPECT_EQ(x.Slices(c), x.Slices(c)); - ExpectPoisoned(c, {{1, 8}}); - } - { - constexpr auto x = L::Partial(1, 2); - alignas(max_align_t) const unsigned char c[n] = {}; - x.PoisonPadding(c); - EXPECT_EQ(x.Slices(c), x.Slices(c)); - ExpectPoisoned(c, {{1, 8}}); - } - { - constexpr auto x = L::Partial(1, 2, 3); - alignas(max_align_t) const unsigned char c[n] = {}; - x.PoisonPadding(c); - EXPECT_EQ(x.Slices(c), x.Slices(c)); - ExpectPoisoned(c, {{1, 8}, {36, 40}}); - } - { - constexpr auto x = L::Partial(1, 2, 3, 4); - alignas(max_align_t) const unsigned char c[n] = {}; - x.PoisonPadding(c); - EXPECT_EQ(x.Slices(c), x.Slices(c)); - ExpectPoisoned(c, {{1, 8}, {36, 40}}); - } - { - constexpr L x(1, 2, 3, 4); - alignas(max_align_t) const unsigned char c[n] = {}; - x.PoisonPadding(c); - EXPECT_EQ(x.Slices(c), x.Slices(c)); - ExpectPoisoned(c, {{1, 8}, {36, 40}}); - } -} - -TEST(Layout, DebugString) { - { - constexpr auto x = Layout<int8_t, int32_t, int8_t, Int128>::Partial(); - EXPECT_EQ("@0<signed char>(1)", x.DebugString()); - } - { - constexpr auto x = Layout<int8_t, int32_t, int8_t, Int128>::Partial(1); - EXPECT_EQ("@0<signed char>(1)[1]; @4<int>(4)", x.DebugString()); - } - { - constexpr auto x = Layout<int8_t, int32_t, int8_t, Int128>::Partial(1, 2); - EXPECT_EQ("@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)", - x.DebugString()); - } - { - constexpr auto x = - Layout<int8_t, int32_t, int8_t, Int128>::Partial(1, 2, 3); - EXPECT_EQ( - "@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)[3]; " - "@16" + - Int128::Name() + "(16)", - x.DebugString()); - } - { - constexpr auto x = - Layout<int8_t, int32_t, int8_t, Int128>::Partial(1, 2, 3, 4); - EXPECT_EQ( - "@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)[3]; " - "@16" + - Int128::Name() + "(16)[4]", - x.DebugString()); - } - { - constexpr Layout<int8_t, int32_t, int8_t, Int128> x(1, 2, 3, 4); - EXPECT_EQ( - "@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)[3]; " - "@16" + - Int128::Name() + "(16)[4]", - x.DebugString()); - } -} - -TEST(Layout, CharTypes) { - constexpr Layout<int32_t> x(1); - alignas(max_align_t) char c[x.AllocSize()] = {}; - alignas(max_align_t) unsigned char uc[x.AllocSize()] = {}; - alignas(max_align_t) signed char sc[x.AllocSize()] = {}; - alignas(max_align_t) const char cc[x.AllocSize()] = {}; - alignas(max_align_t) const unsigned char cuc[x.AllocSize()] = {}; - alignas(max_align_t) const signed char csc[x.AllocSize()] = {}; - - Type<int32_t*>(x.Pointer<0>(c)); - Type<int32_t*>(x.Pointer<0>(uc)); - Type<int32_t*>(x.Pointer<0>(sc)); - Type<const int32_t*>(x.Pointer<0>(cc)); - Type<const int32_t*>(x.Pointer<0>(cuc)); - Type<const int32_t*>(x.Pointer<0>(csc)); - - Type<int32_t*>(x.Pointer<int32_t>(c)); - Type<int32_t*>(x.Pointer<int32_t>(uc)); - Type<int32_t*>(x.Pointer<int32_t>(sc)); - Type<const int32_t*>(x.Pointer<int32_t>(cc)); - Type<const int32_t*>(x.Pointer<int32_t>(cuc)); - Type<const int32_t*>(x.Pointer<int32_t>(csc)); - - Type<std::tuple<int32_t*>>(x.Pointers(c)); - Type<std::tuple<int32_t*>>(x.Pointers(uc)); - Type<std::tuple<int32_t*>>(x.Pointers(sc)); - Type<std::tuple<const int32_t*>>(x.Pointers(cc)); - Type<std::tuple<const int32_t*>>(x.Pointers(cuc)); - Type<std::tuple<const int32_t*>>(x.Pointers(csc)); - - Type<Span<int32_t>>(x.Slice<0>(c)); - Type<Span<int32_t>>(x.Slice<0>(uc)); - Type<Span<int32_t>>(x.Slice<0>(sc)); - Type<Span<const int32_t>>(x.Slice<0>(cc)); - Type<Span<const int32_t>>(x.Slice<0>(cuc)); - Type<Span<const int32_t>>(x.Slice<0>(csc)); - - Type<std::tuple<Span<int32_t>>>(x.Slices(c)); - Type<std::tuple<Span<int32_t>>>(x.Slices(uc)); - Type<std::tuple<Span<int32_t>>>(x.Slices(sc)); - Type<std::tuple<Span<const int32_t>>>(x.Slices(cc)); - Type<std::tuple<Span<const int32_t>>>(x.Slices(cuc)); - Type<std::tuple<Span<const int32_t>>>(x.Slices(csc)); -} - -TEST(Layout, ConstElementType) { - constexpr Layout<const int32_t> x(1); - alignas(int32_t) char c[x.AllocSize()] = {}; - const char* cc = c; - const int32_t* p = reinterpret_cast<const int32_t*>(cc); - - EXPECT_EQ(alignof(int32_t), x.Alignment()); - - EXPECT_EQ(0, x.Offset<0>()); - EXPECT_EQ(0, x.Offset<const int32_t>()); - - EXPECT_THAT(x.Offsets(), ElementsAre(0)); - - EXPECT_EQ(1, x.Size<0>()); - EXPECT_EQ(1, x.Size<const int32_t>()); - - EXPECT_THAT(x.Sizes(), ElementsAre(1)); - - EXPECT_EQ(sizeof(int32_t), x.AllocSize()); - - EXPECT_EQ(p, Type<const int32_t*>(x.Pointer<0>(c))); - EXPECT_EQ(p, Type<const int32_t*>(x.Pointer<0>(cc))); - - EXPECT_EQ(p, Type<const int32_t*>(x.Pointer<const int32_t>(c))); - EXPECT_EQ(p, Type<const int32_t*>(x.Pointer<const int32_t>(cc))); - - EXPECT_THAT(Type<std::tuple<const int32_t*>>(x.Pointers(c)), Tuple(p)); - EXPECT_THAT(Type<std::tuple<const int32_t*>>(x.Pointers(cc)), Tuple(p)); - - EXPECT_THAT(Type<Span<const int32_t>>(x.Slice<0>(c)), - IsSameSlice(Span<const int32_t>(p, 1))); - EXPECT_THAT(Type<Span<const int32_t>>(x.Slice<0>(cc)), - IsSameSlice(Span<const int32_t>(p, 1))); - - EXPECT_THAT(Type<Span<const int32_t>>(x.Slice<const int32_t>(c)), - IsSameSlice(Span<const int32_t>(p, 1))); - EXPECT_THAT(Type<Span<const int32_t>>(x.Slice<const int32_t>(cc)), - IsSameSlice(Span<const int32_t>(p, 1))); - - EXPECT_THAT(Type<std::tuple<Span<const int32_t>>>(x.Slices(c)), - Tuple(IsSameSlice(Span<const int32_t>(p, 1)))); - EXPECT_THAT(Type<std::tuple<Span<const int32_t>>>(x.Slices(cc)), - Tuple(IsSameSlice(Span<const int32_t>(p, 1)))); -} - -namespace example { - -// Immutable move-only string with sizeof equal to sizeof(void*). The string -// size and the characters are kept in the same heap allocation. -class CompactString { - public: - CompactString(const char* s = "") { // NOLINT - const size_t size = strlen(s); - // size_t[1], followed by char[size + 1]. - // This statement doesn't allocate memory. - const L layout(1, size + 1); - // AllocSize() tells us how much memory we need to allocate for all our - // data. - p_.reset(new unsigned char[layout.AllocSize()]); - // If running under ASAN, mark the padding bytes, if any, to catch memory - // errors. - layout.PoisonPadding(p_.get()); - // Store the size in the allocation. - // Pointer<size_t>() is a synonym for Pointer<0>(). - *layout.Pointer<size_t>(p_.get()) = size; - // Store the characters in the allocation. - memcpy(layout.Pointer<char>(p_.get()), s, size + 1); - } - - size_t size() const { - // Equivalent to reinterpret_cast<size_t&>(*p). - return *L::Partial().Pointer<size_t>(p_.get()); - } - - const char* c_str() const { - // Equivalent to reinterpret_cast<char*>(p.get() + sizeof(size_t)). - // The argument in Partial(1) specifies that we have size_t[1] in front of - // the characters. - return L::Partial(1).Pointer<char>(p_.get()); - } - - private: - // Our heap allocation contains a size_t followed by an array of chars. - using L = Layout<size_t, char>; - std::unique_ptr<unsigned char[]> p_; -}; - -TEST(CompactString, Works) { - CompactString s = "hello"; - EXPECT_EQ(5, s.size()); - EXPECT_STREQ("hello", s.c_str()); -} - -} // namespace example - -} // namespace -} // namespace container_internal -ABSL_NAMESPACE_END -} // namespace absl |