erased_storage_ut.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #include <library/cpp/testing/gtest/gtest.h>
  2. #include <library/cpp/yt/memory/erased_storage.h>
  3. #include <library/cpp/int128/int128.h>
  4. #include <library/cpp/yt/misc/guid.h>
  5. #include <util/generic/string.h>
  6. #include <util/system/types.h>
  7. #include <vector>
  8. namespace NYT {
  9. namespace {
  10. ////////////////////////////////////////////////////////////////////////////////
  11. struct TWithFieldInitalizer
  12. {
  13. // NB: This class is not trivially default constructible.
  14. int Field{};
  15. };
  16. static_assert(!std::is_trivially_default_constructible_v<TWithFieldInitalizer>);
  17. struct TCopyWithSideEffects
  18. {
  19. TCopyWithSideEffects(const TCopyWithSideEffects&)
  20. { }
  21. };
  22. static_assert(!std::is_trivially_copy_constructible_v<TCopyWithSideEffects>);
  23. struct TWithSubStruct
  24. {
  25. TWithFieldInitalizer Field;
  26. };
  27. class TWithPrivateMembers
  28. {
  29. public:
  30. TWithPrivateMembers() = default;
  31. private:
  32. [[maybe_unused]] std::array<std::byte, 8> Data_;
  33. };
  34. // Overshadow to bind template parameter.
  35. inline constexpr size_t TestSize = 32;
  36. template <class T>
  37. concept CTriviallyErasable = ::NYT::CTriviallyErasable<T, TestSize>;
  38. using TErasedStorage = ::NYT::TErasedStorage<TestSize>;
  39. ////////////////////////////////////////////////////////////////////////////////
  40. TEST(TErasedStorageTest, Types)
  41. {
  42. static_assert(CTriviallyErasable<int>);
  43. static_assert(CTriviallyErasable<i32>);
  44. static_assert(CTriviallyErasable<i64>);
  45. static_assert(CTriviallyErasable<i128>);
  46. static_assert(CTriviallyErasable<std::array<i128, 2>>);
  47. static_assert(CTriviallyErasable<TGuid>);
  48. static_assert(CTriviallyErasable<void*>);
  49. static_assert(CTriviallyErasable<double>);
  50. static_assert(CTriviallyErasable<const char*>);
  51. static_assert(CTriviallyErasable<TWithFieldInitalizer>);
  52. static_assert(CTriviallyErasable<TWithSubStruct>);
  53. static_assert(CTriviallyErasable<TWithPrivateMembers>);
  54. static_assert(CTriviallyErasable<char[8]>);
  55. static_assert(!CTriviallyErasable<TString>);
  56. static_assert(!CTriviallyErasable<std::vector<int>>);
  57. static_assert(!CTriviallyErasable<std::array<i128, 3>>);
  58. static_assert(!CTriviallyErasable<int&>);
  59. static_assert(!CTriviallyErasable<const int&>);
  60. static_assert(!CTriviallyErasable<int&&>);
  61. static_assert(!CTriviallyErasable<TCopyWithSideEffects>);
  62. }
  63. TEST(TErasedStorageTest, JustWorks)
  64. {
  65. int var = 42;
  66. TErasedStorage stor(var);
  67. EXPECT_EQ(stor.AsConcrete<int>(), 42);
  68. var = 66;
  69. EXPECT_EQ(stor.AsConcrete<int>(), 42);
  70. }
  71. TEST(TErasedStorageTest, CopyAssign)
  72. {
  73. int var = 42;
  74. TErasedStorage stor(var);
  75. EXPECT_EQ(stor.AsConcrete<int>(), 42);
  76. {
  77. int anotherVar = 77;
  78. stor = TErasedStorage(anotherVar);
  79. }
  80. EXPECT_EQ(stor.AsConcrete<int>(), 77);
  81. double thirdVar = 9.92145214;
  82. stor = TErasedStorage(thirdVar);
  83. EXPECT_DOUBLE_EQ(stor.AsConcrete<double>(), 9.92145214);
  84. }
  85. TEST(TErasedStorageTest, Pointer)
  86. {
  87. TString message("Hello world");
  88. TErasedStorage stor(&message);
  89. EXPECT_EQ(*stor.AsConcrete<TString*>(), TString("Hello world"));
  90. message = "Goodbye world";
  91. EXPECT_EQ(*stor.AsConcrete<TString*>(), "Goodbye world");
  92. }
  93. TEST(TErasedStorageTest, MutateStorage)
  94. {
  95. int var = 0;
  96. TErasedStorage stor(var);
  97. EXPECT_EQ(stor.AsConcrete<int>(), 0);
  98. auto& ref = stor.AsConcrete<int>();
  99. ref = 88;
  100. EXPECT_EQ(stor.AsConcrete<int>(), 88);
  101. }
  102. TEST(TErasedStorageTest, EqualityComparison)
  103. {
  104. struct TWidget
  105. {
  106. alignas(8) int Value;
  107. alignas(16) bool Flag;
  108. } widget{1, false};
  109. TErasedStorage stor1(widget);
  110. TErasedStorage stor2(widget);
  111. EXPECT_EQ(stor1, stor2);
  112. }
  113. ////////////////////////////////////////////////////////////////////////////////
  114. } // namespace
  115. } // namespace NYT