inlined_vector_test.cc 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815
  1. // Copyright 2019 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/inlined_vector.h"
  15. #include <algorithm>
  16. #include <forward_list>
  17. #include <list>
  18. #include <memory>
  19. #include <scoped_allocator>
  20. #include <sstream>
  21. #include <stdexcept>
  22. #include <string>
  23. #include <vector>
  24. #include "gmock/gmock.h"
  25. #include "gtest/gtest.h"
  26. #include "absl/base/attributes.h"
  27. #include "absl/base/internal/exception_testing.h"
  28. #include "absl/base/internal/raw_logging.h"
  29. #include "absl/base/macros.h"
  30. #include "absl/base/options.h"
  31. #include "absl/container/internal/counting_allocator.h"
  32. #include "absl/container/internal/test_instance_tracker.h"
  33. #include "absl/hash/hash_testing.h"
  34. #include "absl/memory/memory.h"
  35. #include "absl/strings/str_cat.h"
  36. namespace {
  37. using absl::container_internal::CountingAllocator;
  38. using absl::test_internal::CopyableMovableInstance;
  39. using absl::test_internal::CopyableOnlyInstance;
  40. using absl::test_internal::InstanceTracker;
  41. using testing::AllOf;
  42. using testing::Each;
  43. using testing::ElementsAre;
  44. using testing::ElementsAreArray;
  45. using testing::Eq;
  46. using testing::Gt;
  47. using testing::PrintToString;
  48. using IntVec = absl::InlinedVector<int, 8>;
  49. MATCHER_P(SizeIs, n, "") {
  50. return testing::ExplainMatchResult(n, arg.size(), result_listener);
  51. }
  52. MATCHER_P(CapacityIs, n, "") {
  53. return testing::ExplainMatchResult(n, arg.capacity(), result_listener);
  54. }
  55. MATCHER_P(ValueIs, e, "") {
  56. return testing::ExplainMatchResult(e, arg.value(), result_listener);
  57. }
  58. // TODO(bsamwel): Add support for movable-only types.
  59. // Test fixture for typed tests on BaseCountedInstance derived classes, see
  60. // test_instance_tracker.h.
  61. template <typename T>
  62. class InstanceTest : public ::testing::Test {};
  63. TYPED_TEST_SUITE_P(InstanceTest);
  64. // A simple reference counted class to make sure that the proper elements are
  65. // destroyed in the erase(begin, end) test.
  66. class RefCounted {
  67. public:
  68. RefCounted(int value, int* count) : value_(value), count_(count) { Ref(); }
  69. RefCounted(const RefCounted& v) : value_(v.value_), count_(v.count_) {
  70. Ref();
  71. }
  72. ~RefCounted() {
  73. Unref();
  74. count_ = nullptr;
  75. }
  76. friend void swap(RefCounted& a, RefCounted& b) {
  77. using std::swap;
  78. swap(a.value_, b.value_);
  79. swap(a.count_, b.count_);
  80. }
  81. RefCounted& operator=(RefCounted v) {
  82. using std::swap;
  83. swap(*this, v);
  84. return *this;
  85. }
  86. void Ref() const {
  87. ABSL_RAW_CHECK(count_ != nullptr, "");
  88. ++(*count_);
  89. }
  90. void Unref() const {
  91. --(*count_);
  92. ABSL_RAW_CHECK(*count_ >= 0, "");
  93. }
  94. int value_;
  95. int* count_;
  96. };
  97. using RefCountedVec = absl::InlinedVector<RefCounted, 8>;
  98. // A class with a vtable pointer
  99. class Dynamic {
  100. public:
  101. virtual ~Dynamic() {}
  102. };
  103. using DynamicVec = absl::InlinedVector<Dynamic, 8>;
  104. // Append 0..len-1 to *v
  105. template <typename Container>
  106. static void Fill(Container* v, int len, int offset = 0) {
  107. for (int i = 0; i < len; i++) {
  108. v->push_back(i + offset);
  109. }
  110. }
  111. static IntVec Fill(int len, int offset = 0) {
  112. IntVec v;
  113. Fill(&v, len, offset);
  114. return v;
  115. }
  116. TEST(IntVec, SimpleOps) {
  117. for (int len = 0; len < 20; len++) {
  118. IntVec v;
  119. const IntVec& cv = v; // const alias
  120. Fill(&v, len);
  121. EXPECT_EQ(len, v.size());
  122. EXPECT_LE(len, v.capacity());
  123. for (int i = 0; i < len; i++) {
  124. EXPECT_EQ(i, v[i]);
  125. EXPECT_EQ(i, v.at(i));
  126. }
  127. EXPECT_EQ(v.begin(), v.data());
  128. EXPECT_EQ(cv.begin(), cv.data());
  129. int counter = 0;
  130. for (IntVec::iterator iter = v.begin(); iter != v.end(); ++iter) {
  131. EXPECT_EQ(counter, *iter);
  132. counter++;
  133. }
  134. EXPECT_EQ(counter, len);
  135. counter = 0;
  136. for (IntVec::const_iterator iter = v.begin(); iter != v.end(); ++iter) {
  137. EXPECT_EQ(counter, *iter);
  138. counter++;
  139. }
  140. EXPECT_EQ(counter, len);
  141. counter = 0;
  142. for (IntVec::const_iterator iter = v.cbegin(); iter != v.cend(); ++iter) {
  143. EXPECT_EQ(counter, *iter);
  144. counter++;
  145. }
  146. EXPECT_EQ(counter, len);
  147. if (len > 0) {
  148. EXPECT_EQ(0, v.front());
  149. EXPECT_EQ(len - 1, v.back());
  150. v.pop_back();
  151. EXPECT_EQ(len - 1, v.size());
  152. for (int i = 0; i < v.size(); ++i) {
  153. EXPECT_EQ(i, v[i]);
  154. EXPECT_EQ(i, v.at(i));
  155. }
  156. }
  157. }
  158. }
  159. TEST(IntVec, PopBackNoOverflow) {
  160. IntVec v = {1};
  161. v.pop_back();
  162. EXPECT_EQ(v.size(), 0);
  163. }
  164. TEST(IntVec, AtThrows) {
  165. IntVec v = {1, 2, 3};
  166. EXPECT_EQ(v.at(2), 3);
  167. ABSL_BASE_INTERNAL_EXPECT_FAIL(v.at(3), std::out_of_range,
  168. "failed bounds check");
  169. }
  170. TEST(IntVec, ReverseIterator) {
  171. for (int len = 0; len < 20; len++) {
  172. IntVec v;
  173. Fill(&v, len);
  174. int counter = len;
  175. for (IntVec::reverse_iterator iter = v.rbegin(); iter != v.rend(); ++iter) {
  176. counter--;
  177. EXPECT_EQ(counter, *iter);
  178. }
  179. EXPECT_EQ(counter, 0);
  180. counter = len;
  181. for (IntVec::const_reverse_iterator iter = v.rbegin(); iter != v.rend();
  182. ++iter) {
  183. counter--;
  184. EXPECT_EQ(counter, *iter);
  185. }
  186. EXPECT_EQ(counter, 0);
  187. counter = len;
  188. for (IntVec::const_reverse_iterator iter = v.crbegin(); iter != v.crend();
  189. ++iter) {
  190. counter--;
  191. EXPECT_EQ(counter, *iter);
  192. }
  193. EXPECT_EQ(counter, 0);
  194. }
  195. }
  196. TEST(IntVec, Erase) {
  197. for (int len = 1; len < 20; len++) {
  198. for (int i = 0; i < len; ++i) {
  199. IntVec v;
  200. Fill(&v, len);
  201. v.erase(v.begin() + i);
  202. EXPECT_EQ(len - 1, v.size());
  203. for (int j = 0; j < i; ++j) {
  204. EXPECT_EQ(j, v[j]);
  205. }
  206. for (int j = i; j < len - 1; ++j) {
  207. EXPECT_EQ(j + 1, v[j]);
  208. }
  209. }
  210. }
  211. }
  212. TEST(IntVec, Hardened) {
  213. IntVec v;
  214. Fill(&v, 10);
  215. EXPECT_EQ(v[9], 9);
  216. #if !defined(NDEBUG) || ABSL_OPTION_HARDENED
  217. EXPECT_DEATH_IF_SUPPORTED(v[10], "");
  218. EXPECT_DEATH_IF_SUPPORTED(v[-1], "");
  219. #endif
  220. }
  221. // At the end of this test loop, the elements between [erase_begin, erase_end)
  222. // should have reference counts == 0, and all others elements should have
  223. // reference counts == 1.
  224. TEST(RefCountedVec, EraseBeginEnd) {
  225. for (int len = 1; len < 20; ++len) {
  226. for (int erase_begin = 0; erase_begin < len; ++erase_begin) {
  227. for (int erase_end = erase_begin; erase_end <= len; ++erase_end) {
  228. std::vector<int> counts(len, 0);
  229. RefCountedVec v;
  230. for (int i = 0; i < len; ++i) {
  231. v.push_back(RefCounted(i, &counts[i]));
  232. }
  233. int erase_len = erase_end - erase_begin;
  234. v.erase(v.begin() + erase_begin, v.begin() + erase_end);
  235. EXPECT_EQ(len - erase_len, v.size());
  236. // Check the elements before the first element erased.
  237. for (int i = 0; i < erase_begin; ++i) {
  238. EXPECT_EQ(i, v[i].value_);
  239. }
  240. // Check the elements after the first element erased.
  241. for (int i = erase_begin; i < v.size(); ++i) {
  242. EXPECT_EQ(i + erase_len, v[i].value_);
  243. }
  244. // Check that the elements at the beginning are preserved.
  245. for (int i = 0; i < erase_begin; ++i) {
  246. EXPECT_EQ(1, counts[i]);
  247. }
  248. // Check that the erased elements are destroyed
  249. for (int i = erase_begin; i < erase_end; ++i) {
  250. EXPECT_EQ(0, counts[i]);
  251. }
  252. // Check that the elements at the end are preserved.
  253. for (int i = erase_end; i < len; ++i) {
  254. EXPECT_EQ(1, counts[i]);
  255. }
  256. }
  257. }
  258. }
  259. }
  260. struct NoDefaultCtor {
  261. explicit NoDefaultCtor(int) {}
  262. };
  263. struct NoCopy {
  264. NoCopy() {}
  265. NoCopy(const NoCopy&) = delete;
  266. };
  267. struct NoAssign {
  268. NoAssign() {}
  269. NoAssign& operator=(const NoAssign&) = delete;
  270. };
  271. struct MoveOnly {
  272. MoveOnly() {}
  273. MoveOnly(MoveOnly&&) = default;
  274. MoveOnly& operator=(MoveOnly&&) = default;
  275. };
  276. TEST(InlinedVectorTest, NoDefaultCtor) {
  277. absl::InlinedVector<NoDefaultCtor, 1> v(10, NoDefaultCtor(2));
  278. (void)v;
  279. }
  280. TEST(InlinedVectorTest, NoCopy) {
  281. absl::InlinedVector<NoCopy, 1> v(10);
  282. (void)v;
  283. }
  284. TEST(InlinedVectorTest, NoAssign) {
  285. absl::InlinedVector<NoAssign, 1> v(10);
  286. (void)v;
  287. }
  288. TEST(InlinedVectorTest, MoveOnly) {
  289. absl::InlinedVector<MoveOnly, 2> v;
  290. v.push_back(MoveOnly{});
  291. v.push_back(MoveOnly{});
  292. v.push_back(MoveOnly{});
  293. v.erase(v.begin());
  294. v.push_back(MoveOnly{});
  295. v.erase(v.begin(), v.begin() + 1);
  296. v.insert(v.begin(), MoveOnly{});
  297. v.emplace(v.begin());
  298. v.emplace(v.begin(), MoveOnly{});
  299. }
  300. TEST(InlinedVectorTest, Noexcept) {
  301. EXPECT_TRUE(std::is_nothrow_move_constructible<IntVec>::value);
  302. EXPECT_TRUE((std::is_nothrow_move_constructible<
  303. absl::InlinedVector<MoveOnly, 2>>::value));
  304. struct MoveCanThrow {
  305. MoveCanThrow(MoveCanThrow&&) {}
  306. };
  307. EXPECT_EQ(absl::default_allocator_is_nothrow::value,
  308. (std::is_nothrow_move_constructible<
  309. absl::InlinedVector<MoveCanThrow, 2>>::value));
  310. }
  311. TEST(InlinedVectorTest, EmplaceBack) {
  312. absl::InlinedVector<std::pair<std::string, int>, 1> v;
  313. auto& inlined_element = v.emplace_back("answer", 42);
  314. EXPECT_EQ(&inlined_element, &v[0]);
  315. EXPECT_EQ(inlined_element.first, "answer");
  316. EXPECT_EQ(inlined_element.second, 42);
  317. auto& allocated_element = v.emplace_back("taxicab", 1729);
  318. EXPECT_EQ(&allocated_element, &v[1]);
  319. EXPECT_EQ(allocated_element.first, "taxicab");
  320. EXPECT_EQ(allocated_element.second, 1729);
  321. }
  322. TEST(InlinedVectorTest, ShrinkToFitGrowingVector) {
  323. absl::InlinedVector<std::pair<std::string, int>, 1> v;
  324. v.shrink_to_fit();
  325. EXPECT_EQ(v.capacity(), 1);
  326. v.emplace_back("answer", 42);
  327. v.shrink_to_fit();
  328. EXPECT_EQ(v.capacity(), 1);
  329. v.emplace_back("taxicab", 1729);
  330. EXPECT_GE(v.capacity(), 2);
  331. v.shrink_to_fit();
  332. EXPECT_EQ(v.capacity(), 2);
  333. v.reserve(100);
  334. EXPECT_GE(v.capacity(), 100);
  335. v.shrink_to_fit();
  336. EXPECT_EQ(v.capacity(), 2);
  337. }
  338. TEST(InlinedVectorTest, ShrinkToFitEdgeCases) {
  339. {
  340. absl::InlinedVector<std::pair<std::string, int>, 1> v;
  341. v.emplace_back("answer", 42);
  342. v.emplace_back("taxicab", 1729);
  343. EXPECT_GE(v.capacity(), 2);
  344. v.pop_back();
  345. v.shrink_to_fit();
  346. EXPECT_EQ(v.capacity(), 1);
  347. EXPECT_EQ(v[0].first, "answer");
  348. EXPECT_EQ(v[0].second, 42);
  349. }
  350. {
  351. absl::InlinedVector<std::string, 2> v(100);
  352. v.resize(0);
  353. v.shrink_to_fit();
  354. EXPECT_EQ(v.capacity(), 2); // inlined capacity
  355. }
  356. {
  357. absl::InlinedVector<std::string, 2> v(100);
  358. v.resize(1);
  359. v.shrink_to_fit();
  360. EXPECT_EQ(v.capacity(), 2); // inlined capacity
  361. }
  362. {
  363. absl::InlinedVector<std::string, 2> v(100);
  364. v.resize(2);
  365. v.shrink_to_fit();
  366. EXPECT_EQ(v.capacity(), 2);
  367. }
  368. {
  369. absl::InlinedVector<std::string, 2> v(100);
  370. v.resize(3);
  371. v.shrink_to_fit();
  372. EXPECT_EQ(v.capacity(), 3);
  373. }
  374. }
  375. TEST(IntVec, Insert) {
  376. for (int len = 0; len < 20; len++) {
  377. for (int pos = 0; pos <= len; pos++) {
  378. {
  379. // Single element
  380. std::vector<int> std_v;
  381. Fill(&std_v, len);
  382. IntVec v;
  383. Fill(&v, len);
  384. std_v.insert(std_v.begin() + pos, 9999);
  385. IntVec::iterator it = v.insert(v.cbegin() + pos, 9999);
  386. EXPECT_THAT(v, ElementsAreArray(std_v));
  387. EXPECT_EQ(it, v.cbegin() + pos);
  388. }
  389. {
  390. // n elements
  391. std::vector<int> std_v;
  392. Fill(&std_v, len);
  393. IntVec v;
  394. Fill(&v, len);
  395. IntVec::size_type n = 5;
  396. std_v.insert(std_v.begin() + pos, n, 9999);
  397. IntVec::iterator it = v.insert(v.cbegin() + pos, n, 9999);
  398. EXPECT_THAT(v, ElementsAreArray(std_v));
  399. EXPECT_EQ(it, v.cbegin() + pos);
  400. }
  401. {
  402. // Iterator range (random access iterator)
  403. std::vector<int> std_v;
  404. Fill(&std_v, len);
  405. IntVec v;
  406. Fill(&v, len);
  407. const std::vector<int> input = {9999, 8888, 7777};
  408. std_v.insert(std_v.begin() + pos, input.cbegin(), input.cend());
  409. IntVec::iterator it =
  410. v.insert(v.cbegin() + pos, input.cbegin(), input.cend());
  411. EXPECT_THAT(v, ElementsAreArray(std_v));
  412. EXPECT_EQ(it, v.cbegin() + pos);
  413. }
  414. {
  415. // Iterator range (forward iterator)
  416. std::vector<int> std_v;
  417. Fill(&std_v, len);
  418. IntVec v;
  419. Fill(&v, len);
  420. const std::forward_list<int> input = {9999, 8888, 7777};
  421. std_v.insert(std_v.begin() + pos, input.cbegin(), input.cend());
  422. IntVec::iterator it =
  423. v.insert(v.cbegin() + pos, input.cbegin(), input.cend());
  424. EXPECT_THAT(v, ElementsAreArray(std_v));
  425. EXPECT_EQ(it, v.cbegin() + pos);
  426. }
  427. {
  428. // Iterator range (input iterator)
  429. std::vector<int> std_v;
  430. Fill(&std_v, len);
  431. IntVec v;
  432. Fill(&v, len);
  433. std_v.insert(std_v.begin() + pos, {9999, 8888, 7777});
  434. std::istringstream input("9999 8888 7777");
  435. IntVec::iterator it =
  436. v.insert(v.cbegin() + pos, std::istream_iterator<int>(input),
  437. std::istream_iterator<int>());
  438. EXPECT_THAT(v, ElementsAreArray(std_v));
  439. EXPECT_EQ(it, v.cbegin() + pos);
  440. }
  441. {
  442. // Initializer list
  443. std::vector<int> std_v;
  444. Fill(&std_v, len);
  445. IntVec v;
  446. Fill(&v, len);
  447. std_v.insert(std_v.begin() + pos, {9999, 8888});
  448. IntVec::iterator it = v.insert(v.cbegin() + pos, {9999, 8888});
  449. EXPECT_THAT(v, ElementsAreArray(std_v));
  450. EXPECT_EQ(it, v.cbegin() + pos);
  451. }
  452. }
  453. }
  454. }
  455. TEST(RefCountedVec, InsertConstructorDestructor) {
  456. // Make sure the proper construction/destruction happen during insert
  457. // operations.
  458. for (int len = 0; len < 20; len++) {
  459. SCOPED_TRACE(len);
  460. for (int pos = 0; pos <= len; pos++) {
  461. SCOPED_TRACE(pos);
  462. std::vector<int> counts(len, 0);
  463. int inserted_count = 0;
  464. RefCountedVec v;
  465. for (int i = 0; i < len; ++i) {
  466. SCOPED_TRACE(i);
  467. v.push_back(RefCounted(i, &counts[i]));
  468. }
  469. EXPECT_THAT(counts, Each(Eq(1)));
  470. RefCounted insert_element(9999, &inserted_count);
  471. EXPECT_EQ(1, inserted_count);
  472. v.insert(v.begin() + pos, insert_element);
  473. EXPECT_EQ(2, inserted_count);
  474. // Check that the elements at the end are preserved.
  475. EXPECT_THAT(counts, Each(Eq(1)));
  476. EXPECT_EQ(2, inserted_count);
  477. }
  478. }
  479. }
  480. TEST(IntVec, Resize) {
  481. for (int len = 0; len < 20; len++) {
  482. IntVec v;
  483. Fill(&v, len);
  484. // Try resizing up and down by k elements
  485. static const int kResizeElem = 1000000;
  486. for (int k = 0; k < 10; k++) {
  487. // Enlarging resize
  488. v.resize(len + k, kResizeElem);
  489. EXPECT_EQ(len + k, v.size());
  490. EXPECT_LE(len + k, v.capacity());
  491. for (int i = 0; i < len + k; i++) {
  492. if (i < len) {
  493. EXPECT_EQ(i, v[i]);
  494. } else {
  495. EXPECT_EQ(kResizeElem, v[i]);
  496. }
  497. }
  498. // Shrinking resize
  499. v.resize(len, kResizeElem);
  500. EXPECT_EQ(len, v.size());
  501. EXPECT_LE(len, v.capacity());
  502. for (int i = 0; i < len; i++) {
  503. EXPECT_EQ(i, v[i]);
  504. }
  505. }
  506. }
  507. }
  508. TEST(IntVec, InitWithLength) {
  509. for (int len = 0; len < 20; len++) {
  510. IntVec v(len, 7);
  511. EXPECT_EQ(len, v.size());
  512. EXPECT_LE(len, v.capacity());
  513. for (int i = 0; i < len; i++) {
  514. EXPECT_EQ(7, v[i]);
  515. }
  516. }
  517. }
  518. TEST(IntVec, CopyConstructorAndAssignment) {
  519. for (int len = 0; len < 20; len++) {
  520. IntVec v;
  521. Fill(&v, len);
  522. EXPECT_EQ(len, v.size());
  523. EXPECT_LE(len, v.capacity());
  524. IntVec v2(v);
  525. EXPECT_TRUE(v == v2) << PrintToString(v) << PrintToString(v2);
  526. for (int start_len = 0; start_len < 20; start_len++) {
  527. IntVec v3;
  528. Fill(&v3, start_len, 99); // Add dummy elements that should go away
  529. v3 = v;
  530. EXPECT_TRUE(v == v3) << PrintToString(v) << PrintToString(v3);
  531. }
  532. }
  533. }
  534. TEST(IntVec, AliasingCopyAssignment) {
  535. for (int len = 0; len < 20; ++len) {
  536. IntVec original;
  537. Fill(&original, len);
  538. IntVec dup = original;
  539. dup = *&dup;
  540. EXPECT_EQ(dup, original);
  541. }
  542. }
  543. TEST(IntVec, MoveConstructorAndAssignment) {
  544. for (int len = 0; len < 20; len++) {
  545. IntVec v_in;
  546. const int inlined_capacity = v_in.capacity();
  547. Fill(&v_in, len);
  548. EXPECT_EQ(len, v_in.size());
  549. EXPECT_LE(len, v_in.capacity());
  550. {
  551. IntVec v_temp(v_in);
  552. auto* old_data = v_temp.data();
  553. IntVec v_out(std::move(v_temp));
  554. EXPECT_TRUE(v_in == v_out) << PrintToString(v_in) << PrintToString(v_out);
  555. if (v_in.size() > inlined_capacity) {
  556. // Allocation is moved as a whole, data stays in place.
  557. EXPECT_TRUE(v_out.data() == old_data);
  558. } else {
  559. EXPECT_FALSE(v_out.data() == old_data);
  560. }
  561. }
  562. for (int start_len = 0; start_len < 20; start_len++) {
  563. IntVec v_out;
  564. Fill(&v_out, start_len, 99); // Add dummy elements that should go away
  565. IntVec v_temp(v_in);
  566. auto* old_data = v_temp.data();
  567. v_out = std::move(v_temp);
  568. EXPECT_TRUE(v_in == v_out) << PrintToString(v_in) << PrintToString(v_out);
  569. if (v_in.size() > inlined_capacity) {
  570. // Allocation is moved as a whole, data stays in place.
  571. EXPECT_TRUE(v_out.data() == old_data);
  572. } else {
  573. EXPECT_FALSE(v_out.data() == old_data);
  574. }
  575. }
  576. }
  577. }
  578. class NotTriviallyDestructible {
  579. public:
  580. NotTriviallyDestructible() : p_(new int(1)) {}
  581. explicit NotTriviallyDestructible(int i) : p_(new int(i)) {}
  582. NotTriviallyDestructible(const NotTriviallyDestructible& other)
  583. : p_(new int(*other.p_)) {}
  584. NotTriviallyDestructible& operator=(const NotTriviallyDestructible& other) {
  585. p_ = absl::make_unique<int>(*other.p_);
  586. return *this;
  587. }
  588. bool operator==(const NotTriviallyDestructible& other) const {
  589. return *p_ == *other.p_;
  590. }
  591. private:
  592. std::unique_ptr<int> p_;
  593. };
  594. TEST(AliasingTest, Emplace) {
  595. for (int i = 2; i < 20; ++i) {
  596. absl::InlinedVector<NotTriviallyDestructible, 10> vec;
  597. for (int j = 0; j < i; ++j) {
  598. vec.push_back(NotTriviallyDestructible(j));
  599. }
  600. vec.emplace(vec.begin(), vec[0]);
  601. EXPECT_EQ(vec[0], vec[1]);
  602. vec.emplace(vec.begin() + i / 2, vec[i / 2]);
  603. EXPECT_EQ(vec[i / 2], vec[i / 2 + 1]);
  604. vec.emplace(vec.end() - 1, vec.back());
  605. EXPECT_EQ(vec[vec.size() - 2], vec.back());
  606. }
  607. }
  608. TEST(AliasingTest, InsertWithCount) {
  609. for (int i = 1; i < 20; ++i) {
  610. absl::InlinedVector<NotTriviallyDestructible, 10> vec;
  611. for (int j = 0; j < i; ++j) {
  612. vec.push_back(NotTriviallyDestructible(j));
  613. }
  614. for (int n = 0; n < 5; ++n) {
  615. // We use back where we can because it's guaranteed to become invalidated
  616. vec.insert(vec.begin(), n, vec.back());
  617. auto b = vec.begin();
  618. EXPECT_TRUE(
  619. std::all_of(b, b + n, [&vec](const NotTriviallyDestructible& x) {
  620. return x == vec.back();
  621. }));
  622. auto m_idx = vec.size() / 2;
  623. vec.insert(vec.begin() + m_idx, n, vec.back());
  624. auto m = vec.begin() + m_idx;
  625. EXPECT_TRUE(
  626. std::all_of(m, m + n, [&vec](const NotTriviallyDestructible& x) {
  627. return x == vec.back();
  628. }));
  629. // We want distinct values so the equality test is meaningful,
  630. // vec[vec.size() - 1] is also almost always invalidated.
  631. auto old_e = vec.size() - 1;
  632. auto val = vec[old_e];
  633. vec.insert(vec.end(), n, vec[old_e]);
  634. auto e = vec.begin() + old_e;
  635. EXPECT_TRUE(std::all_of(
  636. e, e + n,
  637. [&val](const NotTriviallyDestructible& x) { return x == val; }));
  638. }
  639. }
  640. }
  641. TEST(OverheadTest, Storage) {
  642. // Check for size overhead.
  643. // In particular, ensure that std::allocator doesn't cost anything to store.
  644. // The union should be absorbing some of the allocation bookkeeping overhead
  645. // in the larger vectors, leaving only the size_ field as overhead.
  646. struct T { void* val; };
  647. size_t expected_overhead = sizeof(T);
  648. EXPECT_EQ((2 * expected_overhead),
  649. sizeof(absl::InlinedVector<T, 1>) - sizeof(T[1]));
  650. EXPECT_EQ(expected_overhead,
  651. sizeof(absl::InlinedVector<T, 2>) - sizeof(T[2]));
  652. EXPECT_EQ(expected_overhead,
  653. sizeof(absl::InlinedVector<T, 3>) - sizeof(T[3]));
  654. EXPECT_EQ(expected_overhead,
  655. sizeof(absl::InlinedVector<T, 4>) - sizeof(T[4]));
  656. EXPECT_EQ(expected_overhead,
  657. sizeof(absl::InlinedVector<T, 5>) - sizeof(T[5]));
  658. EXPECT_EQ(expected_overhead,
  659. sizeof(absl::InlinedVector<T, 6>) - sizeof(T[6]));
  660. EXPECT_EQ(expected_overhead,
  661. sizeof(absl::InlinedVector<T, 7>) - sizeof(T[7]));
  662. EXPECT_EQ(expected_overhead,
  663. sizeof(absl::InlinedVector<T, 8>) - sizeof(T[8]));
  664. }
  665. TEST(IntVec, Clear) {
  666. for (int len = 0; len < 20; len++) {
  667. SCOPED_TRACE(len);
  668. IntVec v;
  669. Fill(&v, len);
  670. v.clear();
  671. EXPECT_EQ(0, v.size());
  672. EXPECT_EQ(v.begin(), v.end());
  673. }
  674. }
  675. TEST(IntVec, Reserve) {
  676. for (int len = 0; len < 20; len++) {
  677. IntVec v;
  678. Fill(&v, len);
  679. for (int newlen = 0; newlen < 100; newlen++) {
  680. const int* start_rep = v.data();
  681. v.reserve(newlen);
  682. const int* final_rep = v.data();
  683. if (newlen <= len) {
  684. EXPECT_EQ(start_rep, final_rep);
  685. }
  686. EXPECT_LE(newlen, v.capacity());
  687. // Filling up to newlen should not change rep
  688. while (v.size() < newlen) {
  689. v.push_back(0);
  690. }
  691. EXPECT_EQ(final_rep, v.data());
  692. }
  693. }
  694. }
  695. TEST(StringVec, SelfRefPushBack) {
  696. std::vector<std::string> std_v;
  697. absl::InlinedVector<std::string, 4> v;
  698. const std::string s = "A quite long string to ensure heap.";
  699. std_v.push_back(s);
  700. v.push_back(s);
  701. for (int i = 0; i < 20; ++i) {
  702. EXPECT_THAT(v, ElementsAreArray(std_v));
  703. v.push_back(v.back());
  704. std_v.push_back(std_v.back());
  705. }
  706. EXPECT_THAT(v, ElementsAreArray(std_v));
  707. }
  708. TEST(StringVec, SelfRefPushBackWithMove) {
  709. std::vector<std::string> std_v;
  710. absl::InlinedVector<std::string, 4> v;
  711. const std::string s = "A quite long string to ensure heap.";
  712. std_v.push_back(s);
  713. v.push_back(s);
  714. for (int i = 0; i < 20; ++i) {
  715. EXPECT_EQ(v.back(), std_v.back());
  716. v.push_back(std::move(v.back()));
  717. std_v.push_back(std::move(std_v.back()));
  718. }
  719. EXPECT_EQ(v.back(), std_v.back());
  720. }
  721. TEST(StringVec, SelfMove) {
  722. const std::string s = "A quite long string to ensure heap.";
  723. for (int len = 0; len < 20; len++) {
  724. SCOPED_TRACE(len);
  725. absl::InlinedVector<std::string, 8> v;
  726. for (int i = 0; i < len; ++i) {
  727. SCOPED_TRACE(i);
  728. v.push_back(s);
  729. }
  730. // Indirection necessary to avoid compiler warning.
  731. v = std::move(*(&v));
  732. // Ensure that the inlined vector is still in a valid state by copying it.
  733. // We don't expect specific contents since a self-move results in an
  734. // unspecified valid state.
  735. std::vector<std::string> copy(v.begin(), v.end());
  736. }
  737. }
  738. TEST(IntVec, Swap) {
  739. for (int l1 = 0; l1 < 20; l1++) {
  740. SCOPED_TRACE(l1);
  741. for (int l2 = 0; l2 < 20; l2++) {
  742. SCOPED_TRACE(l2);
  743. IntVec a = Fill(l1, 0);
  744. IntVec b = Fill(l2, 100);
  745. {
  746. using std::swap;
  747. swap(a, b);
  748. }
  749. EXPECT_EQ(l1, b.size());
  750. EXPECT_EQ(l2, a.size());
  751. for (int i = 0; i < l1; i++) {
  752. SCOPED_TRACE(i);
  753. EXPECT_EQ(i, b[i]);
  754. }
  755. for (int i = 0; i < l2; i++) {
  756. SCOPED_TRACE(i);
  757. EXPECT_EQ(100 + i, a[i]);
  758. }
  759. }
  760. }
  761. }
  762. TYPED_TEST_P(InstanceTest, Swap) {
  763. using Instance = TypeParam;
  764. using InstanceVec = absl::InlinedVector<Instance, 8>;
  765. for (int l1 = 0; l1 < 20; l1++) {
  766. SCOPED_TRACE(l1);
  767. for (int l2 = 0; l2 < 20; l2++) {
  768. SCOPED_TRACE(l2);
  769. InstanceTracker tracker;
  770. InstanceVec a, b;
  771. const size_t inlined_capacity = a.capacity();
  772. auto min_len = std::min(l1, l2);
  773. auto max_len = std::max(l1, l2);
  774. for (int i = 0; i < l1; i++) a.push_back(Instance(i));
  775. for (int i = 0; i < l2; i++) b.push_back(Instance(100 + i));
  776. EXPECT_EQ(tracker.instances(), l1 + l2);
  777. tracker.ResetCopiesMovesSwaps();
  778. {
  779. using std::swap;
  780. swap(a, b);
  781. }
  782. EXPECT_EQ(tracker.instances(), l1 + l2);
  783. if (a.size() > inlined_capacity && b.size() > inlined_capacity) {
  784. EXPECT_EQ(tracker.swaps(), 0); // Allocations are swapped.
  785. EXPECT_EQ(tracker.moves(), 0);
  786. } else if (a.size() <= inlined_capacity && b.size() <= inlined_capacity) {
  787. EXPECT_EQ(tracker.swaps(), min_len);
  788. EXPECT_EQ((tracker.moves() ? tracker.moves() : tracker.copies()),
  789. max_len - min_len);
  790. } else {
  791. // One is allocated and the other isn't. The allocation is transferred
  792. // without copying elements, and the inlined instances are copied/moved.
  793. EXPECT_EQ(tracker.swaps(), 0);
  794. EXPECT_EQ((tracker.moves() ? tracker.moves() : tracker.copies()),
  795. min_len);
  796. }
  797. EXPECT_EQ(l1, b.size());
  798. EXPECT_EQ(l2, a.size());
  799. for (int i = 0; i < l1; i++) {
  800. EXPECT_EQ(i, b[i].value());
  801. }
  802. for (int i = 0; i < l2; i++) {
  803. EXPECT_EQ(100 + i, a[i].value());
  804. }
  805. }
  806. }
  807. }
  808. TEST(IntVec, EqualAndNotEqual) {
  809. IntVec a, b;
  810. EXPECT_TRUE(a == b);
  811. EXPECT_FALSE(a != b);
  812. a.push_back(3);
  813. EXPECT_FALSE(a == b);
  814. EXPECT_TRUE(a != b);
  815. b.push_back(3);
  816. EXPECT_TRUE(a == b);
  817. EXPECT_FALSE(a != b);
  818. b.push_back(7);
  819. EXPECT_FALSE(a == b);
  820. EXPECT_TRUE(a != b);
  821. a.push_back(6);
  822. EXPECT_FALSE(a == b);
  823. EXPECT_TRUE(a != b);
  824. a.clear();
  825. b.clear();
  826. for (int i = 0; i < 100; i++) {
  827. a.push_back(i);
  828. b.push_back(i);
  829. EXPECT_TRUE(a == b);
  830. EXPECT_FALSE(a != b);
  831. b[i] = b[i] + 1;
  832. EXPECT_FALSE(a == b);
  833. EXPECT_TRUE(a != b);
  834. b[i] = b[i] - 1; // Back to before
  835. EXPECT_TRUE(a == b);
  836. EXPECT_FALSE(a != b);
  837. }
  838. }
  839. TEST(IntVec, RelationalOps) {
  840. IntVec a, b;
  841. EXPECT_FALSE(a < b);
  842. EXPECT_FALSE(b < a);
  843. EXPECT_FALSE(a > b);
  844. EXPECT_FALSE(b > a);
  845. EXPECT_TRUE(a <= b);
  846. EXPECT_TRUE(b <= a);
  847. EXPECT_TRUE(a >= b);
  848. EXPECT_TRUE(b >= a);
  849. b.push_back(3);
  850. EXPECT_TRUE(a < b);
  851. EXPECT_FALSE(b < a);
  852. EXPECT_FALSE(a > b);
  853. EXPECT_TRUE(b > a);
  854. EXPECT_TRUE(a <= b);
  855. EXPECT_FALSE(b <= a);
  856. EXPECT_FALSE(a >= b);
  857. EXPECT_TRUE(b >= a);
  858. }
  859. TYPED_TEST_P(InstanceTest, CountConstructorsDestructors) {
  860. using Instance = TypeParam;
  861. using InstanceVec = absl::InlinedVector<Instance, 8>;
  862. InstanceTracker tracker;
  863. for (int len = 0; len < 20; len++) {
  864. SCOPED_TRACE(len);
  865. tracker.ResetCopiesMovesSwaps();
  866. InstanceVec v;
  867. const size_t inlined_capacity = v.capacity();
  868. for (int i = 0; i < len; i++) {
  869. v.push_back(Instance(i));
  870. }
  871. EXPECT_EQ(tracker.instances(), len);
  872. EXPECT_GE(tracker.copies() + tracker.moves(),
  873. len); // More due to reallocation.
  874. tracker.ResetCopiesMovesSwaps();
  875. // Enlarging resize() must construct some objects
  876. tracker.ResetCopiesMovesSwaps();
  877. v.resize(len + 10, Instance(100));
  878. EXPECT_EQ(tracker.instances(), len + 10);
  879. if (len <= inlined_capacity && len + 10 > inlined_capacity) {
  880. EXPECT_EQ(tracker.copies() + tracker.moves(), 10 + len);
  881. } else {
  882. // Only specify a minimum number of copies + moves. We don't want to
  883. // depend on the reallocation policy here.
  884. EXPECT_GE(tracker.copies() + tracker.moves(),
  885. 10); // More due to reallocation.
  886. }
  887. // Shrinking resize() must destroy some objects
  888. tracker.ResetCopiesMovesSwaps();
  889. v.resize(len, Instance(100));
  890. EXPECT_EQ(tracker.instances(), len);
  891. EXPECT_EQ(tracker.copies(), 0);
  892. EXPECT_EQ(tracker.moves(), 0);
  893. // reserve() must not increase the number of initialized objects
  894. SCOPED_TRACE("reserve");
  895. v.reserve(len + 1000);
  896. EXPECT_EQ(tracker.instances(), len);
  897. EXPECT_EQ(tracker.copies() + tracker.moves(), len);
  898. // pop_back() and erase() must destroy one object
  899. if (len > 0) {
  900. tracker.ResetCopiesMovesSwaps();
  901. v.pop_back();
  902. EXPECT_EQ(tracker.instances(), len - 1);
  903. EXPECT_EQ(tracker.copies(), 0);
  904. EXPECT_EQ(tracker.moves(), 0);
  905. if (!v.empty()) {
  906. tracker.ResetCopiesMovesSwaps();
  907. v.erase(v.begin());
  908. EXPECT_EQ(tracker.instances(), len - 2);
  909. EXPECT_EQ(tracker.copies() + tracker.moves(), len - 2);
  910. }
  911. }
  912. tracker.ResetCopiesMovesSwaps();
  913. int instances_before_empty_erase = tracker.instances();
  914. v.erase(v.begin(), v.begin());
  915. EXPECT_EQ(tracker.instances(), instances_before_empty_erase);
  916. EXPECT_EQ(tracker.copies() + tracker.moves(), 0);
  917. }
  918. }
  919. TYPED_TEST_P(InstanceTest, CountConstructorsDestructorsOnCopyConstruction) {
  920. using Instance = TypeParam;
  921. using InstanceVec = absl::InlinedVector<Instance, 8>;
  922. InstanceTracker tracker;
  923. for (int len = 0; len < 20; len++) {
  924. SCOPED_TRACE(len);
  925. tracker.ResetCopiesMovesSwaps();
  926. InstanceVec v;
  927. for (int i = 0; i < len; i++) {
  928. v.push_back(Instance(i));
  929. }
  930. EXPECT_EQ(tracker.instances(), len);
  931. EXPECT_GE(tracker.copies() + tracker.moves(),
  932. len); // More due to reallocation.
  933. tracker.ResetCopiesMovesSwaps();
  934. { // Copy constructor should create 'len' more instances.
  935. InstanceVec v_copy(v);
  936. EXPECT_EQ(tracker.instances(), len + len);
  937. EXPECT_EQ(tracker.copies(), len);
  938. EXPECT_EQ(tracker.moves(), 0);
  939. }
  940. EXPECT_EQ(tracker.instances(), len);
  941. }
  942. }
  943. TYPED_TEST_P(InstanceTest, CountConstructorsDestructorsOnMoveConstruction) {
  944. using Instance = TypeParam;
  945. using InstanceVec = absl::InlinedVector<Instance, 8>;
  946. InstanceTracker tracker;
  947. for (int len = 0; len < 20; len++) {
  948. SCOPED_TRACE(len);
  949. tracker.ResetCopiesMovesSwaps();
  950. InstanceVec v;
  951. const size_t inlined_capacity = v.capacity();
  952. for (int i = 0; i < len; i++) {
  953. v.push_back(Instance(i));
  954. }
  955. EXPECT_EQ(tracker.instances(), len);
  956. EXPECT_GE(tracker.copies() + tracker.moves(),
  957. len); // More due to reallocation.
  958. tracker.ResetCopiesMovesSwaps();
  959. {
  960. InstanceVec v_copy(std::move(v));
  961. if (len > inlined_capacity) {
  962. // Allocation is moved as a whole.
  963. EXPECT_EQ(tracker.instances(), len);
  964. EXPECT_EQ(tracker.live_instances(), len);
  965. // Tests an implementation detail, don't rely on this in your code.
  966. EXPECT_EQ(v.size(), 0); // NOLINT misc-use-after-move
  967. EXPECT_EQ(tracker.copies(), 0);
  968. EXPECT_EQ(tracker.moves(), 0);
  969. } else {
  970. EXPECT_EQ(tracker.instances(), len + len);
  971. if (Instance::supports_move()) {
  972. EXPECT_EQ(tracker.live_instances(), len);
  973. EXPECT_EQ(tracker.copies(), 0);
  974. EXPECT_EQ(tracker.moves(), len);
  975. } else {
  976. EXPECT_EQ(tracker.live_instances(), len + len);
  977. EXPECT_EQ(tracker.copies(), len);
  978. EXPECT_EQ(tracker.moves(), 0);
  979. }
  980. }
  981. EXPECT_EQ(tracker.swaps(), 0);
  982. }
  983. }
  984. }
  985. TYPED_TEST_P(InstanceTest, CountConstructorsDestructorsOnAssignment) {
  986. using Instance = TypeParam;
  987. using InstanceVec = absl::InlinedVector<Instance, 8>;
  988. InstanceTracker tracker;
  989. for (int len = 0; len < 20; len++) {
  990. SCOPED_TRACE(len);
  991. for (int longorshort = 0; longorshort <= 1; ++longorshort) {
  992. SCOPED_TRACE(longorshort);
  993. tracker.ResetCopiesMovesSwaps();
  994. InstanceVec longer, shorter;
  995. for (int i = 0; i < len; i++) {
  996. longer.push_back(Instance(i));
  997. shorter.push_back(Instance(i));
  998. }
  999. longer.push_back(Instance(len));
  1000. EXPECT_EQ(tracker.instances(), len + len + 1);
  1001. EXPECT_GE(tracker.copies() + tracker.moves(),
  1002. len + len + 1); // More due to reallocation.
  1003. tracker.ResetCopiesMovesSwaps();
  1004. if (longorshort) {
  1005. shorter = longer;
  1006. EXPECT_EQ(tracker.instances(), (len + 1) + (len + 1));
  1007. EXPECT_GE(tracker.copies() + tracker.moves(),
  1008. len + 1); // More due to reallocation.
  1009. } else {
  1010. longer = shorter;
  1011. EXPECT_EQ(tracker.instances(), len + len);
  1012. EXPECT_EQ(tracker.copies() + tracker.moves(), len);
  1013. }
  1014. }
  1015. }
  1016. }
  1017. TYPED_TEST_P(InstanceTest, CountConstructorsDestructorsOnMoveAssignment) {
  1018. using Instance = TypeParam;
  1019. using InstanceVec = absl::InlinedVector<Instance, 8>;
  1020. InstanceTracker tracker;
  1021. for (int len = 0; len < 20; len++) {
  1022. SCOPED_TRACE(len);
  1023. for (int longorshort = 0; longorshort <= 1; ++longorshort) {
  1024. SCOPED_TRACE(longorshort);
  1025. tracker.ResetCopiesMovesSwaps();
  1026. InstanceVec longer, shorter;
  1027. const int inlined_capacity = longer.capacity();
  1028. for (int i = 0; i < len; i++) {
  1029. longer.push_back(Instance(i));
  1030. shorter.push_back(Instance(i));
  1031. }
  1032. longer.push_back(Instance(len));
  1033. EXPECT_EQ(tracker.instances(), len + len + 1);
  1034. EXPECT_GE(tracker.copies() + tracker.moves(),
  1035. len + len + 1); // More due to reallocation.
  1036. tracker.ResetCopiesMovesSwaps();
  1037. int src_len;
  1038. if (longorshort) {
  1039. src_len = len + 1;
  1040. shorter = std::move(longer);
  1041. } else {
  1042. src_len = len;
  1043. longer = std::move(shorter);
  1044. }
  1045. if (src_len > inlined_capacity) {
  1046. // Allocation moved as a whole.
  1047. EXPECT_EQ(tracker.instances(), src_len);
  1048. EXPECT_EQ(tracker.live_instances(), src_len);
  1049. EXPECT_EQ(tracker.copies(), 0);
  1050. EXPECT_EQ(tracker.moves(), 0);
  1051. } else {
  1052. // Elements are all copied.
  1053. EXPECT_EQ(tracker.instances(), src_len + src_len);
  1054. if (Instance::supports_move()) {
  1055. EXPECT_EQ(tracker.copies(), 0);
  1056. EXPECT_EQ(tracker.moves(), src_len);
  1057. EXPECT_EQ(tracker.live_instances(), src_len);
  1058. } else {
  1059. EXPECT_EQ(tracker.copies(), src_len);
  1060. EXPECT_EQ(tracker.moves(), 0);
  1061. EXPECT_EQ(tracker.live_instances(), src_len + src_len);
  1062. }
  1063. }
  1064. EXPECT_EQ(tracker.swaps(), 0);
  1065. }
  1066. }
  1067. }
  1068. TEST(CountElemAssign, SimpleTypeWithInlineBacking) {
  1069. for (size_t original_size = 0; original_size <= 5; ++original_size) {
  1070. SCOPED_TRACE(original_size);
  1071. // Original contents are [12345, 12345, ...]
  1072. std::vector<int> original_contents(original_size, 12345);
  1073. absl::InlinedVector<int, 2> v(original_contents.begin(),
  1074. original_contents.end());
  1075. v.assign(2, 123);
  1076. EXPECT_THAT(v, AllOf(SizeIs(2), ElementsAre(123, 123)));
  1077. if (original_size <= 2) {
  1078. // If the original had inline backing, it should stay inline.
  1079. EXPECT_EQ(2, v.capacity());
  1080. }
  1081. }
  1082. }
  1083. TEST(CountElemAssign, SimpleTypeWithAllocation) {
  1084. for (size_t original_size = 0; original_size <= 5; ++original_size) {
  1085. SCOPED_TRACE(original_size);
  1086. // Original contents are [12345, 12345, ...]
  1087. std::vector<int> original_contents(original_size, 12345);
  1088. absl::InlinedVector<int, 2> v(original_contents.begin(),
  1089. original_contents.end());
  1090. v.assign(3, 123);
  1091. EXPECT_THAT(v, AllOf(SizeIs(3), ElementsAre(123, 123, 123)));
  1092. EXPECT_LE(v.size(), v.capacity());
  1093. }
  1094. }
  1095. TYPED_TEST_P(InstanceTest, CountElemAssignInlineBacking) {
  1096. using Instance = TypeParam;
  1097. for (size_t original_size = 0; original_size <= 5; ++original_size) {
  1098. SCOPED_TRACE(original_size);
  1099. // Original contents are [12345, 12345, ...]
  1100. std::vector<Instance> original_contents(original_size, Instance(12345));
  1101. absl::InlinedVector<Instance, 2> v(original_contents.begin(),
  1102. original_contents.end());
  1103. v.assign(2, Instance(123));
  1104. EXPECT_THAT(v, AllOf(SizeIs(2), ElementsAre(ValueIs(123), ValueIs(123))));
  1105. if (original_size <= 2) {
  1106. // If the original had inline backing, it should stay inline.
  1107. EXPECT_EQ(2, v.capacity());
  1108. }
  1109. }
  1110. }
  1111. template <typename Instance>
  1112. void InstanceCountElemAssignWithAllocationTest() {
  1113. for (size_t original_size = 0; original_size <= 5; ++original_size) {
  1114. SCOPED_TRACE(original_size);
  1115. // Original contents are [12345, 12345, ...]
  1116. std::vector<Instance> original_contents(original_size, Instance(12345));
  1117. absl::InlinedVector<Instance, 2> v(original_contents.begin(),
  1118. original_contents.end());
  1119. v.assign(3, Instance(123));
  1120. EXPECT_THAT(v, AllOf(SizeIs(3), ElementsAre(ValueIs(123), ValueIs(123),
  1121. ValueIs(123))));
  1122. EXPECT_LE(v.size(), v.capacity());
  1123. }
  1124. }
  1125. TEST(CountElemAssign, WithAllocationCopyableInstance) {
  1126. InstanceCountElemAssignWithAllocationTest<CopyableOnlyInstance>();
  1127. }
  1128. TEST(CountElemAssign, WithAllocationCopyableMovableInstance) {
  1129. InstanceCountElemAssignWithAllocationTest<CopyableMovableInstance>();
  1130. }
  1131. TEST(RangedConstructor, SimpleType) {
  1132. std::vector<int> source_v = {4, 5, 6};
  1133. // First try to fit in inline backing
  1134. absl::InlinedVector<int, 4> v(source_v.begin(), source_v.end());
  1135. EXPECT_EQ(3, v.size());
  1136. EXPECT_EQ(4, v.capacity()); // Indication that we're still on inlined storage
  1137. EXPECT_EQ(4, v[0]);
  1138. EXPECT_EQ(5, v[1]);
  1139. EXPECT_EQ(6, v[2]);
  1140. // Now, force a re-allocate
  1141. absl::InlinedVector<int, 2> realloc_v(source_v.begin(), source_v.end());
  1142. EXPECT_EQ(3, realloc_v.size());
  1143. EXPECT_LT(2, realloc_v.capacity());
  1144. EXPECT_EQ(4, realloc_v[0]);
  1145. EXPECT_EQ(5, realloc_v[1]);
  1146. EXPECT_EQ(6, realloc_v[2]);
  1147. }
  1148. // Test for ranged constructors using Instance as the element type and
  1149. // SourceContainer as the source container type.
  1150. template <typename Instance, typename SourceContainer, int inlined_capacity>
  1151. void InstanceRangedConstructorTestForContainer() {
  1152. InstanceTracker tracker;
  1153. SourceContainer source_v = {Instance(0), Instance(1)};
  1154. tracker.ResetCopiesMovesSwaps();
  1155. absl::InlinedVector<Instance, inlined_capacity> v(source_v.begin(),
  1156. source_v.end());
  1157. EXPECT_EQ(2, v.size());
  1158. EXPECT_LT(1, v.capacity());
  1159. EXPECT_EQ(0, v[0].value());
  1160. EXPECT_EQ(1, v[1].value());
  1161. EXPECT_EQ(tracker.copies(), 2);
  1162. EXPECT_EQ(tracker.moves(), 0);
  1163. }
  1164. template <typename Instance, int inlined_capacity>
  1165. void InstanceRangedConstructorTestWithCapacity() {
  1166. // Test with const and non-const, random access and non-random-access sources.
  1167. // TODO(bsamwel): Test with an input iterator source.
  1168. {
  1169. SCOPED_TRACE("std::list");
  1170. InstanceRangedConstructorTestForContainer<Instance, std::list<Instance>,
  1171. inlined_capacity>();
  1172. {
  1173. SCOPED_TRACE("const std::list");
  1174. InstanceRangedConstructorTestForContainer<
  1175. Instance, const std::list<Instance>, inlined_capacity>();
  1176. }
  1177. {
  1178. SCOPED_TRACE("std::vector");
  1179. InstanceRangedConstructorTestForContainer<Instance, std::vector<Instance>,
  1180. inlined_capacity>();
  1181. }
  1182. {
  1183. SCOPED_TRACE("const std::vector");
  1184. InstanceRangedConstructorTestForContainer<
  1185. Instance, const std::vector<Instance>, inlined_capacity>();
  1186. }
  1187. }
  1188. }
  1189. TYPED_TEST_P(InstanceTest, RangedConstructor) {
  1190. using Instance = TypeParam;
  1191. SCOPED_TRACE("capacity=1");
  1192. InstanceRangedConstructorTestWithCapacity<Instance, 1>();
  1193. SCOPED_TRACE("capacity=2");
  1194. InstanceRangedConstructorTestWithCapacity<Instance, 2>();
  1195. }
  1196. TEST(RangedConstructor, ElementsAreConstructed) {
  1197. std::vector<std::string> source_v = {"cat", "dog"};
  1198. // Force expansion and re-allocation of v. Ensures that when the vector is
  1199. // expanded that new elements are constructed.
  1200. absl::InlinedVector<std::string, 1> v(source_v.begin(), source_v.end());
  1201. EXPECT_EQ("cat", v[0]);
  1202. EXPECT_EQ("dog", v[1]);
  1203. }
  1204. TEST(RangedAssign, SimpleType) {
  1205. // Test for all combinations of original sizes (empty and non-empty inline,
  1206. // and out of line) and target sizes.
  1207. for (size_t original_size = 0; original_size <= 5; ++original_size) {
  1208. SCOPED_TRACE(original_size);
  1209. // Original contents are [12345, 12345, ...]
  1210. std::vector<int> original_contents(original_size, 12345);
  1211. for (size_t target_size = 0; target_size <= 5; ++target_size) {
  1212. SCOPED_TRACE(target_size);
  1213. // New contents are [3, 4, ...]
  1214. std::vector<int> new_contents;
  1215. for (size_t i = 0; i < target_size; ++i) {
  1216. new_contents.push_back(i + 3);
  1217. }
  1218. absl::InlinedVector<int, 3> v(original_contents.begin(),
  1219. original_contents.end());
  1220. v.assign(new_contents.begin(), new_contents.end());
  1221. EXPECT_EQ(new_contents.size(), v.size());
  1222. EXPECT_LE(new_contents.size(), v.capacity());
  1223. if (target_size <= 3 && original_size <= 3) {
  1224. // Storage should stay inline when target size is small.
  1225. EXPECT_EQ(3, v.capacity());
  1226. }
  1227. EXPECT_THAT(v, ElementsAreArray(new_contents));
  1228. }
  1229. }
  1230. }
  1231. // Returns true if lhs and rhs have the same value.
  1232. template <typename Instance>
  1233. static bool InstanceValuesEqual(const Instance& lhs, const Instance& rhs) {
  1234. return lhs.value() == rhs.value();
  1235. }
  1236. // Test for ranged assign() using Instance as the element type and
  1237. // SourceContainer as the source container type.
  1238. template <typename Instance, typename SourceContainer>
  1239. void InstanceRangedAssignTestForContainer() {
  1240. // Test for all combinations of original sizes (empty and non-empty inline,
  1241. // and out of line) and target sizes.
  1242. for (size_t original_size = 0; original_size <= 5; ++original_size) {
  1243. SCOPED_TRACE(original_size);
  1244. // Original contents are [12345, 12345, ...]
  1245. std::vector<Instance> original_contents(original_size, Instance(12345));
  1246. for (size_t target_size = 0; target_size <= 5; ++target_size) {
  1247. SCOPED_TRACE(target_size);
  1248. // New contents are [3, 4, ...]
  1249. // Generate data using a non-const container, because SourceContainer
  1250. // itself may be const.
  1251. // TODO(bsamwel): Test with an input iterator.
  1252. std::vector<Instance> new_contents_in;
  1253. for (size_t i = 0; i < target_size; ++i) {
  1254. new_contents_in.push_back(Instance(i + 3));
  1255. }
  1256. SourceContainer new_contents(new_contents_in.begin(),
  1257. new_contents_in.end());
  1258. absl::InlinedVector<Instance, 3> v(original_contents.begin(),
  1259. original_contents.end());
  1260. v.assign(new_contents.begin(), new_contents.end());
  1261. EXPECT_EQ(new_contents.size(), v.size());
  1262. EXPECT_LE(new_contents.size(), v.capacity());
  1263. if (target_size <= 3 && original_size <= 3) {
  1264. // Storage should stay inline when target size is small.
  1265. EXPECT_EQ(3, v.capacity());
  1266. }
  1267. EXPECT_TRUE(std::equal(v.begin(), v.end(), new_contents.begin(),
  1268. InstanceValuesEqual<Instance>));
  1269. }
  1270. }
  1271. }
  1272. TYPED_TEST_P(InstanceTest, RangedAssign) {
  1273. using Instance = TypeParam;
  1274. // Test with const and non-const, random access and non-random-access sources.
  1275. // TODO(bsamwel): Test with an input iterator source.
  1276. SCOPED_TRACE("std::list");
  1277. InstanceRangedAssignTestForContainer<Instance, std::list<Instance>>();
  1278. SCOPED_TRACE("const std::list");
  1279. InstanceRangedAssignTestForContainer<Instance, const std::list<Instance>>();
  1280. SCOPED_TRACE("std::vector");
  1281. InstanceRangedAssignTestForContainer<Instance, std::vector<Instance>>();
  1282. SCOPED_TRACE("const std::vector");
  1283. InstanceRangedAssignTestForContainer<Instance, const std::vector<Instance>>();
  1284. }
  1285. TEST(InitializerListConstructor, SimpleTypeWithInlineBacking) {
  1286. EXPECT_THAT((absl::InlinedVector<int, 4>{4, 5, 6}),
  1287. AllOf(SizeIs(3), CapacityIs(4), ElementsAre(4, 5, 6)));
  1288. }
  1289. TEST(InitializerListConstructor, SimpleTypeWithReallocationRequired) {
  1290. EXPECT_THAT((absl::InlinedVector<int, 2>{4, 5, 6}),
  1291. AllOf(SizeIs(3), CapacityIs(Gt(2)), ElementsAre(4, 5, 6)));
  1292. }
  1293. TEST(InitializerListConstructor, DisparateTypesInList) {
  1294. EXPECT_THAT((absl::InlinedVector<int, 2>{-7, 8ULL}), ElementsAre(-7, 8));
  1295. EXPECT_THAT((absl::InlinedVector<std::string, 2>{"foo", std::string("bar")}),
  1296. ElementsAre("foo", "bar"));
  1297. }
  1298. TEST(InitializerListConstructor, ComplexTypeWithInlineBacking) {
  1299. EXPECT_THAT((absl::InlinedVector<CopyableMovableInstance, 1>{
  1300. CopyableMovableInstance(0)}),
  1301. AllOf(SizeIs(1), CapacityIs(1), ElementsAre(ValueIs(0))));
  1302. }
  1303. TEST(InitializerListConstructor, ComplexTypeWithReallocationRequired) {
  1304. EXPECT_THAT(
  1305. (absl::InlinedVector<CopyableMovableInstance, 1>{
  1306. CopyableMovableInstance(0), CopyableMovableInstance(1)}),
  1307. AllOf(SizeIs(2), CapacityIs(Gt(1)), ElementsAre(ValueIs(0), ValueIs(1))));
  1308. }
  1309. TEST(InitializerListAssign, SimpleTypeFitsInlineBacking) {
  1310. for (size_t original_size = 0; original_size <= 4; ++original_size) {
  1311. SCOPED_TRACE(original_size);
  1312. absl::InlinedVector<int, 2> v1(original_size, 12345);
  1313. const size_t original_capacity_v1 = v1.capacity();
  1314. v1.assign({3});
  1315. EXPECT_THAT(
  1316. v1, AllOf(SizeIs(1), CapacityIs(original_capacity_v1), ElementsAre(3)));
  1317. absl::InlinedVector<int, 2> v2(original_size, 12345);
  1318. const size_t original_capacity_v2 = v2.capacity();
  1319. v2 = {3};
  1320. EXPECT_THAT(
  1321. v2, AllOf(SizeIs(1), CapacityIs(original_capacity_v2), ElementsAre(3)));
  1322. }
  1323. }
  1324. TEST(InitializerListAssign, SimpleTypeDoesNotFitInlineBacking) {
  1325. for (size_t original_size = 0; original_size <= 4; ++original_size) {
  1326. SCOPED_TRACE(original_size);
  1327. absl::InlinedVector<int, 2> v1(original_size, 12345);
  1328. v1.assign({3, 4, 5});
  1329. EXPECT_THAT(v1, AllOf(SizeIs(3), ElementsAre(3, 4, 5)));
  1330. EXPECT_LE(3, v1.capacity());
  1331. absl::InlinedVector<int, 2> v2(original_size, 12345);
  1332. v2 = {3, 4, 5};
  1333. EXPECT_THAT(v2, AllOf(SizeIs(3), ElementsAre(3, 4, 5)));
  1334. EXPECT_LE(3, v2.capacity());
  1335. }
  1336. }
  1337. TEST(InitializerListAssign, DisparateTypesInList) {
  1338. absl::InlinedVector<int, 2> v_int1;
  1339. v_int1.assign({-7, 8ULL});
  1340. EXPECT_THAT(v_int1, ElementsAre(-7, 8));
  1341. absl::InlinedVector<int, 2> v_int2;
  1342. v_int2 = {-7, 8ULL};
  1343. EXPECT_THAT(v_int2, ElementsAre(-7, 8));
  1344. absl::InlinedVector<std::string, 2> v_string1;
  1345. v_string1.assign({"foo", std::string("bar")});
  1346. EXPECT_THAT(v_string1, ElementsAre("foo", "bar"));
  1347. absl::InlinedVector<std::string, 2> v_string2;
  1348. v_string2 = {"foo", std::string("bar")};
  1349. EXPECT_THAT(v_string2, ElementsAre("foo", "bar"));
  1350. }
  1351. TYPED_TEST_P(InstanceTest, InitializerListAssign) {
  1352. using Instance = TypeParam;
  1353. for (size_t original_size = 0; original_size <= 4; ++original_size) {
  1354. SCOPED_TRACE(original_size);
  1355. absl::InlinedVector<Instance, 2> v(original_size, Instance(12345));
  1356. const size_t original_capacity = v.capacity();
  1357. v.assign({Instance(3)});
  1358. EXPECT_THAT(v, AllOf(SizeIs(1), CapacityIs(original_capacity),
  1359. ElementsAre(ValueIs(3))));
  1360. }
  1361. for (size_t original_size = 0; original_size <= 4; ++original_size) {
  1362. SCOPED_TRACE(original_size);
  1363. absl::InlinedVector<Instance, 2> v(original_size, Instance(12345));
  1364. v.assign({Instance(3), Instance(4), Instance(5)});
  1365. EXPECT_THAT(
  1366. v, AllOf(SizeIs(3), ElementsAre(ValueIs(3), ValueIs(4), ValueIs(5))));
  1367. EXPECT_LE(3, v.capacity());
  1368. }
  1369. }
  1370. REGISTER_TYPED_TEST_CASE_P(InstanceTest, Swap, CountConstructorsDestructors,
  1371. CountConstructorsDestructorsOnCopyConstruction,
  1372. CountConstructorsDestructorsOnMoveConstruction,
  1373. CountConstructorsDestructorsOnAssignment,
  1374. CountConstructorsDestructorsOnMoveAssignment,
  1375. CountElemAssignInlineBacking, RangedConstructor,
  1376. RangedAssign, InitializerListAssign);
  1377. using InstanceTypes =
  1378. ::testing::Types<CopyableOnlyInstance, CopyableMovableInstance>;
  1379. INSTANTIATE_TYPED_TEST_CASE_P(InstanceTestOnTypes, InstanceTest, InstanceTypes);
  1380. TEST(DynamicVec, DynamicVecCompiles) {
  1381. DynamicVec v;
  1382. (void)v;
  1383. }
  1384. TEST(AllocatorSupportTest, Constructors) {
  1385. using MyAlloc = CountingAllocator<int>;
  1386. using AllocVec = absl::InlinedVector<int, 4, MyAlloc>;
  1387. const int ia[] = {0, 1, 2, 3, 4, 5, 6, 7};
  1388. int64_t allocated = 0;
  1389. MyAlloc alloc(&allocated);
  1390. { AllocVec ABSL_ATTRIBUTE_UNUSED v; }
  1391. { AllocVec ABSL_ATTRIBUTE_UNUSED v(alloc); }
  1392. { AllocVec ABSL_ATTRIBUTE_UNUSED v(ia, ia + ABSL_ARRAYSIZE(ia), alloc); }
  1393. { AllocVec ABSL_ATTRIBUTE_UNUSED v({1, 2, 3}, alloc); }
  1394. AllocVec v2;
  1395. { AllocVec ABSL_ATTRIBUTE_UNUSED v(v2, alloc); }
  1396. { AllocVec ABSL_ATTRIBUTE_UNUSED v(std::move(v2), alloc); }
  1397. }
  1398. TEST(AllocatorSupportTest, CountAllocations) {
  1399. using MyAlloc = CountingAllocator<int>;
  1400. using AllocVec = absl::InlinedVector<int, 4, MyAlloc>;
  1401. const int ia[] = {0, 1, 2, 3, 4, 5, 6, 7};
  1402. int64_t allocated = 0;
  1403. MyAlloc alloc(&allocated);
  1404. {
  1405. AllocVec ABSL_ATTRIBUTE_UNUSED v(ia, ia + 4, alloc);
  1406. EXPECT_THAT(allocated, 0);
  1407. }
  1408. EXPECT_THAT(allocated, 0);
  1409. {
  1410. AllocVec ABSL_ATTRIBUTE_UNUSED v(ia, ia + ABSL_ARRAYSIZE(ia), alloc);
  1411. EXPECT_THAT(allocated, v.size() * sizeof(int));
  1412. }
  1413. EXPECT_THAT(allocated, 0);
  1414. {
  1415. AllocVec v(4, 1, alloc);
  1416. EXPECT_THAT(allocated, 0);
  1417. int64_t allocated2 = 0;
  1418. MyAlloc alloc2(&allocated2);
  1419. AllocVec v2(v, alloc2);
  1420. EXPECT_THAT(allocated2, 0);
  1421. int64_t allocated3 = 0;
  1422. MyAlloc alloc3(&allocated3);
  1423. AllocVec v3(std::move(v), alloc3);
  1424. EXPECT_THAT(allocated3, 0);
  1425. }
  1426. EXPECT_THAT(allocated, 0);
  1427. {
  1428. AllocVec v(8, 2, alloc);
  1429. EXPECT_THAT(allocated, v.size() * sizeof(int));
  1430. int64_t allocated2 = 0;
  1431. MyAlloc alloc2(&allocated2);
  1432. AllocVec v2(v, alloc2);
  1433. EXPECT_THAT(allocated2, v2.size() * sizeof(int));
  1434. int64_t allocated3 = 0;
  1435. MyAlloc alloc3(&allocated3);
  1436. AllocVec v3(std::move(v), alloc3);
  1437. EXPECT_THAT(allocated3, v3.size() * sizeof(int));
  1438. }
  1439. EXPECT_EQ(allocated, 0);
  1440. {
  1441. // Test shrink_to_fit deallocations.
  1442. AllocVec v(8, 2, alloc);
  1443. EXPECT_EQ(allocated, 8 * sizeof(int));
  1444. v.resize(5);
  1445. EXPECT_EQ(allocated, 8 * sizeof(int));
  1446. v.shrink_to_fit();
  1447. EXPECT_EQ(allocated, 5 * sizeof(int));
  1448. v.resize(4);
  1449. EXPECT_EQ(allocated, 5 * sizeof(int));
  1450. v.shrink_to_fit();
  1451. EXPECT_EQ(allocated, 0);
  1452. }
  1453. }
  1454. TEST(AllocatorSupportTest, SwapBothAllocated) {
  1455. using MyAlloc = CountingAllocator<int>;
  1456. using AllocVec = absl::InlinedVector<int, 4, MyAlloc>;
  1457. int64_t allocated1 = 0;
  1458. int64_t allocated2 = 0;
  1459. {
  1460. const int ia1[] = {0, 1, 2, 3, 4, 5, 6, 7};
  1461. const int ia2[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
  1462. MyAlloc a1(&allocated1);
  1463. MyAlloc a2(&allocated2);
  1464. AllocVec v1(ia1, ia1 + ABSL_ARRAYSIZE(ia1), a1);
  1465. AllocVec v2(ia2, ia2 + ABSL_ARRAYSIZE(ia2), a2);
  1466. EXPECT_LT(v1.capacity(), v2.capacity());
  1467. EXPECT_THAT(allocated1, v1.capacity() * sizeof(int));
  1468. EXPECT_THAT(allocated2, v2.capacity() * sizeof(int));
  1469. v1.swap(v2);
  1470. EXPECT_THAT(v1, ElementsAreArray(ia2));
  1471. EXPECT_THAT(v2, ElementsAreArray(ia1));
  1472. EXPECT_THAT(allocated1, v2.capacity() * sizeof(int));
  1473. EXPECT_THAT(allocated2, v1.capacity() * sizeof(int));
  1474. }
  1475. EXPECT_THAT(allocated1, 0);
  1476. EXPECT_THAT(allocated2, 0);
  1477. }
  1478. TEST(AllocatorSupportTest, SwapOneAllocated) {
  1479. using MyAlloc = CountingAllocator<int>;
  1480. using AllocVec = absl::InlinedVector<int, 4, MyAlloc>;
  1481. int64_t allocated1 = 0;
  1482. int64_t allocated2 = 0;
  1483. {
  1484. const int ia1[] = {0, 1, 2, 3, 4, 5, 6, 7};
  1485. const int ia2[] = {0, 1, 2, 3};
  1486. MyAlloc a1(&allocated1);
  1487. MyAlloc a2(&allocated2);
  1488. AllocVec v1(ia1, ia1 + ABSL_ARRAYSIZE(ia1), a1);
  1489. AllocVec v2(ia2, ia2 + ABSL_ARRAYSIZE(ia2), a2);
  1490. EXPECT_THAT(allocated1, v1.capacity() * sizeof(int));
  1491. EXPECT_THAT(allocated2, 0);
  1492. v1.swap(v2);
  1493. EXPECT_THAT(v1, ElementsAreArray(ia2));
  1494. EXPECT_THAT(v2, ElementsAreArray(ia1));
  1495. EXPECT_THAT(allocated1, v2.capacity() * sizeof(int));
  1496. EXPECT_THAT(allocated2, 0);
  1497. EXPECT_TRUE(v2.get_allocator() == a1);
  1498. EXPECT_TRUE(v1.get_allocator() == a2);
  1499. }
  1500. EXPECT_THAT(allocated1, 0);
  1501. EXPECT_THAT(allocated2, 0);
  1502. }
  1503. TEST(AllocatorSupportTest, ScopedAllocatorWorksInlined) {
  1504. using StdVector = std::vector<int, CountingAllocator<int>>;
  1505. using Alloc = CountingAllocator<StdVector>;
  1506. using ScopedAlloc = std::scoped_allocator_adaptor<Alloc>;
  1507. using AllocVec = absl::InlinedVector<StdVector, 1, ScopedAlloc>;
  1508. int64_t total_allocated_byte_count = 0;
  1509. AllocVec inlined_case(ScopedAlloc(Alloc(+&total_allocated_byte_count)));
  1510. // Called only once to remain inlined
  1511. inlined_case.emplace_back();
  1512. int64_t absl_responsible_for_count = total_allocated_byte_count;
  1513. // MSVC's allocator preemptively allocates in debug mode
  1514. #if !defined(_MSC_VER)
  1515. EXPECT_EQ(absl_responsible_for_count, 0);
  1516. #endif // !defined(_MSC_VER)
  1517. inlined_case[0].emplace_back();
  1518. EXPECT_GT(total_allocated_byte_count, absl_responsible_for_count);
  1519. inlined_case.clear();
  1520. inlined_case.shrink_to_fit();
  1521. EXPECT_EQ(total_allocated_byte_count, 0);
  1522. }
  1523. TEST(AllocatorSupportTest, ScopedAllocatorWorksAllocated) {
  1524. using StdVector = std::vector<int, CountingAllocator<int>>;
  1525. using Alloc = CountingAllocator<StdVector>;
  1526. using ScopedAlloc = std::scoped_allocator_adaptor<Alloc>;
  1527. using AllocVec = absl::InlinedVector<StdVector, 1, ScopedAlloc>;
  1528. int64_t total_allocated_byte_count = 0;
  1529. AllocVec allocated_case(ScopedAlloc(Alloc(+&total_allocated_byte_count)));
  1530. // Called twice to force into being allocated
  1531. allocated_case.emplace_back();
  1532. allocated_case.emplace_back();
  1533. int64_t absl_responsible_for_count = total_allocated_byte_count;
  1534. EXPECT_GT(absl_responsible_for_count, 0);
  1535. allocated_case[1].emplace_back();
  1536. EXPECT_GT(total_allocated_byte_count, absl_responsible_for_count);
  1537. allocated_case.clear();
  1538. allocated_case.shrink_to_fit();
  1539. EXPECT_EQ(total_allocated_byte_count, 0);
  1540. }
  1541. TEST(AllocatorSupportTest, SizeAllocConstructor) {
  1542. constexpr int inlined_size = 4;
  1543. using Alloc = CountingAllocator<int>;
  1544. using AllocVec = absl::InlinedVector<int, inlined_size, Alloc>;
  1545. {
  1546. auto len = inlined_size / 2;
  1547. int64_t allocated = 0;
  1548. auto v = AllocVec(len, Alloc(&allocated));
  1549. // Inline storage used; allocator should not be invoked
  1550. EXPECT_THAT(allocated, 0);
  1551. EXPECT_THAT(v, AllOf(SizeIs(len), Each(0)));
  1552. }
  1553. {
  1554. auto len = inlined_size * 2;
  1555. int64_t allocated = 0;
  1556. auto v = AllocVec(len, Alloc(&allocated));
  1557. // Out of line storage used; allocation of 8 elements expected
  1558. EXPECT_THAT(allocated, len * sizeof(int));
  1559. EXPECT_THAT(v, AllOf(SizeIs(len), Each(0)));
  1560. }
  1561. }
  1562. TEST(InlinedVectorTest, MinimumAllocatorCompilesUsingTraits) {
  1563. using T = int;
  1564. using A = std::allocator<T>;
  1565. using ATraits = absl::allocator_traits<A>;
  1566. struct MinimumAllocator {
  1567. using value_type = T;
  1568. value_type* allocate(size_t n) {
  1569. A a;
  1570. return ATraits::allocate(a, n);
  1571. }
  1572. void deallocate(value_type* p, size_t n) {
  1573. A a;
  1574. ATraits::deallocate(a, p, n);
  1575. }
  1576. };
  1577. absl::InlinedVector<T, 1, MinimumAllocator> vec;
  1578. vec.emplace_back();
  1579. vec.resize(0);
  1580. }
  1581. TEST(InlinedVectorTest, AbslHashValueWorks) {
  1582. using V = absl::InlinedVector<int, 4>;
  1583. std::vector<V> cases;
  1584. // Generate a variety of vectors some of these are small enough for the inline
  1585. // space but are stored out of line.
  1586. for (int i = 0; i < 10; ++i) {
  1587. V v;
  1588. for (int j = 0; j < i; ++j) {
  1589. v.push_back(j);
  1590. }
  1591. cases.push_back(v);
  1592. v.resize(i % 4);
  1593. cases.push_back(v);
  1594. }
  1595. EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(cases));
  1596. }
  1597. } // anonymous namespace