stack_vec_ut.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #include "stack_vec.h"
  2. #include <library/cpp/testing/unittest/registar.h>
  3. namespace {
  4. struct TNotCopyAssignable {
  5. const int Value;
  6. };
  7. static_assert(std::is_copy_constructible_v<TNotCopyAssignable>);
  8. static_assert(!std::is_copy_assignable_v<TNotCopyAssignable>);
  9. template <class T, size_t JunkPayloadSize>
  10. struct TThickAlloc: public std::allocator<T> {
  11. template <class U>
  12. struct rebind {
  13. using other = TThickAlloc<U, JunkPayloadSize>;
  14. };
  15. char Junk[JunkPayloadSize]{sizeof(T)};
  16. };
  17. template <class T>
  18. struct TStatefulAlloc: public std::allocator<T> {
  19. using TBase = std::allocator<T>;
  20. template <class U>
  21. struct rebind {
  22. using other = TStatefulAlloc<U>;
  23. };
  24. TStatefulAlloc(size_t* allocCount)
  25. : AllocCount(allocCount)
  26. {}
  27. size_t* AllocCount;
  28. T* allocate(size_t n)
  29. {
  30. *AllocCount += 1;
  31. return TBase::allocate(n);
  32. }
  33. };
  34. }
  35. Y_UNIT_TEST_SUITE(TStackBasedVectorTest) {
  36. Y_UNIT_TEST(TestCreateEmpty) {
  37. TStackVec<int> ints;
  38. UNIT_ASSERT_EQUAL(ints.size(), 0);
  39. }
  40. Y_UNIT_TEST(TestCreateNonEmpty) {
  41. TStackVec<int> ints(5);
  42. UNIT_ASSERT_EQUAL(ints.size(), 5);
  43. for (size_t i = 0; i < ints.size(); ++i) {
  44. UNIT_ASSERT_EQUAL(ints[i], 0);
  45. }
  46. }
  47. Y_UNIT_TEST(TestReallyOnStack) {
  48. const TStackVec<int> vec(5);
  49. UNIT_ASSERT(
  50. (const char*)&vec <= (const char*)&vec[0] &&
  51. (const char*)&vec[0] <= (const char*)&vec + sizeof(vec)
  52. );
  53. }
  54. Y_UNIT_TEST(TestFallback) {
  55. TSmallVec<int> ints;
  56. for (int i = 0; i < 14; ++i) {
  57. ints.push_back(i);
  58. }
  59. for (size_t i = 0; i < ints.size(); ++i) {
  60. UNIT_ASSERT_EQUAL(ints[i], (int)i);
  61. }
  62. for (int i = 14; i < 20; ++i) {
  63. ints.push_back(i);
  64. }
  65. for (size_t i = 0; i < ints.size(); ++i) {
  66. UNIT_ASSERT_EQUAL(ints[i], (int)i);
  67. }
  68. TSmallVec<int> ints2 = ints;
  69. for (size_t i = 0; i < ints2.size(); ++i) {
  70. UNIT_ASSERT_EQUAL(ints2[i], (int)i);
  71. }
  72. TSmallVec<int> ints3;
  73. ints3 = ints2;
  74. for (size_t i = 0; i < ints3.size(); ++i) {
  75. UNIT_ASSERT_EQUAL(ints3[i], (int)i);
  76. }
  77. }
  78. Y_UNIT_TEST(TestCappedSize) {
  79. TStackVec<int, 8, false> ints;
  80. ints.push_back(1);
  81. ints.push_back(2);
  82. auto intsCopy = ints;
  83. UNIT_ASSERT_VALUES_EQUAL(intsCopy.capacity(), 8);
  84. for (int i = 2; i != 8; ++i) {
  85. intsCopy.push_back(i);
  86. }
  87. // Just verify that the program did not crash.
  88. }
  89. Y_UNIT_TEST(TestCappedSizeWithNotCopyAssignable) {
  90. TStackVec<TNotCopyAssignable, 8, false> values;
  91. values.push_back({1});
  92. values.push_back({2});
  93. auto valuesCopy = values;
  94. UNIT_ASSERT_VALUES_EQUAL(valuesCopy.capacity(), 8);
  95. for (int i = 2; i != 8; ++i) {
  96. valuesCopy.push_back({i});
  97. }
  98. // Just verify that the program did not crash.
  99. }
  100. Y_UNIT_TEST(TestCustomAllocSize) {
  101. constexpr size_t n = 16384;
  102. using TVec = TStackVec<size_t, 1, true, TThickAlloc<size_t, n>>;
  103. UNIT_ASSERT_LT(sizeof(TVec), 1.5 * n);
  104. }
  105. Y_UNIT_TEST(TestStatefulAlloc) {
  106. size_t count = 0;
  107. TStackVec<size_t, 1, true, TStatefulAlloc<size_t>> vec{{ &count }};
  108. for (size_t i = 0; i < 5; ++i) {
  109. vec.push_back(1);
  110. }
  111. UNIT_ASSERT_VALUES_EQUAL(count, 3);
  112. }
  113. }