00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "absl/container/internal/layout.h"
00016
00017
00018
00019 #include <stddef.h>
00020 #include <cstdint>
00021 #include <memory>
00022 #include <sstream>
00023 #include <type_traits>
00024
00025 #include "gmock/gmock.h"
00026 #include "gtest/gtest.h"
00027 #include "absl/base/internal/raw_logging.h"
00028 #include "absl/types/span.h"
00029
00030 namespace absl {
00031 namespace container_internal {
00032 namespace {
00033
00034 using ::absl::Span;
00035 using ::testing::ElementsAre;
00036
00037 size_t Distance(const void* from, const void* to) {
00038 ABSL_RAW_CHECK(from <= to, "Distance must be non-negative");
00039 return static_cast<const char*>(to) - static_cast<const char*>(from);
00040 }
00041
00042 template <class Expected, class Actual>
00043 Expected Type(Actual val) {
00044 static_assert(std::is_same<Expected, Actual>(), "");
00045 return val;
00046 }
00047
00048
00049 struct alignas(8) Int128 {
00050 uint64_t a, b;
00051 friend bool operator==(Int128 lhs, Int128 rhs) {
00052 return std::tie(lhs.a, lhs.b) == std::tie(rhs.a, rhs.b);
00053 }
00054
00055 static std::string Name() {
00056 return internal_layout::adl_barrier::TypeName<Int128>();
00057 }
00058 };
00059
00060
00061 struct alignas(8) Int64 {
00062 int64_t a;
00063 friend bool operator==(Int64 lhs, Int64 rhs) {
00064 return lhs.a == rhs.a;
00065 }
00066 };
00067
00068
00069 static_assert(sizeof(int8_t) == 1, "");
00070 static_assert(alignof(int8_t) == 1, "");
00071 static_assert(sizeof(int16_t) == 2, "");
00072 static_assert(alignof(int16_t) == 2, "");
00073 static_assert(sizeof(int32_t) == 4, "");
00074 static_assert(alignof(int32_t) == 4, "");
00075 static_assert(sizeof(Int64) == 8, "");
00076 static_assert(alignof(Int64) == 8, "");
00077 static_assert(sizeof(Int128) == 16, "");
00078 static_assert(alignof(Int128) == 8, "");
00079
00080 template <class Expected, class Actual>
00081 void SameType() {
00082 static_assert(std::is_same<Expected, Actual>(), "");
00083 }
00084
00085 TEST(Layout, ElementType) {
00086 {
00087 using L = Layout<int32_t>;
00088 SameType<int32_t, L::ElementType<0>>();
00089 SameType<int32_t, decltype(L::Partial())::ElementType<0>>();
00090 SameType<int32_t, decltype(L::Partial(0))::ElementType<0>>();
00091 }
00092 {
00093 using L = Layout<int32_t, int32_t>;
00094 SameType<int32_t, L::ElementType<0>>();
00095 SameType<int32_t, L::ElementType<1>>();
00096 SameType<int32_t, decltype(L::Partial())::ElementType<0>>();
00097 SameType<int32_t, decltype(L::Partial())::ElementType<1>>();
00098 SameType<int32_t, decltype(L::Partial(0))::ElementType<0>>();
00099 SameType<int32_t, decltype(L::Partial(0))::ElementType<1>>();
00100 }
00101 {
00102 using L = Layout<int8_t, int32_t, Int128>;
00103 SameType<int8_t, L::ElementType<0>>();
00104 SameType<int32_t, L::ElementType<1>>();
00105 SameType<Int128, L::ElementType<2>>();
00106 SameType<int8_t, decltype(L::Partial())::ElementType<0>>();
00107 SameType<int8_t, decltype(L::Partial(0))::ElementType<0>>();
00108 SameType<int32_t, decltype(L::Partial(0))::ElementType<1>>();
00109 SameType<int8_t, decltype(L::Partial(0, 0))::ElementType<0>>();
00110 SameType<int32_t, decltype(L::Partial(0, 0))::ElementType<1>>();
00111 SameType<Int128, decltype(L::Partial(0, 0))::ElementType<2>>();
00112 SameType<int8_t, decltype(L::Partial(0, 0, 0))::ElementType<0>>();
00113 SameType<int32_t, decltype(L::Partial(0, 0, 0))::ElementType<1>>();
00114 SameType<Int128, decltype(L::Partial(0, 0, 0))::ElementType<2>>();
00115 }
00116 }
00117
00118 TEST(Layout, ElementTypes) {
00119 {
00120 using L = Layout<int32_t>;
00121 SameType<std::tuple<int32_t>, L::ElementTypes>();
00122 SameType<std::tuple<int32_t>, decltype(L::Partial())::ElementTypes>();
00123 SameType<std::tuple<int32_t>, decltype(L::Partial(0))::ElementTypes>();
00124 }
00125 {
00126 using L = Layout<int32_t, int32_t>;
00127 SameType<std::tuple<int32_t, int32_t>, L::ElementTypes>();
00128 SameType<std::tuple<int32_t, int32_t>, decltype(L::Partial())::ElementTypes>();
00129 SameType<std::tuple<int32_t, int32_t>, decltype(L::Partial(0))::ElementTypes>();
00130 }
00131 {
00132 using L = Layout<int8_t, int32_t, Int128>;
00133 SameType<std::tuple<int8_t, int32_t, Int128>, L::ElementTypes>();
00134 SameType<std::tuple<int8_t, int32_t, Int128>,
00135 decltype(L::Partial())::ElementTypes>();
00136 SameType<std::tuple<int8_t, int32_t, Int128>,
00137 decltype(L::Partial(0))::ElementTypes>();
00138 SameType<std::tuple<int8_t, int32_t, Int128>,
00139 decltype(L::Partial(0, 0))::ElementTypes>();
00140 SameType<std::tuple<int8_t, int32_t, Int128>,
00141 decltype(L::Partial(0, 0, 0))::ElementTypes>();
00142 }
00143 }
00144
00145 TEST(Layout, OffsetByIndex) {
00146 {
00147 using L = Layout<int32_t>;
00148 EXPECT_EQ(0, L::Partial().Offset<0>());
00149 EXPECT_EQ(0, L::Partial(3).Offset<0>());
00150 EXPECT_EQ(0, L(3).Offset<0>());
00151 }
00152 {
00153 using L = Layout<int32_t, int32_t>;
00154 EXPECT_EQ(0, L::Partial().Offset<0>());
00155 EXPECT_EQ(0, L::Partial(3).Offset<0>());
00156 EXPECT_EQ(12, L::Partial(3).Offset<1>());
00157 EXPECT_EQ(0, L::Partial(3, 5).Offset<0>());
00158 EXPECT_EQ(12, L::Partial(3, 5).Offset<1>());
00159 EXPECT_EQ(0, L(3, 5).Offset<0>());
00160 EXPECT_EQ(12, L(3, 5).Offset<1>());
00161 }
00162 {
00163 using L = Layout<int8_t, int32_t, Int128>;
00164 EXPECT_EQ(0, L::Partial().Offset<0>());
00165 EXPECT_EQ(0, L::Partial(0).Offset<0>());
00166 EXPECT_EQ(0, L::Partial(0).Offset<1>());
00167 EXPECT_EQ(0, L::Partial(1).Offset<0>());
00168 EXPECT_EQ(4, L::Partial(1).Offset<1>());
00169 EXPECT_EQ(0, L::Partial(5).Offset<0>());
00170 EXPECT_EQ(8, L::Partial(5).Offset<1>());
00171 EXPECT_EQ(0, L::Partial(0, 0).Offset<0>());
00172 EXPECT_EQ(0, L::Partial(0, 0).Offset<1>());
00173 EXPECT_EQ(0, L::Partial(0, 0).Offset<2>());
00174 EXPECT_EQ(0, L::Partial(1, 0).Offset<0>());
00175 EXPECT_EQ(4, L::Partial(1, 0).Offset<1>());
00176 EXPECT_EQ(8, L::Partial(1, 0).Offset<2>());
00177 EXPECT_EQ(0, L::Partial(5, 3).Offset<0>());
00178 EXPECT_EQ(8, L::Partial(5, 3).Offset<1>());
00179 EXPECT_EQ(24, L::Partial(5, 3).Offset<2>());
00180 EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<0>());
00181 EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<1>());
00182 EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<2>());
00183 EXPECT_EQ(0, L::Partial(1, 0, 0).Offset<0>());
00184 EXPECT_EQ(4, L::Partial(1, 0, 0).Offset<1>());
00185 EXPECT_EQ(8, L::Partial(1, 0, 0).Offset<2>());
00186 EXPECT_EQ(0, L::Partial(5, 3, 1).Offset<0>());
00187 EXPECT_EQ(24, L::Partial(5, 3, 1).Offset<2>());
00188 EXPECT_EQ(8, L::Partial(5, 3, 1).Offset<1>());
00189 EXPECT_EQ(0, L(5, 3, 1).Offset<0>());
00190 EXPECT_EQ(24, L(5, 3, 1).Offset<2>());
00191 EXPECT_EQ(8, L(5, 3, 1).Offset<1>());
00192 }
00193 }
00194
00195 TEST(Layout, OffsetByType) {
00196 {
00197 using L = Layout<int32_t>;
00198 EXPECT_EQ(0, L::Partial().Offset<int32_t>());
00199 EXPECT_EQ(0, L::Partial(3).Offset<int32_t>());
00200 EXPECT_EQ(0, L(3).Offset<int32_t>());
00201 }
00202 {
00203 using L = Layout<int8_t, int32_t, Int128>;
00204 EXPECT_EQ(0, L::Partial().Offset<int8_t>());
00205 EXPECT_EQ(0, L::Partial(0).Offset<int8_t>());
00206 EXPECT_EQ(0, L::Partial(0).Offset<int32_t>());
00207 EXPECT_EQ(0, L::Partial(1).Offset<int8_t>());
00208 EXPECT_EQ(4, L::Partial(1).Offset<int32_t>());
00209 EXPECT_EQ(0, L::Partial(5).Offset<int8_t>());
00210 EXPECT_EQ(8, L::Partial(5).Offset<int32_t>());
00211 EXPECT_EQ(0, L::Partial(0, 0).Offset<int8_t>());
00212 EXPECT_EQ(0, L::Partial(0, 0).Offset<int32_t>());
00213 EXPECT_EQ(0, L::Partial(0, 0).Offset<Int128>());
00214 EXPECT_EQ(0, L::Partial(1, 0).Offset<int8_t>());
00215 EXPECT_EQ(4, L::Partial(1, 0).Offset<int32_t>());
00216 EXPECT_EQ(8, L::Partial(1, 0).Offset<Int128>());
00217 EXPECT_EQ(0, L::Partial(5, 3).Offset<int8_t>());
00218 EXPECT_EQ(8, L::Partial(5, 3).Offset<int32_t>());
00219 EXPECT_EQ(24, L::Partial(5, 3).Offset<Int128>());
00220 EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<int8_t>());
00221 EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<int32_t>());
00222 EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<Int128>());
00223 EXPECT_EQ(0, L::Partial(1, 0, 0).Offset<int8_t>());
00224 EXPECT_EQ(4, L::Partial(1, 0, 0).Offset<int32_t>());
00225 EXPECT_EQ(8, L::Partial(1, 0, 0).Offset<Int128>());
00226 EXPECT_EQ(0, L::Partial(5, 3, 1).Offset<int8_t>());
00227 EXPECT_EQ(24, L::Partial(5, 3, 1).Offset<Int128>());
00228 EXPECT_EQ(8, L::Partial(5, 3, 1).Offset<int32_t>());
00229 EXPECT_EQ(0, L(5, 3, 1).Offset<int8_t>());
00230 EXPECT_EQ(24, L(5, 3, 1).Offset<Int128>());
00231 EXPECT_EQ(8, L(5, 3, 1).Offset<int32_t>());
00232 }
00233 }
00234
00235 TEST(Layout, Offsets) {
00236 {
00237 using L = Layout<int32_t>;
00238 EXPECT_THAT(L::Partial().Offsets(), ElementsAre(0));
00239 EXPECT_THAT(L::Partial(3).Offsets(), ElementsAre(0));
00240 EXPECT_THAT(L(3).Offsets(), ElementsAre(0));
00241 }
00242 {
00243 using L = Layout<int32_t, int32_t>;
00244 EXPECT_THAT(L::Partial().Offsets(), ElementsAre(0));
00245 EXPECT_THAT(L::Partial(3).Offsets(), ElementsAre(0, 12));
00246 EXPECT_THAT(L::Partial(3, 5).Offsets(), ElementsAre(0, 12));
00247 EXPECT_THAT(L(3, 5).Offsets(), ElementsAre(0, 12));
00248 }
00249 {
00250 using L = Layout<int8_t, int32_t, Int128>;
00251 EXPECT_THAT(L::Partial().Offsets(), ElementsAre(0));
00252 EXPECT_THAT(L::Partial(1).Offsets(), ElementsAre(0, 4));
00253 EXPECT_THAT(L::Partial(5).Offsets(), ElementsAre(0, 8));
00254 EXPECT_THAT(L::Partial(0, 0).Offsets(), ElementsAre(0, 0, 0));
00255 EXPECT_THAT(L::Partial(1, 0).Offsets(), ElementsAre(0, 4, 8));
00256 EXPECT_THAT(L::Partial(5, 3).Offsets(), ElementsAre(0, 8, 24));
00257 EXPECT_THAT(L::Partial(0, 0, 0).Offsets(), ElementsAre(0, 0, 0));
00258 EXPECT_THAT(L::Partial(1, 0, 0).Offsets(), ElementsAre(0, 4, 8));
00259 EXPECT_THAT(L::Partial(5, 3, 1).Offsets(), ElementsAre(0, 8, 24));
00260 EXPECT_THAT(L(5, 3, 1).Offsets(), ElementsAre(0, 8, 24));
00261 }
00262 }
00263
00264 TEST(Layout, AllocSize) {
00265 {
00266 using L = Layout<int32_t>;
00267 EXPECT_EQ(0, L::Partial(0).AllocSize());
00268 EXPECT_EQ(12, L::Partial(3).AllocSize());
00269 EXPECT_EQ(12, L(3).AllocSize());
00270 }
00271 {
00272 using L = Layout<int32_t, int32_t>;
00273 EXPECT_EQ(32, L::Partial(3, 5).AllocSize());
00274 EXPECT_EQ(32, L(3, 5).AllocSize());
00275 }
00276 {
00277 using L = Layout<int8_t, int32_t, Int128>;
00278 EXPECT_EQ(0, L::Partial(0, 0, 0).AllocSize());
00279 EXPECT_EQ(8, L::Partial(1, 0, 0).AllocSize());
00280 EXPECT_EQ(8, L::Partial(0, 1, 0).AllocSize());
00281 EXPECT_EQ(16, L::Partial(0, 0, 1).AllocSize());
00282 EXPECT_EQ(24, L::Partial(1, 1, 1).AllocSize());
00283 EXPECT_EQ(136, L::Partial(3, 5, 7).AllocSize());
00284 EXPECT_EQ(136, L(3, 5, 7).AllocSize());
00285 }
00286 }
00287
00288 TEST(Layout, SizeByIndex) {
00289 {
00290 using L = Layout<int32_t>;
00291 EXPECT_EQ(0, L::Partial(0).Size<0>());
00292 EXPECT_EQ(3, L::Partial(3).Size<0>());
00293 EXPECT_EQ(3, L(3).Size<0>());
00294 }
00295 {
00296 using L = Layout<int32_t, int32_t>;
00297 EXPECT_EQ(0, L::Partial(0).Size<0>());
00298 EXPECT_EQ(3, L::Partial(3).Size<0>());
00299 EXPECT_EQ(3, L::Partial(3, 5).Size<0>());
00300 EXPECT_EQ(5, L::Partial(3, 5).Size<1>());
00301 EXPECT_EQ(3, L(3, 5).Size<0>());
00302 EXPECT_EQ(5, L(3, 5).Size<1>());
00303 }
00304 {
00305 using L = Layout<int8_t, int32_t, Int128>;
00306 EXPECT_EQ(3, L::Partial(3).Size<0>());
00307 EXPECT_EQ(3, L::Partial(3, 5).Size<0>());
00308 EXPECT_EQ(5, L::Partial(3, 5).Size<1>());
00309 EXPECT_EQ(3, L::Partial(3, 5, 7).Size<0>());
00310 EXPECT_EQ(5, L::Partial(3, 5, 7).Size<1>());
00311 EXPECT_EQ(7, L::Partial(3, 5, 7).Size<2>());
00312 EXPECT_EQ(3, L(3, 5, 7).Size<0>());
00313 EXPECT_EQ(5, L(3, 5, 7).Size<1>());
00314 EXPECT_EQ(7, L(3, 5, 7).Size<2>());
00315 }
00316 }
00317
00318 TEST(Layout, SizeByType) {
00319 {
00320 using L = Layout<int32_t>;
00321 EXPECT_EQ(0, L::Partial(0).Size<int32_t>());
00322 EXPECT_EQ(3, L::Partial(3).Size<int32_t>());
00323 EXPECT_EQ(3, L(3).Size<int32_t>());
00324 }
00325 {
00326 using L = Layout<int8_t, int32_t, Int128>;
00327 EXPECT_EQ(3, L::Partial(3).Size<int8_t>());
00328 EXPECT_EQ(3, L::Partial(3, 5).Size<int8_t>());
00329 EXPECT_EQ(5, L::Partial(3, 5).Size<int32_t>());
00330 EXPECT_EQ(3, L::Partial(3, 5, 7).Size<int8_t>());
00331 EXPECT_EQ(5, L::Partial(3, 5, 7).Size<int32_t>());
00332 EXPECT_EQ(7, L::Partial(3, 5, 7).Size<Int128>());
00333 EXPECT_EQ(3, L(3, 5, 7).Size<int8_t>());
00334 EXPECT_EQ(5, L(3, 5, 7).Size<int32_t>());
00335 EXPECT_EQ(7, L(3, 5, 7).Size<Int128>());
00336 }
00337 }
00338
00339 TEST(Layout, Sizes) {
00340 {
00341 using L = Layout<int32_t>;
00342 EXPECT_THAT(L::Partial().Sizes(), ElementsAre());
00343 EXPECT_THAT(L::Partial(3).Sizes(), ElementsAre(3));
00344 EXPECT_THAT(L(3).Sizes(), ElementsAre(3));
00345 }
00346 {
00347 using L = Layout<int32_t, int32_t>;
00348 EXPECT_THAT(L::Partial().Sizes(), ElementsAre());
00349 EXPECT_THAT(L::Partial(3).Sizes(), ElementsAre(3));
00350 EXPECT_THAT(L::Partial(3, 5).Sizes(), ElementsAre(3, 5));
00351 EXPECT_THAT(L(3, 5).Sizes(), ElementsAre(3, 5));
00352 }
00353 {
00354 using L = Layout<int8_t, int32_t, Int128>;
00355 EXPECT_THAT(L::Partial().Sizes(), ElementsAre());
00356 EXPECT_THAT(L::Partial(3).Sizes(), ElementsAre(3));
00357 EXPECT_THAT(L::Partial(3, 5).Sizes(), ElementsAre(3, 5));
00358 EXPECT_THAT(L::Partial(3, 5, 7).Sizes(), ElementsAre(3, 5, 7));
00359 EXPECT_THAT(L(3, 5, 7).Sizes(), ElementsAre(3, 5, 7));
00360 }
00361 }
00362
00363 TEST(Layout, PointerByIndex) {
00364 alignas(max_align_t) const unsigned char p[100] = {};
00365 {
00366 using L = Layout<int32_t>;
00367 EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L::Partial().Pointer<0>(p))));
00368 EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<0>(p))));
00369 EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L(3).Pointer<0>(p))));
00370 }
00371 {
00372 using L = Layout<int32_t, int32_t>;
00373 EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L::Partial().Pointer<0>(p))));
00374 EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<0>(p))));
00375 EXPECT_EQ(12, Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<1>(p))));
00376 EXPECT_EQ(0,
00377 Distance(p, Type<const int32_t*>(L::Partial(3, 5).Pointer<0>(p))));
00378 EXPECT_EQ(12,
00379 Distance(p, Type<const int32_t*>(L::Partial(3, 5).Pointer<1>(p))));
00380 EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L(3, 5).Pointer<0>(p))));
00381 EXPECT_EQ(12, Distance(p, Type<const int32_t*>(L(3, 5).Pointer<1>(p))));
00382 }
00383 {
00384 using L = Layout<int8_t, int32_t, Int128>;
00385 EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial().Pointer<0>(p))));
00386 EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial(0).Pointer<0>(p))));
00387 EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L::Partial(0).Pointer<1>(p))));
00388 EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial(1).Pointer<0>(p))));
00389 EXPECT_EQ(4, Distance(p, Type<const int32_t*>(L::Partial(1).Pointer<1>(p))));
00390 EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial(5).Pointer<0>(p))));
00391 EXPECT_EQ(8, Distance(p, Type<const int32_t*>(L::Partial(5).Pointer<1>(p))));
00392 EXPECT_EQ(0,
00393 Distance(p, Type<const int8_t*>(L::Partial(0, 0).Pointer<0>(p))));
00394 EXPECT_EQ(0,
00395 Distance(p, Type<const int32_t*>(L::Partial(0, 0).Pointer<1>(p))));
00396 EXPECT_EQ(0,
00397 Distance(p, Type<const Int128*>(L::Partial(0, 0).Pointer<2>(p))));
00398 EXPECT_EQ(0,
00399 Distance(p, Type<const int8_t*>(L::Partial(1, 0).Pointer<0>(p))));
00400 EXPECT_EQ(4,
00401 Distance(p, Type<const int32_t*>(L::Partial(1, 0).Pointer<1>(p))));
00402 EXPECT_EQ(8,
00403 Distance(p, Type<const Int128*>(L::Partial(1, 0).Pointer<2>(p))));
00404 EXPECT_EQ(0,
00405 Distance(p, Type<const int8_t*>(L::Partial(5, 3).Pointer<0>(p))));
00406 EXPECT_EQ(8,
00407 Distance(p, Type<const int32_t*>(L::Partial(5, 3).Pointer<1>(p))));
00408 EXPECT_EQ(24,
00409 Distance(p, Type<const Int128*>(L::Partial(5, 3).Pointer<2>(p))));
00410 EXPECT_EQ(
00411 0, Distance(p, Type<const int8_t*>(L::Partial(0, 0, 0).Pointer<0>(p))));
00412 EXPECT_EQ(
00413 0, Distance(p, Type<const int32_t*>(L::Partial(0, 0, 0).Pointer<1>(p))));
00414 EXPECT_EQ(
00415 0, Distance(p, Type<const Int128*>(L::Partial(0, 0, 0).Pointer<2>(p))));
00416 EXPECT_EQ(
00417 0, Distance(p, Type<const int8_t*>(L::Partial(1, 0, 0).Pointer<0>(p))));
00418 EXPECT_EQ(
00419 4, Distance(p, Type<const int32_t*>(L::Partial(1, 0, 0).Pointer<1>(p))));
00420 EXPECT_EQ(
00421 8, Distance(p, Type<const Int128*>(L::Partial(1, 0, 0).Pointer<2>(p))));
00422 EXPECT_EQ(
00423 0, Distance(p, Type<const int8_t*>(L::Partial(5, 3, 1).Pointer<0>(p))));
00424 EXPECT_EQ(
00425 24,
00426 Distance(p, Type<const Int128*>(L::Partial(5, 3, 1).Pointer<2>(p))));
00427 EXPECT_EQ(
00428 8, Distance(p, Type<const int32_t*>(L::Partial(5, 3, 1).Pointer<1>(p))));
00429 EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L(5, 3, 1).Pointer<0>(p))));
00430 EXPECT_EQ(24, Distance(p, Type<const Int128*>(L(5, 3, 1).Pointer<2>(p))));
00431 EXPECT_EQ(8, Distance(p, Type<const int32_t*>(L(5, 3, 1).Pointer<1>(p))));
00432 }
00433 }
00434
00435 TEST(Layout, PointerByType) {
00436 alignas(max_align_t) const unsigned char p[100] = {};
00437 {
00438 using L = Layout<int32_t>;
00439 EXPECT_EQ(0,
00440 Distance(p, Type<const int32_t*>(L::Partial().Pointer<int32_t>(p))));
00441 EXPECT_EQ(0,
00442 Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<int32_t>(p))));
00443 EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L(3).Pointer<int32_t>(p))));
00444 }
00445 {
00446 using L = Layout<int8_t, int32_t, Int128>;
00447 EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial().Pointer<int8_t>(p))));
00448 EXPECT_EQ(0,
00449 Distance(p, Type<const int8_t*>(L::Partial(0).Pointer<int8_t>(p))));
00450 EXPECT_EQ(0,
00451 Distance(p, Type<const int32_t*>(L::Partial(0).Pointer<int32_t>(p))));
00452 EXPECT_EQ(0,
00453 Distance(p, Type<const int8_t*>(L::Partial(1).Pointer<int8_t>(p))));
00454 EXPECT_EQ(4,
00455 Distance(p, Type<const int32_t*>(L::Partial(1).Pointer<int32_t>(p))));
00456 EXPECT_EQ(0,
00457 Distance(p, Type<const int8_t*>(L::Partial(5).Pointer<int8_t>(p))));
00458 EXPECT_EQ(8,
00459 Distance(p, Type<const int32_t*>(L::Partial(5).Pointer<int32_t>(p))));
00460 EXPECT_EQ(
00461 0, Distance(p, Type<const int8_t*>(L::Partial(0, 0).Pointer<int8_t>(p))));
00462 EXPECT_EQ(
00463 0, Distance(p, Type<const int32_t*>(L::Partial(0, 0).Pointer<int32_t>(p))));
00464 EXPECT_EQ(
00465 0,
00466 Distance(p, Type<const Int128*>(L::Partial(0, 0).Pointer<Int128>(p))));
00467 EXPECT_EQ(
00468 0, Distance(p, Type<const int8_t*>(L::Partial(1, 0).Pointer<int8_t>(p))));
00469 EXPECT_EQ(
00470 4, Distance(p, Type<const int32_t*>(L::Partial(1, 0).Pointer<int32_t>(p))));
00471 EXPECT_EQ(
00472 8,
00473 Distance(p, Type<const Int128*>(L::Partial(1, 0).Pointer<Int128>(p))));
00474 EXPECT_EQ(
00475 0, Distance(p, Type<const int8_t*>(L::Partial(5, 3).Pointer<int8_t>(p))));
00476 EXPECT_EQ(
00477 8, Distance(p, Type<const int32_t*>(L::Partial(5, 3).Pointer<int32_t>(p))));
00478 EXPECT_EQ(
00479 24,
00480 Distance(p, Type<const Int128*>(L::Partial(5, 3).Pointer<Int128>(p))));
00481 EXPECT_EQ(
00482 0,
00483 Distance(p, Type<const int8_t*>(L::Partial(0, 0, 0).Pointer<int8_t>(p))));
00484 EXPECT_EQ(
00485 0,
00486 Distance(p, Type<const int32_t*>(L::Partial(0, 0, 0).Pointer<int32_t>(p))));
00487 EXPECT_EQ(0, Distance(p, Type<const Int128*>(
00488 L::Partial(0, 0, 0).Pointer<Int128>(p))));
00489 EXPECT_EQ(
00490 0,
00491 Distance(p, Type<const int8_t*>(L::Partial(1, 0, 0).Pointer<int8_t>(p))));
00492 EXPECT_EQ(
00493 4,
00494 Distance(p, Type<const int32_t*>(L::Partial(1, 0, 0).Pointer<int32_t>(p))));
00495 EXPECT_EQ(8, Distance(p, Type<const Int128*>(
00496 L::Partial(1, 0, 0).Pointer<Int128>(p))));
00497 EXPECT_EQ(
00498 0,
00499 Distance(p, Type<const int8_t*>(L::Partial(5, 3, 1).Pointer<int8_t>(p))));
00500 EXPECT_EQ(24, Distance(p, Type<const Int128*>(
00501 L::Partial(5, 3, 1).Pointer<Int128>(p))));
00502 EXPECT_EQ(
00503 8,
00504 Distance(p, Type<const int32_t*>(L::Partial(5, 3, 1).Pointer<int32_t>(p))));
00505 EXPECT_EQ(24,
00506 Distance(p, Type<const Int128*>(L(5, 3, 1).Pointer<Int128>(p))));
00507 EXPECT_EQ(8, Distance(p, Type<const int32_t*>(L(5, 3, 1).Pointer<int32_t>(p))));
00508 }
00509 }
00510
00511 TEST(Layout, MutablePointerByIndex) {
00512 alignas(max_align_t) unsigned char p[100];
00513 {
00514 using L = Layout<int32_t>;
00515 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial().Pointer<0>(p))));
00516 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(3).Pointer<0>(p))));
00517 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L(3).Pointer<0>(p))));
00518 }
00519 {
00520 using L = Layout<int32_t, int32_t>;
00521 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial().Pointer<0>(p))));
00522 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(3).Pointer<0>(p))));
00523 EXPECT_EQ(12, Distance(p, Type<int32_t*>(L::Partial(3).Pointer<1>(p))));
00524 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(3, 5).Pointer<0>(p))));
00525 EXPECT_EQ(12, Distance(p, Type<int32_t*>(L::Partial(3, 5).Pointer<1>(p))));
00526 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L(3, 5).Pointer<0>(p))));
00527 EXPECT_EQ(12, Distance(p, Type<int32_t*>(L(3, 5).Pointer<1>(p))));
00528 }
00529 {
00530 using L = Layout<int8_t, int32_t, Int128>;
00531 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial().Pointer<0>(p))));
00532 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0).Pointer<0>(p))));
00533 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(0).Pointer<1>(p))));
00534 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1).Pointer<0>(p))));
00535 EXPECT_EQ(4, Distance(p, Type<int32_t*>(L::Partial(1).Pointer<1>(p))));
00536 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5).Pointer<0>(p))));
00537 EXPECT_EQ(8, Distance(p, Type<int32_t*>(L::Partial(5).Pointer<1>(p))));
00538 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0, 0).Pointer<0>(p))));
00539 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(0, 0).Pointer<1>(p))));
00540 EXPECT_EQ(0, Distance(p, Type<Int128*>(L::Partial(0, 0).Pointer<2>(p))));
00541 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1, 0).Pointer<0>(p))));
00542 EXPECT_EQ(4, Distance(p, Type<int32_t*>(L::Partial(1, 0).Pointer<1>(p))));
00543 EXPECT_EQ(8, Distance(p, Type<Int128*>(L::Partial(1, 0).Pointer<2>(p))));
00544 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5, 3).Pointer<0>(p))));
00545 EXPECT_EQ(8, Distance(p, Type<int32_t*>(L::Partial(5, 3).Pointer<1>(p))));
00546 EXPECT_EQ(24, Distance(p, Type<Int128*>(L::Partial(5, 3).Pointer<2>(p))));
00547 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0, 0, 0).Pointer<0>(p))));
00548 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(0, 0, 0).Pointer<1>(p))));
00549 EXPECT_EQ(0, Distance(p, Type<Int128*>(L::Partial(0, 0, 0).Pointer<2>(p))));
00550 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1, 0, 0).Pointer<0>(p))));
00551 EXPECT_EQ(4, Distance(p, Type<int32_t*>(L::Partial(1, 0, 0).Pointer<1>(p))));
00552 EXPECT_EQ(8, Distance(p, Type<Int128*>(L::Partial(1, 0, 0).Pointer<2>(p))));
00553 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5, 3, 1).Pointer<0>(p))));
00554 EXPECT_EQ(24,
00555 Distance(p, Type<Int128*>(L::Partial(5, 3, 1).Pointer<2>(p))));
00556 EXPECT_EQ(8, Distance(p, Type<int32_t*>(L::Partial(5, 3, 1).Pointer<1>(p))));
00557 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L(5, 3, 1).Pointer<0>(p))));
00558 EXPECT_EQ(24, Distance(p, Type<Int128*>(L(5, 3, 1).Pointer<2>(p))));
00559 EXPECT_EQ(8, Distance(p, Type<int32_t*>(L(5, 3, 1).Pointer<1>(p))));
00560 }
00561 }
00562
00563 TEST(Layout, MutablePointerByType) {
00564 alignas(max_align_t) unsigned char p[100];
00565 {
00566 using L = Layout<int32_t>;
00567 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial().Pointer<int32_t>(p))));
00568 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(3).Pointer<int32_t>(p))));
00569 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L(3).Pointer<int32_t>(p))));
00570 }
00571 {
00572 using L = Layout<int8_t, int32_t, Int128>;
00573 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial().Pointer<int8_t>(p))));
00574 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0).Pointer<int8_t>(p))));
00575 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(0).Pointer<int32_t>(p))));
00576 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1).Pointer<int8_t>(p))));
00577 EXPECT_EQ(4, Distance(p, Type<int32_t*>(L::Partial(1).Pointer<int32_t>(p))));
00578 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5).Pointer<int8_t>(p))));
00579 EXPECT_EQ(8, Distance(p, Type<int32_t*>(L::Partial(5).Pointer<int32_t>(p))));
00580 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0, 0).Pointer<int8_t>(p))));
00581 EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(0, 0).Pointer<int32_t>(p))));
00582 EXPECT_EQ(0,
00583 Distance(p, Type<Int128*>(L::Partial(0, 0).Pointer<Int128>(p))));
00584 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1, 0).Pointer<int8_t>(p))));
00585 EXPECT_EQ(4, Distance(p, Type<int32_t*>(L::Partial(1, 0).Pointer<int32_t>(p))));
00586 EXPECT_EQ(8,
00587 Distance(p, Type<Int128*>(L::Partial(1, 0).Pointer<Int128>(p))));
00588 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5, 3).Pointer<int8_t>(p))));
00589 EXPECT_EQ(8, Distance(p, Type<int32_t*>(L::Partial(5, 3).Pointer<int32_t>(p))));
00590 EXPECT_EQ(24,
00591 Distance(p, Type<Int128*>(L::Partial(5, 3).Pointer<Int128>(p))));
00592 EXPECT_EQ(0,
00593 Distance(p, Type<int8_t*>(L::Partial(0, 0, 0).Pointer<int8_t>(p))));
00594 EXPECT_EQ(0,
00595 Distance(p, Type<int32_t*>(L::Partial(0, 0, 0).Pointer<int32_t>(p))));
00596 EXPECT_EQ(
00597 0, Distance(p, Type<Int128*>(L::Partial(0, 0, 0).Pointer<Int128>(p))));
00598 EXPECT_EQ(0,
00599 Distance(p, Type<int8_t*>(L::Partial(1, 0, 0).Pointer<int8_t>(p))));
00600 EXPECT_EQ(4,
00601 Distance(p, Type<int32_t*>(L::Partial(1, 0, 0).Pointer<int32_t>(p))));
00602 EXPECT_EQ(
00603 8, Distance(p, Type<Int128*>(L::Partial(1, 0, 0).Pointer<Int128>(p))));
00604 EXPECT_EQ(0,
00605 Distance(p, Type<int8_t*>(L::Partial(5, 3, 1).Pointer<int8_t>(p))));
00606 EXPECT_EQ(
00607 24, Distance(p, Type<Int128*>(L::Partial(5, 3, 1).Pointer<Int128>(p))));
00608 EXPECT_EQ(8,
00609 Distance(p, Type<int32_t*>(L::Partial(5, 3, 1).Pointer<int32_t>(p))));
00610 EXPECT_EQ(0, Distance(p, Type<int8_t*>(L(5, 3, 1).Pointer<int8_t>(p))));
00611 EXPECT_EQ(24, Distance(p, Type<Int128*>(L(5, 3, 1).Pointer<Int128>(p))));
00612 EXPECT_EQ(8, Distance(p, Type<int32_t*>(L(5, 3, 1).Pointer<int32_t>(p))));
00613 }
00614 }
00615
00616 TEST(Layout, Pointers) {
00617 alignas(max_align_t) const unsigned char p[100] = {};
00618 using L = Layout<int8_t, int8_t, Int128>;
00619 {
00620 const auto x = L::Partial();
00621 EXPECT_EQ(std::make_tuple(x.Pointer<0>(p)),
00622 Type<std::tuple<const int8_t*>>(x.Pointers(p)));
00623 }
00624 {
00625 const auto x = L::Partial(1);
00626 EXPECT_EQ(std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p)),
00627 (Type<std::tuple<const int8_t*, const int8_t*>>(x.Pointers(p))));
00628 }
00629 {
00630 const auto x = L::Partial(1, 2);
00631 EXPECT_EQ(
00632 std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
00633 (Type<std::tuple<const int8_t*, const int8_t*, const Int128*>>(
00634 x.Pointers(p))));
00635 }
00636 {
00637 const auto x = L::Partial(1, 2, 3);
00638 EXPECT_EQ(
00639 std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
00640 (Type<std::tuple<const int8_t*, const int8_t*, const Int128*>>(
00641 x.Pointers(p))));
00642 }
00643 {
00644 const L x(1, 2, 3);
00645 EXPECT_EQ(
00646 std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
00647 (Type<std::tuple<const int8_t*, const int8_t*, const Int128*>>(
00648 x.Pointers(p))));
00649 }
00650 }
00651
00652 TEST(Layout, MutablePointers) {
00653 alignas(max_align_t) unsigned char p[100];
00654 using L = Layout<int8_t, int8_t, Int128>;
00655 {
00656 const auto x = L::Partial();
00657 EXPECT_EQ(std::make_tuple(x.Pointer<0>(p)),
00658 Type<std::tuple<int8_t*>>(x.Pointers(p)));
00659 }
00660 {
00661 const auto x = L::Partial(1);
00662 EXPECT_EQ(std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p)),
00663 (Type<std::tuple<int8_t*, int8_t*>>(x.Pointers(p))));
00664 }
00665 {
00666 const auto x = L::Partial(1, 2);
00667 EXPECT_EQ(
00668 std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
00669 (Type<std::tuple<int8_t*, int8_t*, Int128*>>(x.Pointers(p))));
00670 }
00671 {
00672 const auto x = L::Partial(1, 2, 3);
00673 EXPECT_EQ(
00674 std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
00675 (Type<std::tuple<int8_t*, int8_t*, Int128*>>(x.Pointers(p))));
00676 }
00677 {
00678 const L x(1, 2, 3);
00679 EXPECT_EQ(
00680 std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
00681 (Type<std::tuple<int8_t*, int8_t*, Int128*>>(x.Pointers(p))));
00682 }
00683 }
00684
00685 TEST(Layout, SliceByIndexSize) {
00686 alignas(max_align_t) const unsigned char p[100] = {};
00687 {
00688 using L = Layout<int32_t>;
00689 EXPECT_EQ(0, L::Partial(0).Slice<0>(p).size());
00690 EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size());
00691 EXPECT_EQ(3, L(3).Slice<0>(p).size());
00692 }
00693 {
00694 using L = Layout<int32_t, int32_t>;
00695 EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size());
00696 EXPECT_EQ(5, L::Partial(3, 5).Slice<1>(p).size());
00697 EXPECT_EQ(5, L(3, 5).Slice<1>(p).size());
00698 }
00699 {
00700 using L = Layout<int8_t, int32_t, Int128>;
00701 EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size());
00702 EXPECT_EQ(3, L::Partial(3, 5).Slice<0>(p).size());
00703 EXPECT_EQ(5, L::Partial(3, 5).Slice<1>(p).size());
00704 EXPECT_EQ(3, L::Partial(3, 5, 7).Slice<0>(p).size());
00705 EXPECT_EQ(5, L::Partial(3, 5, 7).Slice<1>(p).size());
00706 EXPECT_EQ(7, L::Partial(3, 5, 7).Slice<2>(p).size());
00707 EXPECT_EQ(3, L(3, 5, 7).Slice<0>(p).size());
00708 EXPECT_EQ(5, L(3, 5, 7).Slice<1>(p).size());
00709 EXPECT_EQ(7, L(3, 5, 7).Slice<2>(p).size());
00710 }
00711 }
00712
00713 TEST(Layout, SliceByTypeSize) {
00714 alignas(max_align_t) const unsigned char p[100] = {};
00715 {
00716 using L = Layout<int32_t>;
00717 EXPECT_EQ(0, L::Partial(0).Slice<int32_t>(p).size());
00718 EXPECT_EQ(3, L::Partial(3).Slice<int32_t>(p).size());
00719 EXPECT_EQ(3, L(3).Slice<int32_t>(p).size());
00720 }
00721 {
00722 using L = Layout<int8_t, int32_t, Int128>;
00723 EXPECT_EQ(3, L::Partial(3).Slice<int8_t>(p).size());
00724 EXPECT_EQ(3, L::Partial(3, 5).Slice<int8_t>(p).size());
00725 EXPECT_EQ(5, L::Partial(3, 5).Slice<int32_t>(p).size());
00726 EXPECT_EQ(3, L::Partial(3, 5, 7).Slice<int8_t>(p).size());
00727 EXPECT_EQ(5, L::Partial(3, 5, 7).Slice<int32_t>(p).size());
00728 EXPECT_EQ(7, L::Partial(3, 5, 7).Slice<Int128>(p).size());
00729 EXPECT_EQ(3, L(3, 5, 7).Slice<int8_t>(p).size());
00730 EXPECT_EQ(5, L(3, 5, 7).Slice<int32_t>(p).size());
00731 EXPECT_EQ(7, L(3, 5, 7).Slice<Int128>(p).size());
00732 }
00733 }
00734
00735 TEST(Layout, MutableSliceByIndexSize) {
00736 alignas(max_align_t) unsigned char p[100];
00737 {
00738 using L = Layout<int32_t>;
00739 EXPECT_EQ(0, L::Partial(0).Slice<0>(p).size());
00740 EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size());
00741 EXPECT_EQ(3, L(3).Slice<0>(p).size());
00742 }
00743 {
00744 using L = Layout<int32_t, int32_t>;
00745 EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size());
00746 EXPECT_EQ(5, L::Partial(3, 5).Slice<1>(p).size());
00747 EXPECT_EQ(5, L(3, 5).Slice<1>(p).size());
00748 }
00749 {
00750 using L = Layout<int8_t, int32_t, Int128>;
00751 EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size());
00752 EXPECT_EQ(3, L::Partial(3, 5).Slice<0>(p).size());
00753 EXPECT_EQ(5, L::Partial(3, 5).Slice<1>(p).size());
00754 EXPECT_EQ(3, L::Partial(3, 5, 7).Slice<0>(p).size());
00755 EXPECT_EQ(5, L::Partial(3, 5, 7).Slice<1>(p).size());
00756 EXPECT_EQ(7, L::Partial(3, 5, 7).Slice<2>(p).size());
00757 EXPECT_EQ(3, L(3, 5, 7).Slice<0>(p).size());
00758 EXPECT_EQ(5, L(3, 5, 7).Slice<1>(p).size());
00759 EXPECT_EQ(7, L(3, 5, 7).Slice<2>(p).size());
00760 }
00761 }
00762
00763 TEST(Layout, MutableSliceByTypeSize) {
00764 alignas(max_align_t) unsigned char p[100];
00765 {
00766 using L = Layout<int32_t>;
00767 EXPECT_EQ(0, L::Partial(0).Slice<int32_t>(p).size());
00768 EXPECT_EQ(3, L::Partial(3).Slice<int32_t>(p).size());
00769 EXPECT_EQ(3, L(3).Slice<int32_t>(p).size());
00770 }
00771 {
00772 using L = Layout<int8_t, int32_t, Int128>;
00773 EXPECT_EQ(3, L::Partial(3).Slice<int8_t>(p).size());
00774 EXPECT_EQ(3, L::Partial(3, 5).Slice<int8_t>(p).size());
00775 EXPECT_EQ(5, L::Partial(3, 5).Slice<int32_t>(p).size());
00776 EXPECT_EQ(3, L::Partial(3, 5, 7).Slice<int8_t>(p).size());
00777 EXPECT_EQ(5, L::Partial(3, 5, 7).Slice<int32_t>(p).size());
00778 EXPECT_EQ(7, L::Partial(3, 5, 7).Slice<Int128>(p).size());
00779 EXPECT_EQ(3, L(3, 5, 7).Slice<int8_t>(p).size());
00780 EXPECT_EQ(5, L(3, 5, 7).Slice<int32_t>(p).size());
00781 EXPECT_EQ(7, L(3, 5, 7).Slice<Int128>(p).size());
00782 }
00783 }
00784
00785 TEST(Layout, SliceByIndexData) {
00786 alignas(max_align_t) const unsigned char p[100] = {};
00787 {
00788 using L = Layout<int32_t>;
00789 EXPECT_EQ(
00790 0,
00791 Distance(p, Type<Span<const int32_t>>(L::Partial(0).Slice<0>(p)).data()));
00792 EXPECT_EQ(
00793 0,
00794 Distance(p, Type<Span<const int32_t>>(L::Partial(3).Slice<0>(p)).data()));
00795 EXPECT_EQ(0, Distance(p, Type<Span<const int32_t>>(L(3).Slice<0>(p)).data()));
00796 }
00797 {
00798 using L = Layout<int32_t, int32_t>;
00799 EXPECT_EQ(
00800 0,
00801 Distance(p, Type<Span<const int32_t>>(L::Partial(3).Slice<0>(p)).data()));
00802 EXPECT_EQ(
00803 0,
00804 Distance(p,
00805 Type<Span<const int32_t>>(L::Partial(3, 5).Slice<0>(p)).data()));
00806 EXPECT_EQ(
00807 12,
00808 Distance(p,
00809 Type<Span<const int32_t>>(L::Partial(3, 5).Slice<1>(p)).data()));
00810 EXPECT_EQ(0,
00811 Distance(p, Type<Span<const int32_t>>(L(3, 5).Slice<0>(p)).data()));
00812 EXPECT_EQ(12,
00813 Distance(p, Type<Span<const int32_t>>(L(3, 5).Slice<1>(p)).data()));
00814 }
00815 {
00816 using L = Layout<int8_t, int32_t, Int128>;
00817 EXPECT_EQ(
00818 0,
00819 Distance(p, Type<Span<const int8_t>>(L::Partial(0).Slice<0>(p)).data()));
00820 EXPECT_EQ(
00821 0,
00822 Distance(p, Type<Span<const int8_t>>(L::Partial(1).Slice<0>(p)).data()));
00823 EXPECT_EQ(
00824 0,
00825 Distance(p, Type<Span<const int8_t>>(L::Partial(5).Slice<0>(p)).data()));
00826 EXPECT_EQ(
00827 0, Distance(
00828 p, Type<Span<const int8_t>>(L::Partial(0, 0).Slice<0>(p)).data()));
00829 EXPECT_EQ(
00830 0,
00831 Distance(p,
00832 Type<Span<const int32_t>>(L::Partial(0, 0).Slice<1>(p)).data()));
00833 EXPECT_EQ(
00834 0, Distance(
00835 p, Type<Span<const int8_t>>(L::Partial(1, 0).Slice<0>(p)).data()));
00836 EXPECT_EQ(
00837 4,
00838 Distance(p,
00839 Type<Span<const int32_t>>(L::Partial(1, 0).Slice<1>(p)).data()));
00840 EXPECT_EQ(
00841 0, Distance(
00842 p, Type<Span<const int8_t>>(L::Partial(5, 3).Slice<0>(p)).data()));
00843 EXPECT_EQ(
00844 8,
00845 Distance(p,
00846 Type<Span<const int32_t>>(L::Partial(5, 3).Slice<1>(p)).data()));
00847 EXPECT_EQ(
00848 0,
00849 Distance(
00850 p, Type<Span<const int8_t>>(L::Partial(0, 0, 0).Slice<0>(p)).data()));
00851 EXPECT_EQ(
00852 0,
00853 Distance(
00854 p,
00855 Type<Span<const int32_t>>(L::Partial(0, 0, 0).Slice<1>(p)).data()));
00856 EXPECT_EQ(
00857 0,
00858 Distance(
00859 p,
00860 Type<Span<const Int128>>(L::Partial(0, 0, 0).Slice<2>(p)).data()));
00861 EXPECT_EQ(
00862 0,
00863 Distance(
00864 p, Type<Span<const int8_t>>(L::Partial(1, 0, 0).Slice<0>(p)).data()));
00865 EXPECT_EQ(
00866 4,
00867 Distance(
00868 p,
00869 Type<Span<const int32_t>>(L::Partial(1, 0, 0).Slice<1>(p)).data()));
00870 EXPECT_EQ(
00871 8,
00872 Distance(
00873 p,
00874 Type<Span<const Int128>>(L::Partial(1, 0, 0).Slice<2>(p)).data()));
00875 EXPECT_EQ(
00876 0,
00877 Distance(
00878 p, Type<Span<const int8_t>>(L::Partial(5, 3, 1).Slice<0>(p)).data()));
00879 EXPECT_EQ(
00880 24,
00881 Distance(
00882 p,
00883 Type<Span<const Int128>>(L::Partial(5, 3, 1).Slice<2>(p)).data()));
00884 EXPECT_EQ(
00885 8,
00886 Distance(
00887 p,
00888 Type<Span<const int32_t>>(L::Partial(5, 3, 1).Slice<1>(p)).data()));
00889 EXPECT_EQ(
00890 0, Distance(p, Type<Span<const int8_t>>(L(5, 3, 1).Slice<0>(p)).data()));
00891 EXPECT_EQ(
00892 24,
00893 Distance(p, Type<Span<const Int128>>(L(5, 3, 1).Slice<2>(p)).data()));
00894 EXPECT_EQ(
00895 8, Distance(p, Type<Span<const int32_t>>(L(5, 3, 1).Slice<1>(p)).data()));
00896 }
00897 }
00898
00899 TEST(Layout, SliceByTypeData) {
00900 alignas(max_align_t) const unsigned char p[100] = {};
00901 {
00902 using L = Layout<int32_t>;
00903 EXPECT_EQ(
00904 0,
00905 Distance(
00906 p, Type<Span<const int32_t>>(L::Partial(0).Slice<int32_t>(p)).data()));
00907 EXPECT_EQ(
00908 0,
00909 Distance(
00910 p, Type<Span<const int32_t>>(L::Partial(3).Slice<int32_t>(p)).data()));
00911 EXPECT_EQ(
00912 0, Distance(p, Type<Span<const int32_t>>(L(3).Slice<int32_t>(p)).data()));
00913 }
00914 {
00915 using L = Layout<int8_t, int32_t, Int128>;
00916 EXPECT_EQ(
00917 0, Distance(
00918 p, Type<Span<const int8_t>>(L::Partial(0).Slice<int8_t>(p)).data()));
00919 EXPECT_EQ(
00920 0, Distance(
00921 p, Type<Span<const int8_t>>(L::Partial(1).Slice<int8_t>(p)).data()));
00922 EXPECT_EQ(
00923 0, Distance(
00924 p, Type<Span<const int8_t>>(L::Partial(5).Slice<int8_t>(p)).data()));
00925 EXPECT_EQ(
00926 0,
00927 Distance(
00928 p, Type<Span<const int8_t>>(L::Partial(0, 0).Slice<int8_t>(p)).data()));
00929 EXPECT_EQ(
00930 0,
00931 Distance(
00932 p,
00933 Type<Span<const int32_t>>(L::Partial(0, 0).Slice<int32_t>(p)).data()));
00934 EXPECT_EQ(
00935 0,
00936 Distance(
00937 p, Type<Span<const int8_t>>(L::Partial(1, 0).Slice<int8_t>(p)).data()));
00938 EXPECT_EQ(
00939 4,
00940 Distance(
00941 p,
00942 Type<Span<const int32_t>>(L::Partial(1, 0).Slice<int32_t>(p)).data()));
00943 EXPECT_EQ(
00944 0,
00945 Distance(
00946 p, Type<Span<const int8_t>>(L::Partial(5, 3).Slice<int8_t>(p)).data()));
00947 EXPECT_EQ(
00948 8,
00949 Distance(
00950 p,
00951 Type<Span<const int32_t>>(L::Partial(5, 3).Slice<int32_t>(p)).data()));
00952 EXPECT_EQ(
00953 0,
00954 Distance(
00955 p,
00956 Type<Span<const int8_t>>(L::Partial(0, 0, 0).Slice<int8_t>(p)).data()));
00957 EXPECT_EQ(
00958 0,
00959 Distance(p, Type<Span<const int32_t>>(L::Partial(0, 0, 0).Slice<int32_t>(p))
00960 .data()));
00961 EXPECT_EQ(0, Distance(p, Type<Span<const Int128>>(
00962 L::Partial(0, 0, 0).Slice<Int128>(p))
00963 .data()));
00964 EXPECT_EQ(
00965 0,
00966 Distance(
00967 p,
00968 Type<Span<const int8_t>>(L::Partial(1, 0, 0).Slice<int8_t>(p)).data()));
00969 EXPECT_EQ(
00970 4,
00971 Distance(p, Type<Span<const int32_t>>(L::Partial(1, 0, 0).Slice<int32_t>(p))
00972 .data()));
00973 EXPECT_EQ(8, Distance(p, Type<Span<const Int128>>(
00974 L::Partial(1, 0, 0).Slice<Int128>(p))
00975 .data()));
00976 EXPECT_EQ(
00977 0,
00978 Distance(
00979 p,
00980 Type<Span<const int8_t>>(L::Partial(5, 3, 1).Slice<int8_t>(p)).data()));
00981 EXPECT_EQ(24, Distance(p, Type<Span<const Int128>>(
00982 L::Partial(5, 3, 1).Slice<Int128>(p))
00983 .data()));
00984 EXPECT_EQ(
00985 8,
00986 Distance(p, Type<Span<const int32_t>>(L::Partial(5, 3, 1).Slice<int32_t>(p))
00987 .data()));
00988 EXPECT_EQ(
00989 0,
00990 Distance(p, Type<Span<const int8_t>>(L(5, 3, 1).Slice<int8_t>(p)).data()));
00991 EXPECT_EQ(
00992 24,
00993 Distance(p,
00994 Type<Span<const Int128>>(L(5, 3, 1).Slice<Int128>(p)).data()));
00995 EXPECT_EQ(
00996 8, Distance(
00997 p, Type<Span<const int32_t>>(L(5, 3, 1).Slice<int32_t>(p)).data()));
00998 }
00999 }
01000
01001 TEST(Layout, MutableSliceByIndexData) {
01002 alignas(max_align_t) unsigned char p[100];
01003 {
01004 using L = Layout<int32_t>;
01005 EXPECT_EQ(0,
01006 Distance(p, Type<Span<int32_t>>(L::Partial(0).Slice<0>(p)).data()));
01007 EXPECT_EQ(0,
01008 Distance(p, Type<Span<int32_t>>(L::Partial(3).Slice<0>(p)).data()));
01009 EXPECT_EQ(0, Distance(p, Type<Span<int32_t>>(L(3).Slice<0>(p)).data()));
01010 }
01011 {
01012 using L = Layout<int32_t, int32_t>;
01013 EXPECT_EQ(0,
01014 Distance(p, Type<Span<int32_t>>(L::Partial(3).Slice<0>(p)).data()));
01015 EXPECT_EQ(
01016 0, Distance(p, Type<Span<int32_t>>(L::Partial(3, 5).Slice<0>(p)).data()));
01017 EXPECT_EQ(
01018 12,
01019 Distance(p, Type<Span<int32_t>>(L::Partial(3, 5).Slice<1>(p)).data()));
01020 EXPECT_EQ(0, Distance(p, Type<Span<int32_t>>(L(3, 5).Slice<0>(p)).data()));
01021 EXPECT_EQ(12, Distance(p, Type<Span<int32_t>>(L(3, 5).Slice<1>(p)).data()));
01022 }
01023 {
01024 using L = Layout<int8_t, int32_t, Int128>;
01025 EXPECT_EQ(0,
01026 Distance(p, Type<Span<int8_t>>(L::Partial(0).Slice<0>(p)).data()));
01027 EXPECT_EQ(0,
01028 Distance(p, Type<Span<int8_t>>(L::Partial(1).Slice<0>(p)).data()));
01029 EXPECT_EQ(0,
01030 Distance(p, Type<Span<int8_t>>(L::Partial(5).Slice<0>(p)).data()));
01031 EXPECT_EQ(
01032 0, Distance(p, Type<Span<int8_t>>(L::Partial(0, 0).Slice<0>(p)).data()));
01033 EXPECT_EQ(
01034 0, Distance(p, Type<Span<int32_t>>(L::Partial(0, 0).Slice<1>(p)).data()));
01035 EXPECT_EQ(
01036 0, Distance(p, Type<Span<int8_t>>(L::Partial(1, 0).Slice<0>(p)).data()));
01037 EXPECT_EQ(
01038 4, Distance(p, Type<Span<int32_t>>(L::Partial(1, 0).Slice<1>(p)).data()));
01039 EXPECT_EQ(
01040 0, Distance(p, Type<Span<int8_t>>(L::Partial(5, 3).Slice<0>(p)).data()));
01041 EXPECT_EQ(
01042 8, Distance(p, Type<Span<int32_t>>(L::Partial(5, 3).Slice<1>(p)).data()));
01043 EXPECT_EQ(
01044 0,
01045 Distance(p, Type<Span<int8_t>>(L::Partial(0, 0, 0).Slice<0>(p)).data()));
01046 EXPECT_EQ(
01047 0,
01048 Distance(p, Type<Span<int32_t>>(L::Partial(0, 0, 0).Slice<1>(p)).data()));
01049 EXPECT_EQ(
01050 0, Distance(
01051 p, Type<Span<Int128>>(L::Partial(0, 0, 0).Slice<2>(p)).data()));
01052 EXPECT_EQ(
01053 0,
01054 Distance(p, Type<Span<int8_t>>(L::Partial(1, 0, 0).Slice<0>(p)).data()));
01055 EXPECT_EQ(
01056 4,
01057 Distance(p, Type<Span<int32_t>>(L::Partial(1, 0, 0).Slice<1>(p)).data()));
01058 EXPECT_EQ(
01059 8, Distance(
01060 p, Type<Span<Int128>>(L::Partial(1, 0, 0).Slice<2>(p)).data()));
01061 EXPECT_EQ(
01062 0,
01063 Distance(p, Type<Span<int8_t>>(L::Partial(5, 3, 1).Slice<0>(p)).data()));
01064 EXPECT_EQ(
01065 24, Distance(
01066 p, Type<Span<Int128>>(L::Partial(5, 3, 1).Slice<2>(p)).data()));
01067 EXPECT_EQ(
01068 8,
01069 Distance(p, Type<Span<int32_t>>(L::Partial(5, 3, 1).Slice<1>(p)).data()));
01070 EXPECT_EQ(0, Distance(p, Type<Span<int8_t>>(L(5, 3, 1).Slice<0>(p)).data()));
01071 EXPECT_EQ(24,
01072 Distance(p, Type<Span<Int128>>(L(5, 3, 1).Slice<2>(p)).data()));
01073 EXPECT_EQ(8, Distance(p, Type<Span<int32_t>>(L(5, 3, 1).Slice<1>(p)).data()));
01074 }
01075 }
01076
01077 TEST(Layout, MutableSliceByTypeData) {
01078 alignas(max_align_t) unsigned char p[100];
01079 {
01080 using L = Layout<int32_t>;
01081 EXPECT_EQ(
01082 0,
01083 Distance(p, Type<Span<int32_t>>(L::Partial(0).Slice<int32_t>(p)).data()));
01084 EXPECT_EQ(
01085 0,
01086 Distance(p, Type<Span<int32_t>>(L::Partial(3).Slice<int32_t>(p)).data()));
01087 EXPECT_EQ(0, Distance(p, Type<Span<int32_t>>(L(3).Slice<int32_t>(p)).data()));
01088 }
01089 {
01090 using L = Layout<int8_t, int32_t, Int128>;
01091 EXPECT_EQ(
01092 0, Distance(p, Type<Span<int8_t>>(L::Partial(0).Slice<int8_t>(p)).data()));
01093 EXPECT_EQ(
01094 0, Distance(p, Type<Span<int8_t>>(L::Partial(1).Slice<int8_t>(p)).data()));
01095 EXPECT_EQ(
01096 0, Distance(p, Type<Span<int8_t>>(L::Partial(5).Slice<int8_t>(p)).data()));
01097 EXPECT_EQ(
01098 0,
01099 Distance(p, Type<Span<int8_t>>(L::Partial(0, 0).Slice<int8_t>(p)).data()));
01100 EXPECT_EQ(
01101 0, Distance(
01102 p, Type<Span<int32_t>>(L::Partial(0, 0).Slice<int32_t>(p)).data()));
01103 EXPECT_EQ(
01104 0,
01105 Distance(p, Type<Span<int8_t>>(L::Partial(1, 0).Slice<int8_t>(p)).data()));
01106 EXPECT_EQ(
01107 4, Distance(
01108 p, Type<Span<int32_t>>(L::Partial(1, 0).Slice<int32_t>(p)).data()));
01109 EXPECT_EQ(
01110 0,
01111 Distance(p, Type<Span<int8_t>>(L::Partial(5, 3).Slice<int8_t>(p)).data()));
01112 EXPECT_EQ(
01113 8, Distance(
01114 p, Type<Span<int32_t>>(L::Partial(5, 3).Slice<int32_t>(p)).data()));
01115 EXPECT_EQ(
01116 0, Distance(
01117 p, Type<Span<int8_t>>(L::Partial(0, 0, 0).Slice<int8_t>(p)).data()));
01118 EXPECT_EQ(
01119 0,
01120 Distance(
01121 p, Type<Span<int32_t>>(L::Partial(0, 0, 0).Slice<int32_t>(p)).data()));
01122 EXPECT_EQ(
01123 0,
01124 Distance(
01125 p,
01126 Type<Span<Int128>>(L::Partial(0, 0, 0).Slice<Int128>(p)).data()));
01127 EXPECT_EQ(
01128 0, Distance(
01129 p, Type<Span<int8_t>>(L::Partial(1, 0, 0).Slice<int8_t>(p)).data()));
01130 EXPECT_EQ(
01131 4,
01132 Distance(
01133 p, Type<Span<int32_t>>(L::Partial(1, 0, 0).Slice<int32_t>(p)).data()));
01134 EXPECT_EQ(
01135 8,
01136 Distance(
01137 p,
01138 Type<Span<Int128>>(L::Partial(1, 0, 0).Slice<Int128>(p)).data()));
01139 EXPECT_EQ(
01140 0, Distance(
01141 p, Type<Span<int8_t>>(L::Partial(5, 3, 1).Slice<int8_t>(p)).data()));
01142 EXPECT_EQ(
01143 24,
01144 Distance(
01145 p,
01146 Type<Span<Int128>>(L::Partial(5, 3, 1).Slice<Int128>(p)).data()));
01147 EXPECT_EQ(
01148 8,
01149 Distance(
01150 p, Type<Span<int32_t>>(L::Partial(5, 3, 1).Slice<int32_t>(p)).data()));
01151 EXPECT_EQ(0,
01152 Distance(p, Type<Span<int8_t>>(L(5, 3, 1).Slice<int8_t>(p)).data()));
01153 EXPECT_EQ(
01154 24,
01155 Distance(p, Type<Span<Int128>>(L(5, 3, 1).Slice<Int128>(p)).data()));
01156 EXPECT_EQ(
01157 8, Distance(p, Type<Span<int32_t>>(L(5, 3, 1).Slice<int32_t>(p)).data()));
01158 }
01159 }
01160
01161 MATCHER_P(IsSameSlice, slice, "") {
01162 return arg.size() == slice.size() && arg.data() == slice.data();
01163 }
01164
01165 template <typename... M>
01166 class TupleMatcher {
01167 public:
01168 explicit TupleMatcher(M... matchers) : matchers_(std::move(matchers)...) {}
01169
01170 template <typename Tuple>
01171 bool MatchAndExplain(const Tuple& p,
01172 testing::MatchResultListener* ) const {
01173 static_assert(std::tuple_size<Tuple>::value == sizeof...(M), "");
01174 return MatchAndExplainImpl(
01175 p, absl::make_index_sequence<std::tuple_size<Tuple>::value>{});
01176 }
01177
01178
01179
01180 void DescribeTo(::std::ostream* os) const {}
01181 void DescribeNegationTo(::std::ostream* os) const {}
01182
01183 private:
01184 template <typename Tuple, size_t... Is>
01185 bool MatchAndExplainImpl(const Tuple& p, absl::index_sequence<Is...>) const {
01186
01187 return std::min(
01188 {true, testing::SafeMatcherCast<
01189 const typename std::tuple_element<Is, Tuple>::type&>(
01190 std::get<Is>(matchers_))
01191 .Matches(std::get<Is>(p))...});
01192 }
01193
01194 std::tuple<M...> matchers_;
01195 };
01196
01197 template <typename... M>
01198 testing::PolymorphicMatcher<TupleMatcher<M...>> Tuple(M... matchers) {
01199 return testing::MakePolymorphicMatcher(
01200 TupleMatcher<M...>(std::move(matchers)...));
01201 }
01202
01203 TEST(Layout, Slices) {
01204 alignas(max_align_t) const unsigned char p[100] = {};
01205 using L = Layout<int8_t, int8_t, Int128>;
01206 {
01207 const auto x = L::Partial();
01208 EXPECT_THAT(Type<std::tuple<>>(x.Slices(p)), Tuple());
01209 }
01210 {
01211 const auto x = L::Partial(1);
01212 EXPECT_THAT(Type<std::tuple<Span<const int8_t>>>(x.Slices(p)),
01213 Tuple(IsSameSlice(x.Slice<0>(p))));
01214 }
01215 {
01216 const auto x = L::Partial(1, 2);
01217 EXPECT_THAT(
01218 (Type<std::tuple<Span<const int8_t>, Span<const int8_t>>>(x.Slices(p))),
01219 Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p))));
01220 }
01221 {
01222 const auto x = L::Partial(1, 2, 3);
01223 EXPECT_THAT((Type<std::tuple<Span<const int8_t>, Span<const int8_t>,
01224 Span<const Int128>>>(x.Slices(p))),
01225 Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)),
01226 IsSameSlice(x.Slice<2>(p))));
01227 }
01228 {
01229 const L x(1, 2, 3);
01230 EXPECT_THAT((Type<std::tuple<Span<const int8_t>, Span<const int8_t>,
01231 Span<const Int128>>>(x.Slices(p))),
01232 Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)),
01233 IsSameSlice(x.Slice<2>(p))));
01234 }
01235 }
01236
01237 TEST(Layout, MutableSlices) {
01238 alignas(max_align_t) unsigned char p[100] = {};
01239 using L = Layout<int8_t, int8_t, Int128>;
01240 {
01241 const auto x = L::Partial();
01242 EXPECT_THAT(Type<std::tuple<>>(x.Slices(p)), Tuple());
01243 }
01244 {
01245 const auto x = L::Partial(1);
01246 EXPECT_THAT(Type<std::tuple<Span<int8_t>>>(x.Slices(p)),
01247 Tuple(IsSameSlice(x.Slice<0>(p))));
01248 }
01249 {
01250 const auto x = L::Partial(1, 2);
01251 EXPECT_THAT((Type<std::tuple<Span<int8_t>, Span<int8_t>>>(x.Slices(p))),
01252 Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p))));
01253 }
01254 {
01255 const auto x = L::Partial(1, 2, 3);
01256 EXPECT_THAT(
01257 (Type<std::tuple<Span<int8_t>, Span<int8_t>, Span<Int128>>>(x.Slices(p))),
01258 Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)),
01259 IsSameSlice(x.Slice<2>(p))));
01260 }
01261 {
01262 const L x(1, 2, 3);
01263 EXPECT_THAT(
01264 (Type<std::tuple<Span<int8_t>, Span<int8_t>, Span<Int128>>>(x.Slices(p))),
01265 Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)),
01266 IsSameSlice(x.Slice<2>(p))));
01267 }
01268 }
01269
01270 TEST(Layout, UnalignedTypes) {
01271 constexpr Layout<unsigned char, unsigned char, unsigned char> x(1, 2, 3);
01272 alignas(max_align_t) unsigned char p[x.AllocSize() + 1];
01273 EXPECT_THAT(x.Pointers(p + 1), Tuple(p + 1, p + 2, p + 4));
01274 }
01275
01276 TEST(Layout, CustomAlignment) {
01277 constexpr Layout<unsigned char, Aligned<unsigned char, 8>> x(1, 2);
01278 alignas(max_align_t) unsigned char p[x.AllocSize()];
01279 EXPECT_EQ(10, x.AllocSize());
01280 EXPECT_THAT(x.Pointers(p), Tuple(p + 0, p + 8));
01281 }
01282
01283 TEST(Layout, OverAligned) {
01284 constexpr size_t M = alignof(max_align_t);
01285 constexpr Layout<unsigned char, Aligned<unsigned char, 2 * M>> x(1, 3);
01286 alignas(2 * M) unsigned char p[x.AllocSize()];
01287 EXPECT_EQ(2 * M + 3, x.AllocSize());
01288 EXPECT_THAT(x.Pointers(p), Tuple(p + 0, p + 2 * M));
01289 }
01290
01291 TEST(Layout, Alignment) {
01292 static_assert(Layout<int8_t>::Alignment() == 1, "");
01293 static_assert(Layout<int32_t>::Alignment() == 4, "");
01294 static_assert(Layout<Int64>::Alignment() == 8, "");
01295 static_assert(Layout<Aligned<int8_t, 64>>::Alignment() == 64, "");
01296 static_assert(Layout<int8_t, int32_t, Int64>::Alignment() == 8, "");
01297 static_assert(Layout<int8_t, Int64, int32_t>::Alignment() == 8, "");
01298 static_assert(Layout<int32_t, int8_t, Int64>::Alignment() == 8, "");
01299 static_assert(Layout<int32_t, Int64, int8_t>::Alignment() == 8, "");
01300 static_assert(Layout<Int64, int8_t, int32_t>::Alignment() == 8, "");
01301 static_assert(Layout<Int64, int32_t, int8_t>::Alignment() == 8, "");
01302 }
01303
01304 TEST(Layout, ConstexprPartial) {
01305 constexpr size_t M = alignof(max_align_t);
01306 constexpr Layout<unsigned char, Aligned<unsigned char, 2 * M>> x(1, 3);
01307 static_assert(x.Partial(1).template Offset<1>() == 2 * M, "");
01308 }
01309
01310 struct Region {
01311 size_t from;
01312 size_t to;
01313 };
01314
01315 void ExpectRegionPoisoned(const unsigned char* p, size_t n, bool poisoned) {
01316 #ifdef ADDRESS_SANITIZER
01317 for (size_t i = 0; i != n; ++i) {
01318 EXPECT_EQ(poisoned, __asan_address_is_poisoned(p + i));
01319 }
01320 #endif
01321 }
01322
01323 template <size_t N>
01324 void ExpectPoisoned(const unsigned char (&buf)[N],
01325 std::initializer_list<Region> reg) {
01326 size_t prev = 0;
01327 for (const Region& r : reg) {
01328 ExpectRegionPoisoned(buf + prev, r.from - prev, false);
01329 ExpectRegionPoisoned(buf + r.from, r.to - r.from, true);
01330 prev = r.to;
01331 }
01332 ExpectRegionPoisoned(buf + prev, N - prev, false);
01333 }
01334
01335 TEST(Layout, PoisonPadding) {
01336 using L = Layout<int8_t, Int64, int32_t, Int128>;
01337
01338 constexpr size_t n = L::Partial(1, 2, 3, 4).AllocSize();
01339 {
01340 constexpr auto x = L::Partial();
01341 alignas(max_align_t) const unsigned char c[n] = {};
01342 x.PoisonPadding(c);
01343 EXPECT_EQ(x.Slices(c), x.Slices(c));
01344 ExpectPoisoned(c, {});
01345 }
01346 {
01347 constexpr auto x = L::Partial(1);
01348 alignas(max_align_t) const unsigned char c[n] = {};
01349 x.PoisonPadding(c);
01350 EXPECT_EQ(x.Slices(c), x.Slices(c));
01351 ExpectPoisoned(c, {{1, 8}});
01352 }
01353 {
01354 constexpr auto x = L::Partial(1, 2);
01355 alignas(max_align_t) const unsigned char c[n] = {};
01356 x.PoisonPadding(c);
01357 EXPECT_EQ(x.Slices(c), x.Slices(c));
01358 ExpectPoisoned(c, {{1, 8}});
01359 }
01360 {
01361 constexpr auto x = L::Partial(1, 2, 3);
01362 alignas(max_align_t) const unsigned char c[n] = {};
01363 x.PoisonPadding(c);
01364 EXPECT_EQ(x.Slices(c), x.Slices(c));
01365 ExpectPoisoned(c, {{1, 8}, {36, 40}});
01366 }
01367 {
01368 constexpr auto x = L::Partial(1, 2, 3, 4);
01369 alignas(max_align_t) const unsigned char c[n] = {};
01370 x.PoisonPadding(c);
01371 EXPECT_EQ(x.Slices(c), x.Slices(c));
01372 ExpectPoisoned(c, {{1, 8}, {36, 40}});
01373 }
01374 {
01375 constexpr L x(1, 2, 3, 4);
01376 alignas(max_align_t) const unsigned char c[n] = {};
01377 x.PoisonPadding(c);
01378 EXPECT_EQ(x.Slices(c), x.Slices(c));
01379 ExpectPoisoned(c, {{1, 8}, {36, 40}});
01380 }
01381 }
01382
01383 TEST(Layout, DebugString) {
01384 {
01385 constexpr auto x = Layout<int8_t, int32_t, int8_t, Int128>::Partial();
01386 EXPECT_EQ("@0<signed char>(1)", x.DebugString());
01387 }
01388 {
01389 constexpr auto x = Layout<int8_t, int32_t, int8_t, Int128>::Partial(1);
01390 EXPECT_EQ("@0<signed char>(1)[1]; @4<int>(4)", x.DebugString());
01391 }
01392 {
01393 constexpr auto x = Layout<int8_t, int32_t, int8_t, Int128>::Partial(1, 2);
01394 EXPECT_EQ("@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)",
01395 x.DebugString());
01396 }
01397 {
01398 constexpr auto x = Layout<int8_t, int32_t, int8_t, Int128>::Partial(1, 2, 3);
01399 EXPECT_EQ(
01400 "@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)[3]; "
01401 "@16" +
01402 Int128::Name() + "(16)",
01403 x.DebugString());
01404 }
01405 {
01406 constexpr auto x = Layout<int8_t, int32_t, int8_t, Int128>::Partial(1, 2, 3, 4);
01407 EXPECT_EQ(
01408 "@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)[3]; "
01409 "@16" +
01410 Int128::Name() + "(16)[4]",
01411 x.DebugString());
01412 }
01413 {
01414 constexpr Layout<int8_t, int32_t, int8_t, Int128> x(1, 2, 3, 4);
01415 EXPECT_EQ(
01416 "@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)[3]; "
01417 "@16" +
01418 Int128::Name() + "(16)[4]",
01419 x.DebugString());
01420 }
01421 }
01422
01423 TEST(Layout, CharTypes) {
01424 constexpr Layout<int32_t> x(1);
01425 alignas(max_align_t) char c[x.AllocSize()] = {};
01426 alignas(max_align_t) unsigned char uc[x.AllocSize()] = {};
01427 alignas(max_align_t) signed char sc[x.AllocSize()] = {};
01428 alignas(max_align_t) const char cc[x.AllocSize()] = {};
01429 alignas(max_align_t) const unsigned char cuc[x.AllocSize()] = {};
01430 alignas(max_align_t) const signed char csc[x.AllocSize()] = {};
01431
01432 Type<int32_t*>(x.Pointer<0>(c));
01433 Type<int32_t*>(x.Pointer<0>(uc));
01434 Type<int32_t*>(x.Pointer<0>(sc));
01435 Type<const int32_t*>(x.Pointer<0>(cc));
01436 Type<const int32_t*>(x.Pointer<0>(cuc));
01437 Type<const int32_t*>(x.Pointer<0>(csc));
01438
01439 Type<int32_t*>(x.Pointer<int32_t>(c));
01440 Type<int32_t*>(x.Pointer<int32_t>(uc));
01441 Type<int32_t*>(x.Pointer<int32_t>(sc));
01442 Type<const int32_t*>(x.Pointer<int32_t>(cc));
01443 Type<const int32_t*>(x.Pointer<int32_t>(cuc));
01444 Type<const int32_t*>(x.Pointer<int32_t>(csc));
01445
01446 Type<std::tuple<int32_t*>>(x.Pointers(c));
01447 Type<std::tuple<int32_t*>>(x.Pointers(uc));
01448 Type<std::tuple<int32_t*>>(x.Pointers(sc));
01449 Type<std::tuple<const int32_t*>>(x.Pointers(cc));
01450 Type<std::tuple<const int32_t*>>(x.Pointers(cuc));
01451 Type<std::tuple<const int32_t*>>(x.Pointers(csc));
01452
01453 Type<Span<int32_t>>(x.Slice<0>(c));
01454 Type<Span<int32_t>>(x.Slice<0>(uc));
01455 Type<Span<int32_t>>(x.Slice<0>(sc));
01456 Type<Span<const int32_t>>(x.Slice<0>(cc));
01457 Type<Span<const int32_t>>(x.Slice<0>(cuc));
01458 Type<Span<const int32_t>>(x.Slice<0>(csc));
01459
01460 Type<std::tuple<Span<int32_t>>>(x.Slices(c));
01461 Type<std::tuple<Span<int32_t>>>(x.Slices(uc));
01462 Type<std::tuple<Span<int32_t>>>(x.Slices(sc));
01463 Type<std::tuple<Span<const int32_t>>>(x.Slices(cc));
01464 Type<std::tuple<Span<const int32_t>>>(x.Slices(cuc));
01465 Type<std::tuple<Span<const int32_t>>>(x.Slices(csc));
01466 }
01467
01468 TEST(Layout, ConstElementType) {
01469 constexpr Layout<const int32_t> x(1);
01470 alignas(int32_t) char c[x.AllocSize()] = {};
01471 const char* cc = c;
01472 const int32_t* p = reinterpret_cast<const int32_t*>(cc);
01473
01474 EXPECT_EQ(alignof(int32_t), x.Alignment());
01475
01476 EXPECT_EQ(0, x.Offset<0>());
01477 EXPECT_EQ(0, x.Offset<const int32_t>());
01478
01479 EXPECT_THAT(x.Offsets(), ElementsAre(0));
01480
01481 EXPECT_EQ(1, x.Size<0>());
01482 EXPECT_EQ(1, x.Size<const int32_t>());
01483
01484 EXPECT_THAT(x.Sizes(), ElementsAre(1));
01485
01486 EXPECT_EQ(sizeof(int32_t), x.AllocSize());
01487
01488 EXPECT_EQ(p, Type<const int32_t*>(x.Pointer<0>(c)));
01489 EXPECT_EQ(p, Type<const int32_t*>(x.Pointer<0>(cc)));
01490
01491 EXPECT_EQ(p, Type<const int32_t*>(x.Pointer<const int32_t>(c)));
01492 EXPECT_EQ(p, Type<const int32_t*>(x.Pointer<const int32_t>(cc)));
01493
01494 EXPECT_THAT(Type<std::tuple<const int32_t*>>(x.Pointers(c)), Tuple(p));
01495 EXPECT_THAT(Type<std::tuple<const int32_t*>>(x.Pointers(cc)), Tuple(p));
01496
01497 EXPECT_THAT(Type<Span<const int32_t>>(x.Slice<0>(c)),
01498 IsSameSlice(Span<const int32_t>(p, 1)));
01499 EXPECT_THAT(Type<Span<const int32_t>>(x.Slice<0>(cc)),
01500 IsSameSlice(Span<const int32_t>(p, 1)));
01501
01502 EXPECT_THAT(Type<Span<const int32_t>>(x.Slice<const int32_t>(c)),
01503 IsSameSlice(Span<const int32_t>(p, 1)));
01504 EXPECT_THAT(Type<Span<const int32_t>>(x.Slice<const int32_t>(cc)),
01505 IsSameSlice(Span<const int32_t>(p, 1)));
01506
01507 EXPECT_THAT(Type<std::tuple<Span<const int32_t>>>(x.Slices(c)),
01508 Tuple(IsSameSlice(Span<const int32_t>(p, 1))));
01509 EXPECT_THAT(Type<std::tuple<Span<const int32_t>>>(x.Slices(cc)),
01510 Tuple(IsSameSlice(Span<const int32_t>(p, 1))));
01511 }
01512
01513 namespace example {
01514
01515
01516
01517 class CompactString {
01518 public:
01519 CompactString(const char* s = "") {
01520 const size_t size = strlen(s);
01521
01522
01523 const L layout(1, size + 1);
01524
01525
01526 p_.reset(new unsigned char[layout.AllocSize()]);
01527
01528
01529 layout.PoisonPadding(p_.get());
01530
01531
01532 *layout.Pointer<size_t>(p_.get()) = size;
01533
01534 memcpy(layout.Pointer<char>(p_.get()), s, size + 1);
01535 }
01536
01537 size_t size() const {
01538
01539 return *L::Partial().Pointer<size_t>(p_.get());
01540 }
01541
01542 const char* c_str() const {
01543
01544
01545
01546 return L::Partial(1).Pointer<char>(p_.get());
01547 }
01548
01549 private:
01550
01551 using L = Layout<size_t, char>;
01552 std::unique_ptr<unsigned char[]> p_;
01553 };
01554
01555 TEST(CompactString, Works) {
01556 CompactString s = "hello";
01557 EXPECT_EQ(5, s.size());
01558 EXPECT_STREQ("hello", s.c_str());
01559 }
01560
01561 }
01562
01563 }
01564 }
01565 }