layout_test.cc 60 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641
  1. // Copyright 2018 The Abseil Authors.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // https://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "absl/container/internal/layout.h"
  15. // We need ::max_align_t because some libstdc++ versions don't provide
  16. // std::max_align_t
  17. #include <stddef.h>
  18. #include <cstdint>
  19. #include <memory>
  20. #include <sstream>
  21. #include <type_traits>
  22. #include "gmock/gmock.h"
  23. #include "gtest/gtest.h"
  24. #include "absl/base/config.h"
  25. #include "absl/base/internal/raw_logging.h"
  26. #include "absl/types/span.h"
  27. namespace absl {
  28. ABSL_NAMESPACE_BEGIN
  29. namespace container_internal {
  30. namespace {
  31. using ::absl::Span;
  32. using ::testing::ElementsAre;
  33. size_t Distance(const void* from, const void* to) {
  34. ABSL_RAW_CHECK(from <= to, "Distance must be non-negative");
  35. return static_cast<const char*>(to) - static_cast<const char*>(from);
  36. }
  37. template <class Expected, class Actual>
  38. Expected Type(Actual val) {
  39. static_assert(std::is_same<Expected, Actual>(), "");
  40. return val;
  41. }
  42. // Helper classes to test different size and alignments.
  43. struct alignas(8) Int128 {
  44. uint64_t a, b;
  45. friend bool operator==(Int128 lhs, Int128 rhs) {
  46. return std::tie(lhs.a, lhs.b) == std::tie(rhs.a, rhs.b);
  47. }
  48. static std::string Name() {
  49. return internal_layout::adl_barrier::TypeName<Int128>();
  50. }
  51. };
  52. // int64_t is *not* 8-byte aligned on all platforms!
  53. struct alignas(8) Int64 {
  54. int64_t a;
  55. friend bool operator==(Int64 lhs, Int64 rhs) {
  56. return lhs.a == rhs.a;
  57. }
  58. };
  59. // Properties of types that this test relies on.
  60. static_assert(sizeof(int8_t) == 1, "");
  61. static_assert(alignof(int8_t) == 1, "");
  62. static_assert(sizeof(int16_t) == 2, "");
  63. static_assert(alignof(int16_t) == 2, "");
  64. static_assert(sizeof(int32_t) == 4, "");
  65. static_assert(alignof(int32_t) == 4, "");
  66. static_assert(sizeof(Int64) == 8, "");
  67. static_assert(alignof(Int64) == 8, "");
  68. static_assert(sizeof(Int128) == 16, "");
  69. static_assert(alignof(Int128) == 8, "");
  70. template <class Expected, class Actual>
  71. void SameType() {
  72. static_assert(std::is_same<Expected, Actual>(), "");
  73. }
  74. TEST(Layout, ElementType) {
  75. {
  76. using L = Layout<int32_t>;
  77. SameType<int32_t, L::ElementType<0>>();
  78. SameType<int32_t, decltype(L::Partial())::ElementType<0>>();
  79. SameType<int32_t, decltype(L::Partial(0))::ElementType<0>>();
  80. }
  81. {
  82. using L = Layout<int32_t, int32_t>;
  83. SameType<int32_t, L::ElementType<0>>();
  84. SameType<int32_t, L::ElementType<1>>();
  85. SameType<int32_t, decltype(L::Partial())::ElementType<0>>();
  86. SameType<int32_t, decltype(L::Partial())::ElementType<1>>();
  87. SameType<int32_t, decltype(L::Partial(0))::ElementType<0>>();
  88. SameType<int32_t, decltype(L::Partial(0))::ElementType<1>>();
  89. }
  90. {
  91. using L = Layout<int8_t, int32_t, Int128>;
  92. SameType<int8_t, L::ElementType<0>>();
  93. SameType<int32_t, L::ElementType<1>>();
  94. SameType<Int128, L::ElementType<2>>();
  95. SameType<int8_t, decltype(L::Partial())::ElementType<0>>();
  96. SameType<int8_t, decltype(L::Partial(0))::ElementType<0>>();
  97. SameType<int32_t, decltype(L::Partial(0))::ElementType<1>>();
  98. SameType<int8_t, decltype(L::Partial(0, 0))::ElementType<0>>();
  99. SameType<int32_t, decltype(L::Partial(0, 0))::ElementType<1>>();
  100. SameType<Int128, decltype(L::Partial(0, 0))::ElementType<2>>();
  101. SameType<int8_t, decltype(L::Partial(0, 0, 0))::ElementType<0>>();
  102. SameType<int32_t, decltype(L::Partial(0, 0, 0))::ElementType<1>>();
  103. SameType<Int128, decltype(L::Partial(0, 0, 0))::ElementType<2>>();
  104. }
  105. }
  106. TEST(Layout, ElementTypes) {
  107. {
  108. using L = Layout<int32_t>;
  109. SameType<std::tuple<int32_t>, L::ElementTypes>();
  110. SameType<std::tuple<int32_t>, decltype(L::Partial())::ElementTypes>();
  111. SameType<std::tuple<int32_t>, decltype(L::Partial(0))::ElementTypes>();
  112. }
  113. {
  114. using L = Layout<int32_t, int32_t>;
  115. SameType<std::tuple<int32_t, int32_t>, L::ElementTypes>();
  116. SameType<std::tuple<int32_t, int32_t>,
  117. decltype(L::Partial())::ElementTypes>();
  118. SameType<std::tuple<int32_t, int32_t>,
  119. decltype(L::Partial(0))::ElementTypes>();
  120. }
  121. {
  122. using L = Layout<int8_t, int32_t, Int128>;
  123. SameType<std::tuple<int8_t, int32_t, Int128>, L::ElementTypes>();
  124. SameType<std::tuple<int8_t, int32_t, Int128>,
  125. decltype(L::Partial())::ElementTypes>();
  126. SameType<std::tuple<int8_t, int32_t, Int128>,
  127. decltype(L::Partial(0))::ElementTypes>();
  128. SameType<std::tuple<int8_t, int32_t, Int128>,
  129. decltype(L::Partial(0, 0))::ElementTypes>();
  130. SameType<std::tuple<int8_t, int32_t, Int128>,
  131. decltype(L::Partial(0, 0, 0))::ElementTypes>();
  132. }
  133. }
  134. TEST(Layout, OffsetByIndex) {
  135. {
  136. using L = Layout<int32_t>;
  137. EXPECT_EQ(0, L::Partial().Offset<0>());
  138. EXPECT_EQ(0, L::Partial(3).Offset<0>());
  139. EXPECT_EQ(0, L(3).Offset<0>());
  140. }
  141. {
  142. using L = Layout<int32_t, int32_t>;
  143. EXPECT_EQ(0, L::Partial().Offset<0>());
  144. EXPECT_EQ(0, L::Partial(3).Offset<0>());
  145. EXPECT_EQ(12, L::Partial(3).Offset<1>());
  146. EXPECT_EQ(0, L::Partial(3, 5).Offset<0>());
  147. EXPECT_EQ(12, L::Partial(3, 5).Offset<1>());
  148. EXPECT_EQ(0, L(3, 5).Offset<0>());
  149. EXPECT_EQ(12, L(3, 5).Offset<1>());
  150. }
  151. {
  152. using L = Layout<int8_t, int32_t, Int128>;
  153. EXPECT_EQ(0, L::Partial().Offset<0>());
  154. EXPECT_EQ(0, L::Partial(0).Offset<0>());
  155. EXPECT_EQ(0, L::Partial(0).Offset<1>());
  156. EXPECT_EQ(0, L::Partial(1).Offset<0>());
  157. EXPECT_EQ(4, L::Partial(1).Offset<1>());
  158. EXPECT_EQ(0, L::Partial(5).Offset<0>());
  159. EXPECT_EQ(8, L::Partial(5).Offset<1>());
  160. EXPECT_EQ(0, L::Partial(0, 0).Offset<0>());
  161. EXPECT_EQ(0, L::Partial(0, 0).Offset<1>());
  162. EXPECT_EQ(0, L::Partial(0, 0).Offset<2>());
  163. EXPECT_EQ(0, L::Partial(1, 0).Offset<0>());
  164. EXPECT_EQ(4, L::Partial(1, 0).Offset<1>());
  165. EXPECT_EQ(8, L::Partial(1, 0).Offset<2>());
  166. EXPECT_EQ(0, L::Partial(5, 3).Offset<0>());
  167. EXPECT_EQ(8, L::Partial(5, 3).Offset<1>());
  168. EXPECT_EQ(24, L::Partial(5, 3).Offset<2>());
  169. EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<0>());
  170. EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<1>());
  171. EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<2>());
  172. EXPECT_EQ(0, L::Partial(1, 0, 0).Offset<0>());
  173. EXPECT_EQ(4, L::Partial(1, 0, 0).Offset<1>());
  174. EXPECT_EQ(8, L::Partial(1, 0, 0).Offset<2>());
  175. EXPECT_EQ(0, L::Partial(5, 3, 1).Offset<0>());
  176. EXPECT_EQ(24, L::Partial(5, 3, 1).Offset<2>());
  177. EXPECT_EQ(8, L::Partial(5, 3, 1).Offset<1>());
  178. EXPECT_EQ(0, L(5, 3, 1).Offset<0>());
  179. EXPECT_EQ(24, L(5, 3, 1).Offset<2>());
  180. EXPECT_EQ(8, L(5, 3, 1).Offset<1>());
  181. }
  182. }
  183. TEST(Layout, OffsetByType) {
  184. {
  185. using L = Layout<int32_t>;
  186. EXPECT_EQ(0, L::Partial().Offset<int32_t>());
  187. EXPECT_EQ(0, L::Partial(3).Offset<int32_t>());
  188. EXPECT_EQ(0, L(3).Offset<int32_t>());
  189. }
  190. {
  191. using L = Layout<int8_t, int32_t, Int128>;
  192. EXPECT_EQ(0, L::Partial().Offset<int8_t>());
  193. EXPECT_EQ(0, L::Partial(0).Offset<int8_t>());
  194. EXPECT_EQ(0, L::Partial(0).Offset<int32_t>());
  195. EXPECT_EQ(0, L::Partial(1).Offset<int8_t>());
  196. EXPECT_EQ(4, L::Partial(1).Offset<int32_t>());
  197. EXPECT_EQ(0, L::Partial(5).Offset<int8_t>());
  198. EXPECT_EQ(8, L::Partial(5).Offset<int32_t>());
  199. EXPECT_EQ(0, L::Partial(0, 0).Offset<int8_t>());
  200. EXPECT_EQ(0, L::Partial(0, 0).Offset<int32_t>());
  201. EXPECT_EQ(0, L::Partial(0, 0).Offset<Int128>());
  202. EXPECT_EQ(0, L::Partial(1, 0).Offset<int8_t>());
  203. EXPECT_EQ(4, L::Partial(1, 0).Offset<int32_t>());
  204. EXPECT_EQ(8, L::Partial(1, 0).Offset<Int128>());
  205. EXPECT_EQ(0, L::Partial(5, 3).Offset<int8_t>());
  206. EXPECT_EQ(8, L::Partial(5, 3).Offset<int32_t>());
  207. EXPECT_EQ(24, L::Partial(5, 3).Offset<Int128>());
  208. EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<int8_t>());
  209. EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<int32_t>());
  210. EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<Int128>());
  211. EXPECT_EQ(0, L::Partial(1, 0, 0).Offset<int8_t>());
  212. EXPECT_EQ(4, L::Partial(1, 0, 0).Offset<int32_t>());
  213. EXPECT_EQ(8, L::Partial(1, 0, 0).Offset<Int128>());
  214. EXPECT_EQ(0, L::Partial(5, 3, 1).Offset<int8_t>());
  215. EXPECT_EQ(24, L::Partial(5, 3, 1).Offset<Int128>());
  216. EXPECT_EQ(8, L::Partial(5, 3, 1).Offset<int32_t>());
  217. EXPECT_EQ(0, L(5, 3, 1).Offset<int8_t>());
  218. EXPECT_EQ(24, L(5, 3, 1).Offset<Int128>());
  219. EXPECT_EQ(8, L(5, 3, 1).Offset<int32_t>());
  220. }
  221. }
  222. TEST(Layout, Offsets) {
  223. {
  224. using L = Layout<int32_t>;
  225. EXPECT_THAT(L::Partial().Offsets(), ElementsAre(0));
  226. EXPECT_THAT(L::Partial(3).Offsets(), ElementsAre(0));
  227. EXPECT_THAT(L(3).Offsets(), ElementsAre(0));
  228. }
  229. {
  230. using L = Layout<int32_t, int32_t>;
  231. EXPECT_THAT(L::Partial().Offsets(), ElementsAre(0));
  232. EXPECT_THAT(L::Partial(3).Offsets(), ElementsAre(0, 12));
  233. EXPECT_THAT(L::Partial(3, 5).Offsets(), ElementsAre(0, 12));
  234. EXPECT_THAT(L(3, 5).Offsets(), ElementsAre(0, 12));
  235. }
  236. {
  237. using L = Layout<int8_t, int32_t, Int128>;
  238. EXPECT_THAT(L::Partial().Offsets(), ElementsAre(0));
  239. EXPECT_THAT(L::Partial(1).Offsets(), ElementsAre(0, 4));
  240. EXPECT_THAT(L::Partial(5).Offsets(), ElementsAre(0, 8));
  241. EXPECT_THAT(L::Partial(0, 0).Offsets(), ElementsAre(0, 0, 0));
  242. EXPECT_THAT(L::Partial(1, 0).Offsets(), ElementsAre(0, 4, 8));
  243. EXPECT_THAT(L::Partial(5, 3).Offsets(), ElementsAre(0, 8, 24));
  244. EXPECT_THAT(L::Partial(0, 0, 0).Offsets(), ElementsAre(0, 0, 0));
  245. EXPECT_THAT(L::Partial(1, 0, 0).Offsets(), ElementsAre(0, 4, 8));
  246. EXPECT_THAT(L::Partial(5, 3, 1).Offsets(), ElementsAre(0, 8, 24));
  247. EXPECT_THAT(L(5, 3, 1).Offsets(), ElementsAre(0, 8, 24));
  248. }
  249. }
  250. TEST(Layout, AllocSize) {
  251. {
  252. using L = Layout<int32_t>;
  253. EXPECT_EQ(0, L::Partial(0).AllocSize());
  254. EXPECT_EQ(12, L::Partial(3).AllocSize());
  255. EXPECT_EQ(12, L(3).AllocSize());
  256. }
  257. {
  258. using L = Layout<int32_t, int32_t>;
  259. EXPECT_EQ(32, L::Partial(3, 5).AllocSize());
  260. EXPECT_EQ(32, L(3, 5).AllocSize());
  261. }
  262. {
  263. using L = Layout<int8_t, int32_t, Int128>;
  264. EXPECT_EQ(0, L::Partial(0, 0, 0).AllocSize());
  265. EXPECT_EQ(8, L::Partial(1, 0, 0).AllocSize());
  266. EXPECT_EQ(8, L::Partial(0, 1, 0).AllocSize());
  267. EXPECT_EQ(16, L::Partial(0, 0, 1).AllocSize());
  268. EXPECT_EQ(24, L::Partial(1, 1, 1).AllocSize());
  269. EXPECT_EQ(136, L::Partial(3, 5, 7).AllocSize());
  270. EXPECT_EQ(136, L(3, 5, 7).AllocSize());
  271. }
  272. }
  273. TEST(Layout, SizeByIndex) {
  274. {
  275. using L = Layout<int32_t>;
  276. EXPECT_EQ(0, L::Partial(0).Size<0>());
  277. EXPECT_EQ(3, L::Partial(3).Size<0>());
  278. EXPECT_EQ(3, L(3).Size<0>());
  279. }
  280. {
  281. using L = Layout<int32_t, int32_t>;
  282. EXPECT_EQ(0, L::Partial(0).Size<0>());
  283. EXPECT_EQ(3, L::Partial(3).Size<0>());
  284. EXPECT_EQ(3, L::Partial(3, 5).Size<0>());
  285. EXPECT_EQ(5, L::Partial(3, 5).Size<1>());
  286. EXPECT_EQ(3, L(3, 5).Size<0>());
  287. EXPECT_EQ(5, L(3, 5).Size<1>());
  288. }
  289. {
  290. using L = Layout<int8_t, int32_t, Int128>;
  291. EXPECT_EQ(3, L::Partial(3).Size<0>());
  292. EXPECT_EQ(3, L::Partial(3, 5).Size<0>());
  293. EXPECT_EQ(5, L::Partial(3, 5).Size<1>());
  294. EXPECT_EQ(3, L::Partial(3, 5, 7).Size<0>());
  295. EXPECT_EQ(5, L::Partial(3, 5, 7).Size<1>());
  296. EXPECT_EQ(7, L::Partial(3, 5, 7).Size<2>());
  297. EXPECT_EQ(3, L(3, 5, 7).Size<0>());
  298. EXPECT_EQ(5, L(3, 5, 7).Size<1>());
  299. EXPECT_EQ(7, L(3, 5, 7).Size<2>());
  300. }
  301. }
  302. TEST(Layout, SizeByType) {
  303. {
  304. using L = Layout<int32_t>;
  305. EXPECT_EQ(0, L::Partial(0).Size<int32_t>());
  306. EXPECT_EQ(3, L::Partial(3).Size<int32_t>());
  307. EXPECT_EQ(3, L(3).Size<int32_t>());
  308. }
  309. {
  310. using L = Layout<int8_t, int32_t, Int128>;
  311. EXPECT_EQ(3, L::Partial(3).Size<int8_t>());
  312. EXPECT_EQ(3, L::Partial(3, 5).Size<int8_t>());
  313. EXPECT_EQ(5, L::Partial(3, 5).Size<int32_t>());
  314. EXPECT_EQ(3, L::Partial(3, 5, 7).Size<int8_t>());
  315. EXPECT_EQ(5, L::Partial(3, 5, 7).Size<int32_t>());
  316. EXPECT_EQ(7, L::Partial(3, 5, 7).Size<Int128>());
  317. EXPECT_EQ(3, L(3, 5, 7).Size<int8_t>());
  318. EXPECT_EQ(5, L(3, 5, 7).Size<int32_t>());
  319. EXPECT_EQ(7, L(3, 5, 7).Size<Int128>());
  320. }
  321. }
  322. TEST(Layout, Sizes) {
  323. {
  324. using L = Layout<int32_t>;
  325. EXPECT_THAT(L::Partial().Sizes(), ElementsAre());
  326. EXPECT_THAT(L::Partial(3).Sizes(), ElementsAre(3));
  327. EXPECT_THAT(L(3).Sizes(), ElementsAre(3));
  328. }
  329. {
  330. using L = Layout<int32_t, int32_t>;
  331. EXPECT_THAT(L::Partial().Sizes(), ElementsAre());
  332. EXPECT_THAT(L::Partial(3).Sizes(), ElementsAre(3));
  333. EXPECT_THAT(L::Partial(3, 5).Sizes(), ElementsAre(3, 5));
  334. EXPECT_THAT(L(3, 5).Sizes(), ElementsAre(3, 5));
  335. }
  336. {
  337. using L = Layout<int8_t, int32_t, Int128>;
  338. EXPECT_THAT(L::Partial().Sizes(), ElementsAre());
  339. EXPECT_THAT(L::Partial(3).Sizes(), ElementsAre(3));
  340. EXPECT_THAT(L::Partial(3, 5).Sizes(), ElementsAre(3, 5));
  341. EXPECT_THAT(L::Partial(3, 5, 7).Sizes(), ElementsAre(3, 5, 7));
  342. EXPECT_THAT(L(3, 5, 7).Sizes(), ElementsAre(3, 5, 7));
  343. }
  344. }
  345. TEST(Layout, PointerByIndex) {
  346. alignas(max_align_t) const unsigned char p[100] = {};
  347. {
  348. using L = Layout<int32_t>;
  349. EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L::Partial().Pointer<0>(p))));
  350. EXPECT_EQ(0,
  351. Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<0>(p))));
  352. EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L(3).Pointer<0>(p))));
  353. }
  354. {
  355. using L = Layout<int32_t, int32_t>;
  356. EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L::Partial().Pointer<0>(p))));
  357. EXPECT_EQ(0,
  358. Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<0>(p))));
  359. EXPECT_EQ(12,
  360. Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<1>(p))));
  361. EXPECT_EQ(
  362. 0, Distance(p, Type<const int32_t*>(L::Partial(3, 5).Pointer<0>(p))));
  363. EXPECT_EQ(
  364. 12, Distance(p, Type<const int32_t*>(L::Partial(3, 5).Pointer<1>(p))));
  365. EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L(3, 5).Pointer<0>(p))));
  366. EXPECT_EQ(12, Distance(p, Type<const int32_t*>(L(3, 5).Pointer<1>(p))));
  367. }
  368. {
  369. using L = Layout<int8_t, int32_t, Int128>;
  370. EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial().Pointer<0>(p))));
  371. EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial(0).Pointer<0>(p))));
  372. EXPECT_EQ(0,
  373. Distance(p, Type<const int32_t*>(L::Partial(0).Pointer<1>(p))));
  374. EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial(1).Pointer<0>(p))));
  375. EXPECT_EQ(4,
  376. Distance(p, Type<const int32_t*>(L::Partial(1).Pointer<1>(p))));
  377. EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L::Partial(5).Pointer<0>(p))));
  378. EXPECT_EQ(8,
  379. Distance(p, Type<const int32_t*>(L::Partial(5).Pointer<1>(p))));
  380. EXPECT_EQ(0,
  381. Distance(p, Type<const int8_t*>(L::Partial(0, 0).Pointer<0>(p))));
  382. EXPECT_EQ(
  383. 0, Distance(p, Type<const int32_t*>(L::Partial(0, 0).Pointer<1>(p))));
  384. EXPECT_EQ(0,
  385. Distance(p, Type<const Int128*>(L::Partial(0, 0).Pointer<2>(p))));
  386. EXPECT_EQ(0,
  387. Distance(p, Type<const int8_t*>(L::Partial(1, 0).Pointer<0>(p))));
  388. EXPECT_EQ(
  389. 4, Distance(p, Type<const int32_t*>(L::Partial(1, 0).Pointer<1>(p))));
  390. EXPECT_EQ(8,
  391. Distance(p, Type<const Int128*>(L::Partial(1, 0).Pointer<2>(p))));
  392. EXPECT_EQ(0,
  393. Distance(p, Type<const int8_t*>(L::Partial(5, 3).Pointer<0>(p))));
  394. EXPECT_EQ(
  395. 8, Distance(p, Type<const int32_t*>(L::Partial(5, 3).Pointer<1>(p))));
  396. EXPECT_EQ(24,
  397. Distance(p, Type<const Int128*>(L::Partial(5, 3).Pointer<2>(p))));
  398. EXPECT_EQ(
  399. 0, Distance(p, Type<const int8_t*>(L::Partial(0, 0, 0).Pointer<0>(p))));
  400. EXPECT_EQ(
  401. 0,
  402. Distance(p, Type<const int32_t*>(L::Partial(0, 0, 0).Pointer<1>(p))));
  403. EXPECT_EQ(
  404. 0, Distance(p, Type<const Int128*>(L::Partial(0, 0, 0).Pointer<2>(p))));
  405. EXPECT_EQ(
  406. 0, Distance(p, Type<const int8_t*>(L::Partial(1, 0, 0).Pointer<0>(p))));
  407. EXPECT_EQ(
  408. 4,
  409. Distance(p, Type<const int32_t*>(L::Partial(1, 0, 0).Pointer<1>(p))));
  410. EXPECT_EQ(
  411. 8, Distance(p, Type<const Int128*>(L::Partial(1, 0, 0).Pointer<2>(p))));
  412. EXPECT_EQ(
  413. 0, Distance(p, Type<const int8_t*>(L::Partial(5, 3, 1).Pointer<0>(p))));
  414. EXPECT_EQ(
  415. 24,
  416. Distance(p, Type<const Int128*>(L::Partial(5, 3, 1).Pointer<2>(p))));
  417. EXPECT_EQ(
  418. 8,
  419. Distance(p, Type<const int32_t*>(L::Partial(5, 3, 1).Pointer<1>(p))));
  420. EXPECT_EQ(0, Distance(p, Type<const int8_t*>(L(5, 3, 1).Pointer<0>(p))));
  421. EXPECT_EQ(24, Distance(p, Type<const Int128*>(L(5, 3, 1).Pointer<2>(p))));
  422. EXPECT_EQ(8, Distance(p, Type<const int32_t*>(L(5, 3, 1).Pointer<1>(p))));
  423. }
  424. }
  425. TEST(Layout, PointerByType) {
  426. alignas(max_align_t) const unsigned char p[100] = {};
  427. {
  428. using L = Layout<int32_t>;
  429. EXPECT_EQ(
  430. 0, Distance(p, Type<const int32_t*>(L::Partial().Pointer<int32_t>(p))));
  431. EXPECT_EQ(
  432. 0,
  433. Distance(p, Type<const int32_t*>(L::Partial(3).Pointer<int32_t>(p))));
  434. EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L(3).Pointer<int32_t>(p))));
  435. }
  436. {
  437. using L = Layout<int8_t, int32_t, Int128>;
  438. EXPECT_EQ(
  439. 0, Distance(p, Type<const int8_t*>(L::Partial().Pointer<int8_t>(p))));
  440. EXPECT_EQ(
  441. 0, Distance(p, Type<const int8_t*>(L::Partial(0).Pointer<int8_t>(p))));
  442. EXPECT_EQ(
  443. 0,
  444. Distance(p, Type<const int32_t*>(L::Partial(0).Pointer<int32_t>(p))));
  445. EXPECT_EQ(
  446. 0, Distance(p, Type<const int8_t*>(L::Partial(1).Pointer<int8_t>(p))));
  447. EXPECT_EQ(
  448. 4,
  449. Distance(p, Type<const int32_t*>(L::Partial(1).Pointer<int32_t>(p))));
  450. EXPECT_EQ(
  451. 0, Distance(p, Type<const int8_t*>(L::Partial(5).Pointer<int8_t>(p))));
  452. EXPECT_EQ(
  453. 8,
  454. Distance(p, Type<const int32_t*>(L::Partial(5).Pointer<int32_t>(p))));
  455. EXPECT_EQ(
  456. 0,
  457. Distance(p, Type<const int8_t*>(L::Partial(0, 0).Pointer<int8_t>(p))));
  458. EXPECT_EQ(0, Distance(p, Type<const int32_t*>(
  459. L::Partial(0, 0).Pointer<int32_t>(p))));
  460. EXPECT_EQ(
  461. 0,
  462. Distance(p, Type<const Int128*>(L::Partial(0, 0).Pointer<Int128>(p))));
  463. EXPECT_EQ(
  464. 0,
  465. Distance(p, Type<const int8_t*>(L::Partial(1, 0).Pointer<int8_t>(p))));
  466. EXPECT_EQ(4, Distance(p, Type<const int32_t*>(
  467. L::Partial(1, 0).Pointer<int32_t>(p))));
  468. EXPECT_EQ(
  469. 8,
  470. Distance(p, Type<const Int128*>(L::Partial(1, 0).Pointer<Int128>(p))));
  471. EXPECT_EQ(
  472. 0,
  473. Distance(p, Type<const int8_t*>(L::Partial(5, 3).Pointer<int8_t>(p))));
  474. EXPECT_EQ(8, Distance(p, Type<const int32_t*>(
  475. L::Partial(5, 3).Pointer<int32_t>(p))));
  476. EXPECT_EQ(
  477. 24,
  478. Distance(p, Type<const Int128*>(L::Partial(5, 3).Pointer<Int128>(p))));
  479. EXPECT_EQ(0, Distance(p, Type<const int8_t*>(
  480. L::Partial(0, 0, 0).Pointer<int8_t>(p))));
  481. EXPECT_EQ(0, Distance(p, Type<const int32_t*>(
  482. L::Partial(0, 0, 0).Pointer<int32_t>(p))));
  483. EXPECT_EQ(0, Distance(p, Type<const Int128*>(
  484. L::Partial(0, 0, 0).Pointer<Int128>(p))));
  485. EXPECT_EQ(0, Distance(p, Type<const int8_t*>(
  486. L::Partial(1, 0, 0).Pointer<int8_t>(p))));
  487. EXPECT_EQ(4, Distance(p, Type<const int32_t*>(
  488. L::Partial(1, 0, 0).Pointer<int32_t>(p))));
  489. EXPECT_EQ(8, Distance(p, Type<const Int128*>(
  490. L::Partial(1, 0, 0).Pointer<Int128>(p))));
  491. EXPECT_EQ(0, Distance(p, Type<const int8_t*>(
  492. L::Partial(5, 3, 1).Pointer<int8_t>(p))));
  493. EXPECT_EQ(24, Distance(p, Type<const Int128*>(
  494. L::Partial(5, 3, 1).Pointer<Int128>(p))));
  495. EXPECT_EQ(8, Distance(p, Type<const int32_t*>(
  496. L::Partial(5, 3, 1).Pointer<int32_t>(p))));
  497. EXPECT_EQ(24,
  498. Distance(p, Type<const Int128*>(L(5, 3, 1).Pointer<Int128>(p))));
  499. EXPECT_EQ(
  500. 8, Distance(p, Type<const int32_t*>(L(5, 3, 1).Pointer<int32_t>(p))));
  501. }
  502. }
  503. TEST(Layout, MutablePointerByIndex) {
  504. alignas(max_align_t) unsigned char p[100];
  505. {
  506. using L = Layout<int32_t>;
  507. EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial().Pointer<0>(p))));
  508. EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(3).Pointer<0>(p))));
  509. EXPECT_EQ(0, Distance(p, Type<int32_t*>(L(3).Pointer<0>(p))));
  510. }
  511. {
  512. using L = Layout<int32_t, int32_t>;
  513. EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial().Pointer<0>(p))));
  514. EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(3).Pointer<0>(p))));
  515. EXPECT_EQ(12, Distance(p, Type<int32_t*>(L::Partial(3).Pointer<1>(p))));
  516. EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(3, 5).Pointer<0>(p))));
  517. EXPECT_EQ(12, Distance(p, Type<int32_t*>(L::Partial(3, 5).Pointer<1>(p))));
  518. EXPECT_EQ(0, Distance(p, Type<int32_t*>(L(3, 5).Pointer<0>(p))));
  519. EXPECT_EQ(12, Distance(p, Type<int32_t*>(L(3, 5).Pointer<1>(p))));
  520. }
  521. {
  522. using L = Layout<int8_t, int32_t, Int128>;
  523. EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial().Pointer<0>(p))));
  524. EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0).Pointer<0>(p))));
  525. EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(0).Pointer<1>(p))));
  526. EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1).Pointer<0>(p))));
  527. EXPECT_EQ(4, Distance(p, Type<int32_t*>(L::Partial(1).Pointer<1>(p))));
  528. EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5).Pointer<0>(p))));
  529. EXPECT_EQ(8, Distance(p, Type<int32_t*>(L::Partial(5).Pointer<1>(p))));
  530. EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0, 0).Pointer<0>(p))));
  531. EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial(0, 0).Pointer<1>(p))));
  532. EXPECT_EQ(0, Distance(p, Type<Int128*>(L::Partial(0, 0).Pointer<2>(p))));
  533. EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1, 0).Pointer<0>(p))));
  534. EXPECT_EQ(4, Distance(p, Type<int32_t*>(L::Partial(1, 0).Pointer<1>(p))));
  535. EXPECT_EQ(8, Distance(p, Type<Int128*>(L::Partial(1, 0).Pointer<2>(p))));
  536. EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5, 3).Pointer<0>(p))));
  537. EXPECT_EQ(8, Distance(p, Type<int32_t*>(L::Partial(5, 3).Pointer<1>(p))));
  538. EXPECT_EQ(24, Distance(p, Type<Int128*>(L::Partial(5, 3).Pointer<2>(p))));
  539. EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0, 0, 0).Pointer<0>(p))));
  540. EXPECT_EQ(0,
  541. Distance(p, Type<int32_t*>(L::Partial(0, 0, 0).Pointer<1>(p))));
  542. EXPECT_EQ(0, Distance(p, Type<Int128*>(L::Partial(0, 0, 0).Pointer<2>(p))));
  543. EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1, 0, 0).Pointer<0>(p))));
  544. EXPECT_EQ(4,
  545. Distance(p, Type<int32_t*>(L::Partial(1, 0, 0).Pointer<1>(p))));
  546. EXPECT_EQ(8, Distance(p, Type<Int128*>(L::Partial(1, 0, 0).Pointer<2>(p))));
  547. EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5, 3, 1).Pointer<0>(p))));
  548. EXPECT_EQ(24,
  549. Distance(p, Type<Int128*>(L::Partial(5, 3, 1).Pointer<2>(p))));
  550. EXPECT_EQ(8,
  551. Distance(p, Type<int32_t*>(L::Partial(5, 3, 1).Pointer<1>(p))));
  552. EXPECT_EQ(0, Distance(p, Type<int8_t*>(L(5, 3, 1).Pointer<0>(p))));
  553. EXPECT_EQ(24, Distance(p, Type<Int128*>(L(5, 3, 1).Pointer<2>(p))));
  554. EXPECT_EQ(8, Distance(p, Type<int32_t*>(L(5, 3, 1).Pointer<1>(p))));
  555. }
  556. }
  557. TEST(Layout, MutablePointerByType) {
  558. alignas(max_align_t) unsigned char p[100];
  559. {
  560. using L = Layout<int32_t>;
  561. EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial().Pointer<int32_t>(p))));
  562. EXPECT_EQ(0,
  563. Distance(p, Type<int32_t*>(L::Partial(3).Pointer<int32_t>(p))));
  564. EXPECT_EQ(0, Distance(p, Type<int32_t*>(L(3).Pointer<int32_t>(p))));
  565. }
  566. {
  567. using L = Layout<int8_t, int32_t, Int128>;
  568. EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial().Pointer<int8_t>(p))));
  569. EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(0).Pointer<int8_t>(p))));
  570. EXPECT_EQ(0,
  571. Distance(p, Type<int32_t*>(L::Partial(0).Pointer<int32_t>(p))));
  572. EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(1).Pointer<int8_t>(p))));
  573. EXPECT_EQ(4,
  574. Distance(p, Type<int32_t*>(L::Partial(1).Pointer<int32_t>(p))));
  575. EXPECT_EQ(0, Distance(p, Type<int8_t*>(L::Partial(5).Pointer<int8_t>(p))));
  576. EXPECT_EQ(8,
  577. Distance(p, Type<int32_t*>(L::Partial(5).Pointer<int32_t>(p))));
  578. EXPECT_EQ(0,
  579. Distance(p, Type<int8_t*>(L::Partial(0, 0).Pointer<int8_t>(p))));
  580. EXPECT_EQ(
  581. 0, Distance(p, Type<int32_t*>(L::Partial(0, 0).Pointer<int32_t>(p))));
  582. EXPECT_EQ(0,
  583. Distance(p, Type<Int128*>(L::Partial(0, 0).Pointer<Int128>(p))));
  584. EXPECT_EQ(0,
  585. Distance(p, Type<int8_t*>(L::Partial(1, 0).Pointer<int8_t>(p))));
  586. EXPECT_EQ(
  587. 4, Distance(p, Type<int32_t*>(L::Partial(1, 0).Pointer<int32_t>(p))));
  588. EXPECT_EQ(8,
  589. Distance(p, Type<Int128*>(L::Partial(1, 0).Pointer<Int128>(p))));
  590. EXPECT_EQ(0,
  591. Distance(p, Type<int8_t*>(L::Partial(5, 3).Pointer<int8_t>(p))));
  592. EXPECT_EQ(
  593. 8, Distance(p, Type<int32_t*>(L::Partial(5, 3).Pointer<int32_t>(p))));
  594. EXPECT_EQ(24,
  595. Distance(p, Type<Int128*>(L::Partial(5, 3).Pointer<Int128>(p))));
  596. EXPECT_EQ(
  597. 0, Distance(p, Type<int8_t*>(L::Partial(0, 0, 0).Pointer<int8_t>(p))));
  598. EXPECT_EQ(
  599. 0,
  600. Distance(p, Type<int32_t*>(L::Partial(0, 0, 0).Pointer<int32_t>(p))));
  601. EXPECT_EQ(
  602. 0, Distance(p, Type<Int128*>(L::Partial(0, 0, 0).Pointer<Int128>(p))));
  603. EXPECT_EQ(
  604. 0, Distance(p, Type<int8_t*>(L::Partial(1, 0, 0).Pointer<int8_t>(p))));
  605. EXPECT_EQ(
  606. 4,
  607. Distance(p, Type<int32_t*>(L::Partial(1, 0, 0).Pointer<int32_t>(p))));
  608. EXPECT_EQ(
  609. 8, Distance(p, Type<Int128*>(L::Partial(1, 0, 0).Pointer<Int128>(p))));
  610. EXPECT_EQ(
  611. 0, Distance(p, Type<int8_t*>(L::Partial(5, 3, 1).Pointer<int8_t>(p))));
  612. EXPECT_EQ(
  613. 24, Distance(p, Type<Int128*>(L::Partial(5, 3, 1).Pointer<Int128>(p))));
  614. EXPECT_EQ(
  615. 8,
  616. Distance(p, Type<int32_t*>(L::Partial(5, 3, 1).Pointer<int32_t>(p))));
  617. EXPECT_EQ(0, Distance(p, Type<int8_t*>(L(5, 3, 1).Pointer<int8_t>(p))));
  618. EXPECT_EQ(24, Distance(p, Type<Int128*>(L(5, 3, 1).Pointer<Int128>(p))));
  619. EXPECT_EQ(8, Distance(p, Type<int32_t*>(L(5, 3, 1).Pointer<int32_t>(p))));
  620. }
  621. }
  622. TEST(Layout, Pointers) {
  623. alignas(max_align_t) const unsigned char p[100] = {};
  624. using L = Layout<int8_t, int8_t, Int128>;
  625. {
  626. const auto x = L::Partial();
  627. EXPECT_EQ(std::make_tuple(x.Pointer<0>(p)),
  628. Type<std::tuple<const int8_t*>>(x.Pointers(p)));
  629. }
  630. {
  631. const auto x = L::Partial(1);
  632. EXPECT_EQ(std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p)),
  633. (Type<std::tuple<const int8_t*, const int8_t*>>(x.Pointers(p))));
  634. }
  635. {
  636. const auto x = L::Partial(1, 2);
  637. EXPECT_EQ(
  638. std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
  639. (Type<std::tuple<const int8_t*, const int8_t*, const Int128*>>(
  640. x.Pointers(p))));
  641. }
  642. {
  643. const auto x = L::Partial(1, 2, 3);
  644. EXPECT_EQ(
  645. std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
  646. (Type<std::tuple<const int8_t*, const int8_t*, const Int128*>>(
  647. x.Pointers(p))));
  648. }
  649. {
  650. const L x(1, 2, 3);
  651. EXPECT_EQ(
  652. std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
  653. (Type<std::tuple<const int8_t*, const int8_t*, const Int128*>>(
  654. x.Pointers(p))));
  655. }
  656. }
  657. TEST(Layout, MutablePointers) {
  658. alignas(max_align_t) unsigned char p[100];
  659. using L = Layout<int8_t, int8_t, Int128>;
  660. {
  661. const auto x = L::Partial();
  662. EXPECT_EQ(std::make_tuple(x.Pointer<0>(p)),
  663. Type<std::tuple<int8_t*>>(x.Pointers(p)));
  664. }
  665. {
  666. const auto x = L::Partial(1);
  667. EXPECT_EQ(std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p)),
  668. (Type<std::tuple<int8_t*, int8_t*>>(x.Pointers(p))));
  669. }
  670. {
  671. const auto x = L::Partial(1, 2);
  672. EXPECT_EQ(
  673. std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
  674. (Type<std::tuple<int8_t*, int8_t*, Int128*>>(x.Pointers(p))));
  675. }
  676. {
  677. const auto x = L::Partial(1, 2, 3);
  678. EXPECT_EQ(
  679. std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
  680. (Type<std::tuple<int8_t*, int8_t*, Int128*>>(x.Pointers(p))));
  681. }
  682. {
  683. const L x(1, 2, 3);
  684. EXPECT_EQ(
  685. std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)),
  686. (Type<std::tuple<int8_t*, int8_t*, Int128*>>(x.Pointers(p))));
  687. }
  688. }
  689. TEST(Layout, SliceByIndexSize) {
  690. alignas(max_align_t) const unsigned char p[100] = {};
  691. {
  692. using L = Layout<int32_t>;
  693. EXPECT_EQ(0, L::Partial(0).Slice<0>(p).size());
  694. EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size());
  695. EXPECT_EQ(3, L(3).Slice<0>(p).size());
  696. }
  697. {
  698. using L = Layout<int32_t, int32_t>;
  699. EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size());
  700. EXPECT_EQ(5, L::Partial(3, 5).Slice<1>(p).size());
  701. EXPECT_EQ(5, L(3, 5).Slice<1>(p).size());
  702. }
  703. {
  704. using L = Layout<int8_t, int32_t, Int128>;
  705. EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size());
  706. EXPECT_EQ(3, L::Partial(3, 5).Slice<0>(p).size());
  707. EXPECT_EQ(5, L::Partial(3, 5).Slice<1>(p).size());
  708. EXPECT_EQ(3, L::Partial(3, 5, 7).Slice<0>(p).size());
  709. EXPECT_EQ(5, L::Partial(3, 5, 7).Slice<1>(p).size());
  710. EXPECT_EQ(7, L::Partial(3, 5, 7).Slice<2>(p).size());
  711. EXPECT_EQ(3, L(3, 5, 7).Slice<0>(p).size());
  712. EXPECT_EQ(5, L(3, 5, 7).Slice<1>(p).size());
  713. EXPECT_EQ(7, L(3, 5, 7).Slice<2>(p).size());
  714. }
  715. }
  716. TEST(Layout, SliceByTypeSize) {
  717. alignas(max_align_t) const unsigned char p[100] = {};
  718. {
  719. using L = Layout<int32_t>;
  720. EXPECT_EQ(0, L::Partial(0).Slice<int32_t>(p).size());
  721. EXPECT_EQ(3, L::Partial(3).Slice<int32_t>(p).size());
  722. EXPECT_EQ(3, L(3).Slice<int32_t>(p).size());
  723. }
  724. {
  725. using L = Layout<int8_t, int32_t, Int128>;
  726. EXPECT_EQ(3, L::Partial(3).Slice<int8_t>(p).size());
  727. EXPECT_EQ(3, L::Partial(3, 5).Slice<int8_t>(p).size());
  728. EXPECT_EQ(5, L::Partial(3, 5).Slice<int32_t>(p).size());
  729. EXPECT_EQ(3, L::Partial(3, 5, 7).Slice<int8_t>(p).size());
  730. EXPECT_EQ(5, L::Partial(3, 5, 7).Slice<int32_t>(p).size());
  731. EXPECT_EQ(7, L::Partial(3, 5, 7).Slice<Int128>(p).size());
  732. EXPECT_EQ(3, L(3, 5, 7).Slice<int8_t>(p).size());
  733. EXPECT_EQ(5, L(3, 5, 7).Slice<int32_t>(p).size());
  734. EXPECT_EQ(7, L(3, 5, 7).Slice<Int128>(p).size());
  735. }
  736. }
  737. TEST(Layout, MutableSliceByIndexSize) {
  738. alignas(max_align_t) unsigned char p[100];
  739. {
  740. using L = Layout<int32_t>;
  741. EXPECT_EQ(0, L::Partial(0).Slice<0>(p).size());
  742. EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size());
  743. EXPECT_EQ(3, L(3).Slice<0>(p).size());
  744. }
  745. {
  746. using L = Layout<int32_t, int32_t>;
  747. EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size());
  748. EXPECT_EQ(5, L::Partial(3, 5).Slice<1>(p).size());
  749. EXPECT_EQ(5, L(3, 5).Slice<1>(p).size());
  750. }
  751. {
  752. using L = Layout<int8_t, int32_t, Int128>;
  753. EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size());
  754. EXPECT_EQ(3, L::Partial(3, 5).Slice<0>(p).size());
  755. EXPECT_EQ(5, L::Partial(3, 5).Slice<1>(p).size());
  756. EXPECT_EQ(3, L::Partial(3, 5, 7).Slice<0>(p).size());
  757. EXPECT_EQ(5, L::Partial(3, 5, 7).Slice<1>(p).size());
  758. EXPECT_EQ(7, L::Partial(3, 5, 7).Slice<2>(p).size());
  759. EXPECT_EQ(3, L(3, 5, 7).Slice<0>(p).size());
  760. EXPECT_EQ(5, L(3, 5, 7).Slice<1>(p).size());
  761. EXPECT_EQ(7, L(3, 5, 7).Slice<2>(p).size());
  762. }
  763. }
  764. TEST(Layout, MutableSliceByTypeSize) {
  765. alignas(max_align_t) unsigned char p[100];
  766. {
  767. using L = Layout<int32_t>;
  768. EXPECT_EQ(0, L::Partial(0).Slice<int32_t>(p).size());
  769. EXPECT_EQ(3, L::Partial(3).Slice<int32_t>(p).size());
  770. EXPECT_EQ(3, L(3).Slice<int32_t>(p).size());
  771. }
  772. {
  773. using L = Layout<int8_t, int32_t, Int128>;
  774. EXPECT_EQ(3, L::Partial(3).Slice<int8_t>(p).size());
  775. EXPECT_EQ(3, L::Partial(3, 5).Slice<int8_t>(p).size());
  776. EXPECT_EQ(5, L::Partial(3, 5).Slice<int32_t>(p).size());
  777. EXPECT_EQ(3, L::Partial(3, 5, 7).Slice<int8_t>(p).size());
  778. EXPECT_EQ(5, L::Partial(3, 5, 7).Slice<int32_t>(p).size());
  779. EXPECT_EQ(7, L::Partial(3, 5, 7).Slice<Int128>(p).size());
  780. EXPECT_EQ(3, L(3, 5, 7).Slice<int8_t>(p).size());
  781. EXPECT_EQ(5, L(3, 5, 7).Slice<int32_t>(p).size());
  782. EXPECT_EQ(7, L(3, 5, 7).Slice<Int128>(p).size());
  783. }
  784. }
  785. TEST(Layout, SliceByIndexData) {
  786. alignas(max_align_t) const unsigned char p[100] = {};
  787. {
  788. using L = Layout<int32_t>;
  789. EXPECT_EQ(
  790. 0, Distance(
  791. p, Type<Span<const int32_t>>(L::Partial(0).Slice<0>(p)).data()));
  792. EXPECT_EQ(
  793. 0, Distance(
  794. p, Type<Span<const int32_t>>(L::Partial(3).Slice<0>(p)).data()));
  795. EXPECT_EQ(0,
  796. Distance(p, Type<Span<const int32_t>>(L(3).Slice<0>(p)).data()));
  797. }
  798. {
  799. using L = Layout<int32_t, int32_t>;
  800. EXPECT_EQ(
  801. 0, Distance(
  802. p, Type<Span<const int32_t>>(L::Partial(3).Slice<0>(p)).data()));
  803. EXPECT_EQ(
  804. 0,
  805. Distance(
  806. p, Type<Span<const int32_t>>(L::Partial(3, 5).Slice<0>(p)).data()));
  807. EXPECT_EQ(
  808. 12,
  809. Distance(
  810. p, Type<Span<const int32_t>>(L::Partial(3, 5).Slice<1>(p)).data()));
  811. EXPECT_EQ(
  812. 0, Distance(p, Type<Span<const int32_t>>(L(3, 5).Slice<0>(p)).data()));
  813. EXPECT_EQ(
  814. 12, Distance(p, Type<Span<const int32_t>>(L(3, 5).Slice<1>(p)).data()));
  815. }
  816. {
  817. using L = Layout<int8_t, int32_t, Int128>;
  818. EXPECT_EQ(
  819. 0, Distance(
  820. p, Type<Span<const int8_t>>(L::Partial(0).Slice<0>(p)).data()));
  821. EXPECT_EQ(
  822. 0, Distance(
  823. p, Type<Span<const int8_t>>(L::Partial(1).Slice<0>(p)).data()));
  824. EXPECT_EQ(
  825. 0, Distance(
  826. p, Type<Span<const int8_t>>(L::Partial(5).Slice<0>(p)).data()));
  827. EXPECT_EQ(
  828. 0,
  829. Distance(
  830. p, Type<Span<const int8_t>>(L::Partial(0, 0).Slice<0>(p)).data()));
  831. EXPECT_EQ(
  832. 0,
  833. Distance(
  834. p, Type<Span<const int32_t>>(L::Partial(0, 0).Slice<1>(p)).data()));
  835. EXPECT_EQ(
  836. 0,
  837. Distance(
  838. p, Type<Span<const int8_t>>(L::Partial(1, 0).Slice<0>(p)).data()));
  839. EXPECT_EQ(
  840. 4,
  841. Distance(
  842. p, Type<Span<const int32_t>>(L::Partial(1, 0).Slice<1>(p)).data()));
  843. EXPECT_EQ(
  844. 0,
  845. Distance(
  846. p, Type<Span<const int8_t>>(L::Partial(5, 3).Slice<0>(p)).data()));
  847. EXPECT_EQ(
  848. 8,
  849. Distance(
  850. p, Type<Span<const int32_t>>(L::Partial(5, 3).Slice<1>(p)).data()));
  851. EXPECT_EQ(
  852. 0,
  853. Distance(
  854. p,
  855. Type<Span<const int8_t>>(L::Partial(0, 0, 0).Slice<0>(p)).data()));
  856. EXPECT_EQ(
  857. 0,
  858. Distance(
  859. p,
  860. Type<Span<const int32_t>>(L::Partial(0, 0, 0).Slice<1>(p)).data()));
  861. EXPECT_EQ(
  862. 0,
  863. Distance(
  864. p,
  865. Type<Span<const Int128>>(L::Partial(0, 0, 0).Slice<2>(p)).data()));
  866. EXPECT_EQ(
  867. 0,
  868. Distance(
  869. p,
  870. Type<Span<const int8_t>>(L::Partial(1, 0, 0).Slice<0>(p)).data()));
  871. EXPECT_EQ(
  872. 4,
  873. Distance(
  874. p,
  875. Type<Span<const int32_t>>(L::Partial(1, 0, 0).Slice<1>(p)).data()));
  876. EXPECT_EQ(
  877. 8,
  878. Distance(
  879. p,
  880. Type<Span<const Int128>>(L::Partial(1, 0, 0).Slice<2>(p)).data()));
  881. EXPECT_EQ(
  882. 0,
  883. Distance(
  884. p,
  885. Type<Span<const int8_t>>(L::Partial(5, 3, 1).Slice<0>(p)).data()));
  886. EXPECT_EQ(
  887. 24,
  888. Distance(
  889. p,
  890. Type<Span<const Int128>>(L::Partial(5, 3, 1).Slice<2>(p)).data()));
  891. EXPECT_EQ(
  892. 8,
  893. Distance(
  894. p,
  895. Type<Span<const int32_t>>(L::Partial(5, 3, 1).Slice<1>(p)).data()));
  896. EXPECT_EQ(
  897. 0,
  898. Distance(p, Type<Span<const int8_t>>(L(5, 3, 1).Slice<0>(p)).data()));
  899. EXPECT_EQ(
  900. 24,
  901. Distance(p, Type<Span<const Int128>>(L(5, 3, 1).Slice<2>(p)).data()));
  902. EXPECT_EQ(
  903. 8,
  904. Distance(p, Type<Span<const int32_t>>(L(5, 3, 1).Slice<1>(p)).data()));
  905. }
  906. }
  907. TEST(Layout, SliceByTypeData) {
  908. alignas(max_align_t) const unsigned char p[100] = {};
  909. {
  910. using L = Layout<int32_t>;
  911. EXPECT_EQ(
  912. 0,
  913. Distance(
  914. p,
  915. Type<Span<const int32_t>>(L::Partial(0).Slice<int32_t>(p)).data()));
  916. EXPECT_EQ(
  917. 0,
  918. Distance(
  919. p,
  920. Type<Span<const int32_t>>(L::Partial(3).Slice<int32_t>(p)).data()));
  921. EXPECT_EQ(
  922. 0,
  923. Distance(p, Type<Span<const int32_t>>(L(3).Slice<int32_t>(p)).data()));
  924. }
  925. {
  926. using L = Layout<int8_t, int32_t, Int128>;
  927. EXPECT_EQ(
  928. 0,
  929. Distance(
  930. p,
  931. Type<Span<const int8_t>>(L::Partial(0).Slice<int8_t>(p)).data()));
  932. EXPECT_EQ(
  933. 0,
  934. Distance(
  935. p,
  936. Type<Span<const int8_t>>(L::Partial(1).Slice<int8_t>(p)).data()));
  937. EXPECT_EQ(
  938. 0,
  939. Distance(
  940. p,
  941. Type<Span<const int8_t>>(L::Partial(5).Slice<int8_t>(p)).data()));
  942. EXPECT_EQ(
  943. 0,
  944. Distance(p, Type<Span<const int8_t>>(L::Partial(0, 0).Slice<int8_t>(p))
  945. .data()));
  946. EXPECT_EQ(0, Distance(p, Type<Span<const int32_t>>(
  947. L::Partial(0, 0).Slice<int32_t>(p))
  948. .data()));
  949. EXPECT_EQ(
  950. 0,
  951. Distance(p, Type<Span<const int8_t>>(L::Partial(1, 0).Slice<int8_t>(p))
  952. .data()));
  953. EXPECT_EQ(4, Distance(p, Type<Span<const int32_t>>(
  954. L::Partial(1, 0).Slice<int32_t>(p))
  955. .data()));
  956. EXPECT_EQ(
  957. 0,
  958. Distance(p, Type<Span<const int8_t>>(L::Partial(5, 3).Slice<int8_t>(p))
  959. .data()));
  960. EXPECT_EQ(8, Distance(p, Type<Span<const int32_t>>(
  961. L::Partial(5, 3).Slice<int32_t>(p))
  962. .data()));
  963. EXPECT_EQ(0, Distance(p, Type<Span<const int8_t>>(
  964. L::Partial(0, 0, 0).Slice<int8_t>(p))
  965. .data()));
  966. EXPECT_EQ(0, Distance(p, Type<Span<const int32_t>>(
  967. L::Partial(0, 0, 0).Slice<int32_t>(p))
  968. .data()));
  969. EXPECT_EQ(0, Distance(p, Type<Span<const Int128>>(
  970. L::Partial(0, 0, 0).Slice<Int128>(p))
  971. .data()));
  972. EXPECT_EQ(0, Distance(p, Type<Span<const int8_t>>(
  973. L::Partial(1, 0, 0).Slice<int8_t>(p))
  974. .data()));
  975. EXPECT_EQ(4, Distance(p, Type<Span<const int32_t>>(
  976. L::Partial(1, 0, 0).Slice<int32_t>(p))
  977. .data()));
  978. EXPECT_EQ(8, Distance(p, Type<Span<const Int128>>(
  979. L::Partial(1, 0, 0).Slice<Int128>(p))
  980. .data()));
  981. EXPECT_EQ(0, Distance(p, Type<Span<const int8_t>>(
  982. L::Partial(5, 3, 1).Slice<int8_t>(p))
  983. .data()));
  984. EXPECT_EQ(24, Distance(p, Type<Span<const Int128>>(
  985. L::Partial(5, 3, 1).Slice<Int128>(p))
  986. .data()));
  987. EXPECT_EQ(8, Distance(p, Type<Span<const int32_t>>(
  988. L::Partial(5, 3, 1).Slice<int32_t>(p))
  989. .data()));
  990. EXPECT_EQ(
  991. 0,
  992. Distance(p,
  993. Type<Span<const int8_t>>(L(5, 3, 1).Slice<int8_t>(p)).data()));
  994. EXPECT_EQ(
  995. 24,
  996. Distance(p,
  997. Type<Span<const Int128>>(L(5, 3, 1).Slice<Int128>(p)).data()));
  998. EXPECT_EQ(
  999. 8,
  1000. Distance(
  1001. p, Type<Span<const int32_t>>(L(5, 3, 1).Slice<int32_t>(p)).data()));
  1002. }
  1003. }
  1004. TEST(Layout, MutableSliceByIndexData) {
  1005. alignas(max_align_t) unsigned char p[100];
  1006. {
  1007. using L = Layout<int32_t>;
  1008. EXPECT_EQ(
  1009. 0, Distance(p, Type<Span<int32_t>>(L::Partial(0).Slice<0>(p)).data()));
  1010. EXPECT_EQ(
  1011. 0, Distance(p, Type<Span<int32_t>>(L::Partial(3).Slice<0>(p)).data()));
  1012. EXPECT_EQ(0, Distance(p, Type<Span<int32_t>>(L(3).Slice<0>(p)).data()));
  1013. }
  1014. {
  1015. using L = Layout<int32_t, int32_t>;
  1016. EXPECT_EQ(
  1017. 0, Distance(p, Type<Span<int32_t>>(L::Partial(3).Slice<0>(p)).data()));
  1018. EXPECT_EQ(
  1019. 0,
  1020. Distance(p, Type<Span<int32_t>>(L::Partial(3, 5).Slice<0>(p)).data()));
  1021. EXPECT_EQ(
  1022. 12,
  1023. Distance(p, Type<Span<int32_t>>(L::Partial(3, 5).Slice<1>(p)).data()));
  1024. EXPECT_EQ(0, Distance(p, Type<Span<int32_t>>(L(3, 5).Slice<0>(p)).data()));
  1025. EXPECT_EQ(12, Distance(p, Type<Span<int32_t>>(L(3, 5).Slice<1>(p)).data()));
  1026. }
  1027. {
  1028. using L = Layout<int8_t, int32_t, Int128>;
  1029. EXPECT_EQ(
  1030. 0, Distance(p, Type<Span<int8_t>>(L::Partial(0).Slice<0>(p)).data()));
  1031. EXPECT_EQ(
  1032. 0, Distance(p, Type<Span<int8_t>>(L::Partial(1).Slice<0>(p)).data()));
  1033. EXPECT_EQ(
  1034. 0, Distance(p, Type<Span<int8_t>>(L::Partial(5).Slice<0>(p)).data()));
  1035. EXPECT_EQ(
  1036. 0,
  1037. Distance(p, Type<Span<int8_t>>(L::Partial(0, 0).Slice<0>(p)).data()));
  1038. EXPECT_EQ(
  1039. 0,
  1040. Distance(p, Type<Span<int32_t>>(L::Partial(0, 0).Slice<1>(p)).data()));
  1041. EXPECT_EQ(
  1042. 0,
  1043. Distance(p, Type<Span<int8_t>>(L::Partial(1, 0).Slice<0>(p)).data()));
  1044. EXPECT_EQ(
  1045. 4,
  1046. Distance(p, Type<Span<int32_t>>(L::Partial(1, 0).Slice<1>(p)).data()));
  1047. EXPECT_EQ(
  1048. 0,
  1049. Distance(p, Type<Span<int8_t>>(L::Partial(5, 3).Slice<0>(p)).data()));
  1050. EXPECT_EQ(
  1051. 8,
  1052. Distance(p, Type<Span<int32_t>>(L::Partial(5, 3).Slice<1>(p)).data()));
  1053. EXPECT_EQ(
  1054. 0, Distance(
  1055. p, Type<Span<int8_t>>(L::Partial(0, 0, 0).Slice<0>(p)).data()));
  1056. EXPECT_EQ(
  1057. 0, Distance(
  1058. p, Type<Span<int32_t>>(L::Partial(0, 0, 0).Slice<1>(p)).data()));
  1059. EXPECT_EQ(
  1060. 0, Distance(
  1061. p, Type<Span<Int128>>(L::Partial(0, 0, 0).Slice<2>(p)).data()));
  1062. EXPECT_EQ(
  1063. 0, Distance(
  1064. p, Type<Span<int8_t>>(L::Partial(1, 0, 0).Slice<0>(p)).data()));
  1065. EXPECT_EQ(
  1066. 4, Distance(
  1067. p, Type<Span<int32_t>>(L::Partial(1, 0, 0).Slice<1>(p)).data()));
  1068. EXPECT_EQ(
  1069. 8, Distance(
  1070. p, Type<Span<Int128>>(L::Partial(1, 0, 0).Slice<2>(p)).data()));
  1071. EXPECT_EQ(
  1072. 0, Distance(
  1073. p, Type<Span<int8_t>>(L::Partial(5, 3, 1).Slice<0>(p)).data()));
  1074. EXPECT_EQ(
  1075. 24, Distance(
  1076. p, Type<Span<Int128>>(L::Partial(5, 3, 1).Slice<2>(p)).data()));
  1077. EXPECT_EQ(
  1078. 8, Distance(
  1079. p, Type<Span<int32_t>>(L::Partial(5, 3, 1).Slice<1>(p)).data()));
  1080. EXPECT_EQ(0,
  1081. Distance(p, Type<Span<int8_t>>(L(5, 3, 1).Slice<0>(p)).data()));
  1082. EXPECT_EQ(24,
  1083. Distance(p, Type<Span<Int128>>(L(5, 3, 1).Slice<2>(p)).data()));
  1084. EXPECT_EQ(8,
  1085. Distance(p, Type<Span<int32_t>>(L(5, 3, 1).Slice<1>(p)).data()));
  1086. }
  1087. }
  1088. TEST(Layout, MutableSliceByTypeData) {
  1089. alignas(max_align_t) unsigned char p[100];
  1090. {
  1091. using L = Layout<int32_t>;
  1092. EXPECT_EQ(
  1093. 0, Distance(
  1094. p, Type<Span<int32_t>>(L::Partial(0).Slice<int32_t>(p)).data()));
  1095. EXPECT_EQ(
  1096. 0, Distance(
  1097. p, Type<Span<int32_t>>(L::Partial(3).Slice<int32_t>(p)).data()));
  1098. EXPECT_EQ(0,
  1099. Distance(p, Type<Span<int32_t>>(L(3).Slice<int32_t>(p)).data()));
  1100. }
  1101. {
  1102. using L = Layout<int8_t, int32_t, Int128>;
  1103. EXPECT_EQ(
  1104. 0,
  1105. Distance(p, Type<Span<int8_t>>(L::Partial(0).Slice<int8_t>(p)).data()));
  1106. EXPECT_EQ(
  1107. 0,
  1108. Distance(p, Type<Span<int8_t>>(L::Partial(1).Slice<int8_t>(p)).data()));
  1109. EXPECT_EQ(
  1110. 0,
  1111. Distance(p, Type<Span<int8_t>>(L::Partial(5).Slice<int8_t>(p)).data()));
  1112. EXPECT_EQ(
  1113. 0,
  1114. Distance(p,
  1115. Type<Span<int8_t>>(L::Partial(0, 0).Slice<int8_t>(p)).data()));
  1116. EXPECT_EQ(
  1117. 0,
  1118. Distance(
  1119. p, Type<Span<int32_t>>(L::Partial(0, 0).Slice<int32_t>(p)).data()));
  1120. EXPECT_EQ(
  1121. 0,
  1122. Distance(p,
  1123. Type<Span<int8_t>>(L::Partial(1, 0).Slice<int8_t>(p)).data()));
  1124. EXPECT_EQ(
  1125. 4,
  1126. Distance(
  1127. p, Type<Span<int32_t>>(L::Partial(1, 0).Slice<int32_t>(p)).data()));
  1128. EXPECT_EQ(
  1129. 0,
  1130. Distance(p,
  1131. Type<Span<int8_t>>(L::Partial(5, 3).Slice<int8_t>(p)).data()));
  1132. EXPECT_EQ(
  1133. 8,
  1134. Distance(
  1135. p, Type<Span<int32_t>>(L::Partial(5, 3).Slice<int32_t>(p)).data()));
  1136. EXPECT_EQ(
  1137. 0,
  1138. Distance(
  1139. p,
  1140. Type<Span<int8_t>>(L::Partial(0, 0, 0).Slice<int8_t>(p)).data()));
  1141. EXPECT_EQ(
  1142. 0,
  1143. Distance(
  1144. p,
  1145. Type<Span<int32_t>>(L::Partial(0, 0, 0).Slice<int32_t>(p)).data()));
  1146. EXPECT_EQ(
  1147. 0,
  1148. Distance(
  1149. p,
  1150. Type<Span<Int128>>(L::Partial(0, 0, 0).Slice<Int128>(p)).data()));
  1151. EXPECT_EQ(
  1152. 0,
  1153. Distance(
  1154. p,
  1155. Type<Span<int8_t>>(L::Partial(1, 0, 0).Slice<int8_t>(p)).data()));
  1156. EXPECT_EQ(
  1157. 4,
  1158. Distance(
  1159. p,
  1160. Type<Span<int32_t>>(L::Partial(1, 0, 0).Slice<int32_t>(p)).data()));
  1161. EXPECT_EQ(
  1162. 8,
  1163. Distance(
  1164. p,
  1165. Type<Span<Int128>>(L::Partial(1, 0, 0).Slice<Int128>(p)).data()));
  1166. EXPECT_EQ(
  1167. 0,
  1168. Distance(
  1169. p,
  1170. Type<Span<int8_t>>(L::Partial(5, 3, 1).Slice<int8_t>(p)).data()));
  1171. EXPECT_EQ(
  1172. 24,
  1173. Distance(
  1174. p,
  1175. Type<Span<Int128>>(L::Partial(5, 3, 1).Slice<Int128>(p)).data()));
  1176. EXPECT_EQ(
  1177. 8,
  1178. Distance(
  1179. p,
  1180. Type<Span<int32_t>>(L::Partial(5, 3, 1).Slice<int32_t>(p)).data()));
  1181. EXPECT_EQ(
  1182. 0, Distance(p, Type<Span<int8_t>>(L(5, 3, 1).Slice<int8_t>(p)).data()));
  1183. EXPECT_EQ(
  1184. 24,
  1185. Distance(p, Type<Span<Int128>>(L(5, 3, 1).Slice<Int128>(p)).data()));
  1186. EXPECT_EQ(
  1187. 8,
  1188. Distance(p, Type<Span<int32_t>>(L(5, 3, 1).Slice<int32_t>(p)).data()));
  1189. }
  1190. }
  1191. MATCHER_P(IsSameSlice, slice, "") {
  1192. return arg.size() == slice.size() && arg.data() == slice.data();
  1193. }
  1194. template <typename... M>
  1195. class TupleMatcher {
  1196. public:
  1197. explicit TupleMatcher(M... matchers) : matchers_(std::move(matchers)...) {}
  1198. template <typename Tuple>
  1199. bool MatchAndExplain(const Tuple& p,
  1200. testing::MatchResultListener* /* listener */) const {
  1201. static_assert(std::tuple_size<Tuple>::value == sizeof...(M), "");
  1202. return MatchAndExplainImpl(
  1203. p, absl::make_index_sequence<std::tuple_size<Tuple>::value>{});
  1204. }
  1205. // For the matcher concept. Left empty as we don't really need the diagnostics
  1206. // right now.
  1207. void DescribeTo(::std::ostream* os) const {}
  1208. void DescribeNegationTo(::std::ostream* os) const {}
  1209. private:
  1210. template <typename Tuple, size_t... Is>
  1211. bool MatchAndExplainImpl(const Tuple& p, absl::index_sequence<Is...>) const {
  1212. // Using std::min as a simple variadic "and".
  1213. return std::min(
  1214. {true, testing::SafeMatcherCast<
  1215. const typename std::tuple_element<Is, Tuple>::type&>(
  1216. std::get<Is>(matchers_))
  1217. .Matches(std::get<Is>(p))...});
  1218. }
  1219. std::tuple<M...> matchers_;
  1220. };
  1221. template <typename... M>
  1222. testing::PolymorphicMatcher<TupleMatcher<M...>> Tuple(M... matchers) {
  1223. return testing::MakePolymorphicMatcher(
  1224. TupleMatcher<M...>(std::move(matchers)...));
  1225. }
  1226. TEST(Layout, Slices) {
  1227. alignas(max_align_t) const unsigned char p[100] = {};
  1228. using L = Layout<int8_t, int8_t, Int128>;
  1229. {
  1230. const auto x = L::Partial();
  1231. EXPECT_THAT(Type<std::tuple<>>(x.Slices(p)), Tuple());
  1232. }
  1233. {
  1234. const auto x = L::Partial(1);
  1235. EXPECT_THAT(Type<std::tuple<Span<const int8_t>>>(x.Slices(p)),
  1236. Tuple(IsSameSlice(x.Slice<0>(p))));
  1237. }
  1238. {
  1239. const auto x = L::Partial(1, 2);
  1240. EXPECT_THAT(
  1241. (Type<std::tuple<Span<const int8_t>, Span<const int8_t>>>(x.Slices(p))),
  1242. Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p))));
  1243. }
  1244. {
  1245. const auto x = L::Partial(1, 2, 3);
  1246. EXPECT_THAT((Type<std::tuple<Span<const int8_t>, Span<const int8_t>,
  1247. Span<const Int128>>>(x.Slices(p))),
  1248. Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)),
  1249. IsSameSlice(x.Slice<2>(p))));
  1250. }
  1251. {
  1252. const L x(1, 2, 3);
  1253. EXPECT_THAT((Type<std::tuple<Span<const int8_t>, Span<const int8_t>,
  1254. Span<const Int128>>>(x.Slices(p))),
  1255. Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)),
  1256. IsSameSlice(x.Slice<2>(p))));
  1257. }
  1258. }
  1259. TEST(Layout, MutableSlices) {
  1260. alignas(max_align_t) unsigned char p[100] = {};
  1261. using L = Layout<int8_t, int8_t, Int128>;
  1262. {
  1263. const auto x = L::Partial();
  1264. EXPECT_THAT(Type<std::tuple<>>(x.Slices(p)), Tuple());
  1265. }
  1266. {
  1267. const auto x = L::Partial(1);
  1268. EXPECT_THAT(Type<std::tuple<Span<int8_t>>>(x.Slices(p)),
  1269. Tuple(IsSameSlice(x.Slice<0>(p))));
  1270. }
  1271. {
  1272. const auto x = L::Partial(1, 2);
  1273. EXPECT_THAT((Type<std::tuple<Span<int8_t>, Span<int8_t>>>(x.Slices(p))),
  1274. Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p))));
  1275. }
  1276. {
  1277. const auto x = L::Partial(1, 2, 3);
  1278. EXPECT_THAT((Type<std::tuple<Span<int8_t>, Span<int8_t>, Span<Int128>>>(
  1279. x.Slices(p))),
  1280. Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)),
  1281. IsSameSlice(x.Slice<2>(p))));
  1282. }
  1283. {
  1284. const L x(1, 2, 3);
  1285. EXPECT_THAT((Type<std::tuple<Span<int8_t>, Span<int8_t>, Span<Int128>>>(
  1286. x.Slices(p))),
  1287. Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)),
  1288. IsSameSlice(x.Slice<2>(p))));
  1289. }
  1290. }
  1291. TEST(Layout, UnalignedTypes) {
  1292. constexpr Layout<unsigned char, unsigned char, unsigned char> x(1, 2, 3);
  1293. alignas(max_align_t) unsigned char p[x.AllocSize() + 1];
  1294. EXPECT_THAT(x.Pointers(p + 1), Tuple(p + 1, p + 2, p + 4));
  1295. }
  1296. TEST(Layout, CustomAlignment) {
  1297. constexpr Layout<unsigned char, Aligned<unsigned char, 8>> x(1, 2);
  1298. alignas(max_align_t) unsigned char p[x.AllocSize()];
  1299. EXPECT_EQ(10, x.AllocSize());
  1300. EXPECT_THAT(x.Pointers(p), Tuple(p + 0, p + 8));
  1301. }
  1302. TEST(Layout, OverAligned) {
  1303. constexpr size_t M = alignof(max_align_t);
  1304. constexpr Layout<unsigned char, Aligned<unsigned char, 2 * M>> x(1, 3);
  1305. #ifdef __GNUC__
  1306. // Using __attribute__ ((aligned ())) instead of alignas to bypass a gcc bug:
  1307. // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89357
  1308. __attribute__((aligned(2 * M))) unsigned char p[x.AllocSize()];
  1309. #else
  1310. alignas(2 * M) unsigned char p[x.AllocSize()];
  1311. #endif
  1312. EXPECT_EQ(2 * M + 3, x.AllocSize());
  1313. EXPECT_THAT(x.Pointers(p), Tuple(p + 0, p + 2 * M));
  1314. }
  1315. TEST(Layout, Alignment) {
  1316. static_assert(Layout<int8_t>::Alignment() == 1, "");
  1317. static_assert(Layout<int32_t>::Alignment() == 4, "");
  1318. static_assert(Layout<Int64>::Alignment() == 8, "");
  1319. static_assert(Layout<Aligned<int8_t, 64>>::Alignment() == 64, "");
  1320. static_assert(Layout<int8_t, int32_t, Int64>::Alignment() == 8, "");
  1321. static_assert(Layout<int8_t, Int64, int32_t>::Alignment() == 8, "");
  1322. static_assert(Layout<int32_t, int8_t, Int64>::Alignment() == 8, "");
  1323. static_assert(Layout<int32_t, Int64, int8_t>::Alignment() == 8, "");
  1324. static_assert(Layout<Int64, int8_t, int32_t>::Alignment() == 8, "");
  1325. static_assert(Layout<Int64, int32_t, int8_t>::Alignment() == 8, "");
  1326. }
  1327. TEST(Layout, ConstexprPartial) {
  1328. constexpr size_t M = alignof(max_align_t);
  1329. constexpr Layout<unsigned char, Aligned<unsigned char, 2 * M>> x(1, 3);
  1330. static_assert(x.Partial(1).template Offset<1>() == 2 * M, "");
  1331. }
  1332. // [from, to)
  1333. struct Region {
  1334. size_t from;
  1335. size_t to;
  1336. };
  1337. void ExpectRegionPoisoned(const unsigned char* p, size_t n, bool poisoned) {
  1338. #ifdef ABSL_HAVE_ADDRESS_SANITIZER
  1339. for (size_t i = 0; i != n; ++i) {
  1340. EXPECT_EQ(poisoned, __asan_address_is_poisoned(p + i));
  1341. }
  1342. #endif
  1343. }
  1344. template <size_t N>
  1345. void ExpectPoisoned(const unsigned char (&buf)[N],
  1346. std::initializer_list<Region> reg) {
  1347. size_t prev = 0;
  1348. for (const Region& r : reg) {
  1349. ExpectRegionPoisoned(buf + prev, r.from - prev, false);
  1350. ExpectRegionPoisoned(buf + r.from, r.to - r.from, true);
  1351. prev = r.to;
  1352. }
  1353. ExpectRegionPoisoned(buf + prev, N - prev, false);
  1354. }
  1355. TEST(Layout, PoisonPadding) {
  1356. using L = Layout<int8_t, Int64, int32_t, Int128>;
  1357. constexpr size_t n = L::Partial(1, 2, 3, 4).AllocSize();
  1358. {
  1359. constexpr auto x = L::Partial();
  1360. alignas(max_align_t) const unsigned char c[n] = {};
  1361. x.PoisonPadding(c);
  1362. EXPECT_EQ(x.Slices(c), x.Slices(c));
  1363. ExpectPoisoned(c, {});
  1364. }
  1365. {
  1366. constexpr auto x = L::Partial(1);
  1367. alignas(max_align_t) const unsigned char c[n] = {};
  1368. x.PoisonPadding(c);
  1369. EXPECT_EQ(x.Slices(c), x.Slices(c));
  1370. ExpectPoisoned(c, {{1, 8}});
  1371. }
  1372. {
  1373. constexpr auto x = L::Partial(1, 2);
  1374. alignas(max_align_t) const unsigned char c[n] = {};
  1375. x.PoisonPadding(c);
  1376. EXPECT_EQ(x.Slices(c), x.Slices(c));
  1377. ExpectPoisoned(c, {{1, 8}});
  1378. }
  1379. {
  1380. constexpr auto x = L::Partial(1, 2, 3);
  1381. alignas(max_align_t) const unsigned char c[n] = {};
  1382. x.PoisonPadding(c);
  1383. EXPECT_EQ(x.Slices(c), x.Slices(c));
  1384. ExpectPoisoned(c, {{1, 8}, {36, 40}});
  1385. }
  1386. {
  1387. constexpr auto x = L::Partial(1, 2, 3, 4);
  1388. alignas(max_align_t) const unsigned char c[n] = {};
  1389. x.PoisonPadding(c);
  1390. EXPECT_EQ(x.Slices(c), x.Slices(c));
  1391. ExpectPoisoned(c, {{1, 8}, {36, 40}});
  1392. }
  1393. {
  1394. constexpr L x(1, 2, 3, 4);
  1395. alignas(max_align_t) const unsigned char c[n] = {};
  1396. x.PoisonPadding(c);
  1397. EXPECT_EQ(x.Slices(c), x.Slices(c));
  1398. ExpectPoisoned(c, {{1, 8}, {36, 40}});
  1399. }
  1400. }
  1401. TEST(Layout, DebugString) {
  1402. {
  1403. constexpr auto x = Layout<int8_t, int32_t, int8_t, Int128>::Partial();
  1404. EXPECT_EQ("@0<signed char>(1)", x.DebugString());
  1405. }
  1406. {
  1407. constexpr auto x = Layout<int8_t, int32_t, int8_t, Int128>::Partial(1);
  1408. EXPECT_EQ("@0<signed char>(1)[1]; @4<int>(4)", x.DebugString());
  1409. }
  1410. {
  1411. constexpr auto x = Layout<int8_t, int32_t, int8_t, Int128>::Partial(1, 2);
  1412. EXPECT_EQ("@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)",
  1413. x.DebugString());
  1414. }
  1415. {
  1416. constexpr auto x =
  1417. Layout<int8_t, int32_t, int8_t, Int128>::Partial(1, 2, 3);
  1418. EXPECT_EQ(
  1419. "@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)[3]; "
  1420. "@16" +
  1421. Int128::Name() + "(16)",
  1422. x.DebugString());
  1423. }
  1424. {
  1425. constexpr auto x =
  1426. Layout<int8_t, int32_t, int8_t, Int128>::Partial(1, 2, 3, 4);
  1427. EXPECT_EQ(
  1428. "@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)[3]; "
  1429. "@16" +
  1430. Int128::Name() + "(16)[4]",
  1431. x.DebugString());
  1432. }
  1433. {
  1434. constexpr Layout<int8_t, int32_t, int8_t, Int128> x(1, 2, 3, 4);
  1435. EXPECT_EQ(
  1436. "@0<signed char>(1)[1]; @4<int>(4)[2]; @12<signed char>(1)[3]; "
  1437. "@16" +
  1438. Int128::Name() + "(16)[4]",
  1439. x.DebugString());
  1440. }
  1441. }
  1442. TEST(Layout, CharTypes) {
  1443. constexpr Layout<int32_t> x(1);
  1444. alignas(max_align_t) char c[x.AllocSize()] = {};
  1445. alignas(max_align_t) unsigned char uc[x.AllocSize()] = {};
  1446. alignas(max_align_t) signed char sc[x.AllocSize()] = {};
  1447. alignas(max_align_t) const char cc[x.AllocSize()] = {};
  1448. alignas(max_align_t) const unsigned char cuc[x.AllocSize()] = {};
  1449. alignas(max_align_t) const signed char csc[x.AllocSize()] = {};
  1450. Type<int32_t*>(x.Pointer<0>(c));
  1451. Type<int32_t*>(x.Pointer<0>(uc));
  1452. Type<int32_t*>(x.Pointer<0>(sc));
  1453. Type<const int32_t*>(x.Pointer<0>(cc));
  1454. Type<const int32_t*>(x.Pointer<0>(cuc));
  1455. Type<const int32_t*>(x.Pointer<0>(csc));
  1456. Type<int32_t*>(x.Pointer<int32_t>(c));
  1457. Type<int32_t*>(x.Pointer<int32_t>(uc));
  1458. Type<int32_t*>(x.Pointer<int32_t>(sc));
  1459. Type<const int32_t*>(x.Pointer<int32_t>(cc));
  1460. Type<const int32_t*>(x.Pointer<int32_t>(cuc));
  1461. Type<const int32_t*>(x.Pointer<int32_t>(csc));
  1462. Type<std::tuple<int32_t*>>(x.Pointers(c));
  1463. Type<std::tuple<int32_t*>>(x.Pointers(uc));
  1464. Type<std::tuple<int32_t*>>(x.Pointers(sc));
  1465. Type<std::tuple<const int32_t*>>(x.Pointers(cc));
  1466. Type<std::tuple<const int32_t*>>(x.Pointers(cuc));
  1467. Type<std::tuple<const int32_t*>>(x.Pointers(csc));
  1468. Type<Span<int32_t>>(x.Slice<0>(c));
  1469. Type<Span<int32_t>>(x.Slice<0>(uc));
  1470. Type<Span<int32_t>>(x.Slice<0>(sc));
  1471. Type<Span<const int32_t>>(x.Slice<0>(cc));
  1472. Type<Span<const int32_t>>(x.Slice<0>(cuc));
  1473. Type<Span<const int32_t>>(x.Slice<0>(csc));
  1474. Type<std::tuple<Span<int32_t>>>(x.Slices(c));
  1475. Type<std::tuple<Span<int32_t>>>(x.Slices(uc));
  1476. Type<std::tuple<Span<int32_t>>>(x.Slices(sc));
  1477. Type<std::tuple<Span<const int32_t>>>(x.Slices(cc));
  1478. Type<std::tuple<Span<const int32_t>>>(x.Slices(cuc));
  1479. Type<std::tuple<Span<const int32_t>>>(x.Slices(csc));
  1480. }
  1481. TEST(Layout, ConstElementType) {
  1482. constexpr Layout<const int32_t> x(1);
  1483. alignas(int32_t) char c[x.AllocSize()] = {};
  1484. const char* cc = c;
  1485. const int32_t* p = reinterpret_cast<const int32_t*>(cc);
  1486. EXPECT_EQ(alignof(int32_t), x.Alignment());
  1487. EXPECT_EQ(0, x.Offset<0>());
  1488. EXPECT_EQ(0, x.Offset<const int32_t>());
  1489. EXPECT_THAT(x.Offsets(), ElementsAre(0));
  1490. EXPECT_EQ(1, x.Size<0>());
  1491. EXPECT_EQ(1, x.Size<const int32_t>());
  1492. EXPECT_THAT(x.Sizes(), ElementsAre(1));
  1493. EXPECT_EQ(sizeof(int32_t), x.AllocSize());
  1494. EXPECT_EQ(p, Type<const int32_t*>(x.Pointer<0>(c)));
  1495. EXPECT_EQ(p, Type<const int32_t*>(x.Pointer<0>(cc)));
  1496. EXPECT_EQ(p, Type<const int32_t*>(x.Pointer<const int32_t>(c)));
  1497. EXPECT_EQ(p, Type<const int32_t*>(x.Pointer<const int32_t>(cc)));
  1498. EXPECT_THAT(Type<std::tuple<const int32_t*>>(x.Pointers(c)), Tuple(p));
  1499. EXPECT_THAT(Type<std::tuple<const int32_t*>>(x.Pointers(cc)), Tuple(p));
  1500. EXPECT_THAT(Type<Span<const int32_t>>(x.Slice<0>(c)),
  1501. IsSameSlice(Span<const int32_t>(p, 1)));
  1502. EXPECT_THAT(Type<Span<const int32_t>>(x.Slice<0>(cc)),
  1503. IsSameSlice(Span<const int32_t>(p, 1)));
  1504. EXPECT_THAT(Type<Span<const int32_t>>(x.Slice<const int32_t>(c)),
  1505. IsSameSlice(Span<const int32_t>(p, 1)));
  1506. EXPECT_THAT(Type<Span<const int32_t>>(x.Slice<const int32_t>(cc)),
  1507. IsSameSlice(Span<const int32_t>(p, 1)));
  1508. EXPECT_THAT(Type<std::tuple<Span<const int32_t>>>(x.Slices(c)),
  1509. Tuple(IsSameSlice(Span<const int32_t>(p, 1))));
  1510. EXPECT_THAT(Type<std::tuple<Span<const int32_t>>>(x.Slices(cc)),
  1511. Tuple(IsSameSlice(Span<const int32_t>(p, 1))));
  1512. }
  1513. namespace example {
  1514. // Immutable move-only string with sizeof equal to sizeof(void*). The string
  1515. // size and the characters are kept in the same heap allocation.
  1516. class CompactString {
  1517. public:
  1518. CompactString(const char* s = "") { // NOLINT
  1519. const size_t size = strlen(s);
  1520. // size_t[1], followed by char[size + 1].
  1521. // This statement doesn't allocate memory.
  1522. const L layout(1, size + 1);
  1523. // AllocSize() tells us how much memory we need to allocate for all our
  1524. // data.
  1525. p_.reset(new unsigned char[layout.AllocSize()]);
  1526. // If running under ASAN, mark the padding bytes, if any, to catch memory
  1527. // errors.
  1528. layout.PoisonPadding(p_.get());
  1529. // Store the size in the allocation.
  1530. // Pointer<size_t>() is a synonym for Pointer<0>().
  1531. *layout.Pointer<size_t>(p_.get()) = size;
  1532. // Store the characters in the allocation.
  1533. memcpy(layout.Pointer<char>(p_.get()), s, size + 1);
  1534. }
  1535. size_t size() const {
  1536. // Equivalent to reinterpret_cast<size_t&>(*p).
  1537. return *L::Partial().Pointer<size_t>(p_.get());
  1538. }
  1539. const char* c_str() const {
  1540. // Equivalent to reinterpret_cast<char*>(p.get() + sizeof(size_t)).
  1541. // The argument in Partial(1) specifies that we have size_t[1] in front of
  1542. // the characters.
  1543. return L::Partial(1).Pointer<char>(p_.get());
  1544. }
  1545. private:
  1546. // Our heap allocation contains a size_t followed by an array of chars.
  1547. using L = Layout<size_t, char>;
  1548. std::unique_ptr<unsigned char[]> p_;
  1549. };
  1550. TEST(CompactString, Works) {
  1551. CompactString s = "hello";
  1552. EXPECT_EQ(5, s.size());
  1553. EXPECT_STREQ("hello", s.c_str());
  1554. }
  1555. } // namespace example
  1556. } // namespace
  1557. } // namespace container_internal
  1558. ABSL_NAMESPACE_END
  1559. } // namespace absl