compressed_pair.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. #include <tuple>
  2. #include <type_traits>
  3. #include <utility>
  4. #include <gtest/gtest.h>
  5. #include <entt/core/compressed_pair.hpp>
  6. struct empty_type {};
  7. struct move_only_type {
  8. move_only_type()
  9. : value{new int{99}} {}
  10. move_only_type(int v)
  11. : value{new int{v}} {}
  12. ~move_only_type() {
  13. delete value;
  14. }
  15. move_only_type(const move_only_type &) = delete;
  16. move_only_type &operator=(const move_only_type &) = delete;
  17. move_only_type(move_only_type &&other) ENTT_NOEXCEPT
  18. : value{std::exchange(other.value, nullptr)} {}
  19. move_only_type &operator=(move_only_type &&other) ENTT_NOEXCEPT {
  20. delete value;
  21. value = std::exchange(other.value, nullptr);
  22. return *this;
  23. }
  24. int *value;
  25. };
  26. struct non_default_constructible {
  27. non_default_constructible(int v)
  28. : value{v} {}
  29. int value;
  30. };
  31. TEST(CompressedPair, Size) {
  32. struct local {
  33. int value;
  34. empty_type empty;
  35. };
  36. static_assert(sizeof(entt::compressed_pair<int, int>) == sizeof(int[2u]));
  37. static_assert(sizeof(entt::compressed_pair<empty_type, int>) == sizeof(int));
  38. static_assert(sizeof(entt::compressed_pair<int, empty_type>) == sizeof(int));
  39. static_assert(sizeof(entt::compressed_pair<int, empty_type>) < sizeof(local));
  40. static_assert(sizeof(entt::compressed_pair<int, empty_type>) < sizeof(std::pair<int, empty_type>));
  41. }
  42. TEST(CompressedPair, ConstructCopyMove) {
  43. static_assert(!std::is_default_constructible_v<entt::compressed_pair<non_default_constructible, empty_type>>);
  44. static_assert(std::is_default_constructible_v<entt::compressed_pair<move_only_type, empty_type>>);
  45. static_assert(std::is_copy_constructible_v<entt::compressed_pair<non_default_constructible, empty_type>>);
  46. static_assert(!std::is_copy_constructible_v<entt::compressed_pair<move_only_type, empty_type>>);
  47. static_assert(std::is_copy_assignable_v<entt::compressed_pair<non_default_constructible, empty_type>>);
  48. static_assert(!std::is_copy_assignable_v<entt::compressed_pair<move_only_type, empty_type>>);
  49. static_assert(std::is_move_constructible_v<entt::compressed_pair<move_only_type, empty_type>>);
  50. static_assert(std::is_move_assignable_v<entt::compressed_pair<move_only_type, empty_type>>);
  51. entt::compressed_pair copyable{non_default_constructible{42}, empty_type{}};
  52. auto by_copy{copyable};
  53. ASSERT_EQ(by_copy.first().value, 42);
  54. by_copy.first().value = 3;
  55. copyable = by_copy;
  56. ASSERT_EQ(copyable.first().value, 3);
  57. entt::compressed_pair<empty_type, move_only_type> movable{};
  58. auto by_move{std::move(movable)};
  59. ASSERT_EQ(*by_move.second().value, 99);
  60. ASSERT_EQ(movable.second().value, nullptr);
  61. *by_move.second().value = 3;
  62. movable = std::move(by_move);
  63. ASSERT_EQ(*movable.second().value, 3);
  64. ASSERT_EQ(by_move.second().value, nullptr);
  65. }
  66. TEST(CompressedPair, PiecewiseConstruct) {
  67. entt::compressed_pair<empty_type, int> pair{std::piecewise_construct, std::make_tuple(), std::make_tuple(3)};
  68. ASSERT_EQ(pair.second(), 3);
  69. }
  70. TEST(CompressedPair, DeductionGuide) {
  71. int value = 42;
  72. empty_type empty{};
  73. entt::compressed_pair pair{value, 3};
  74. static_assert(std::is_same_v<decltype(entt::compressed_pair{empty_type{}, empty}), entt::compressed_pair<empty_type, empty_type>>);
  75. ASSERT_TRUE((std::is_same_v<decltype(pair), entt::compressed_pair<int, int>>));
  76. ASSERT_EQ(pair.first(), 42);
  77. ASSERT_EQ(pair.second(), 3);
  78. }
  79. TEST(CompressedPair, Getters) {
  80. entt::compressed_pair pair{3, empty_type{}};
  81. const auto &cpair = pair;
  82. static_assert(std::is_same_v<decltype(pair.first()), int &>);
  83. static_assert(std::is_same_v<decltype(pair.second()), empty_type &>);
  84. static_assert(std::is_same_v<decltype(cpair.first()), const int &>);
  85. static_assert(std::is_same_v<decltype(cpair.second()), const empty_type &>);
  86. ASSERT_EQ(pair.first(), cpair.first());
  87. ASSERT_EQ(&pair.second(), &cpair.second());
  88. }
  89. TEST(CompressedPair, Swap) {
  90. entt::compressed_pair pair{1, 2};
  91. entt::compressed_pair other{3, 4};
  92. swap(pair, other);
  93. ASSERT_EQ(pair.first(), 3);
  94. ASSERT_EQ(pair.second(), 4);
  95. ASSERT_EQ(other.first(), 1);
  96. ASSERT_EQ(other.second(), 2);
  97. pair.swap(other);
  98. ASSERT_EQ(pair.first(), 1);
  99. ASSERT_EQ(pair.second(), 2);
  100. ASSERT_EQ(other.first(), 3);
  101. ASSERT_EQ(other.second(), 4);
  102. }
  103. TEST(CompressedPair, Get) {
  104. entt::compressed_pair pair{1, 2};
  105. ASSERT_EQ(pair.get<0>(), 1);
  106. ASSERT_EQ(pair.get<1>(), 2);
  107. ASSERT_EQ(&pair.get<0>(), &pair.first());
  108. ASSERT_EQ(&pair.get<1>(), &pair.second());
  109. auto &&[first, second] = pair;
  110. ASSERT_EQ(first, 1);
  111. ASSERT_EQ(second, 2);
  112. first = 3;
  113. second = 4;
  114. ASSERT_EQ(pair.first(), 3);
  115. ASSERT_EQ(pair.second(), 4);
  116. auto &[cfirst, csecond] = std::as_const(pair);
  117. ASSERT_EQ(cfirst, 3);
  118. ASSERT_EQ(csecond, 4);
  119. static_assert(std::is_same_v<decltype(cfirst), const int>);
  120. static_assert(std::is_same_v<decltype(csecond), const int>);
  121. auto [tfirst, tsecond] = entt::compressed_pair{9, 99};
  122. ASSERT_EQ(tfirst, 9);
  123. ASSERT_EQ(tsecond, 99);
  124. static_assert(std::is_same_v<decltype(cfirst), const int>);
  125. static_assert(std::is_same_v<decltype(csecond), const int>);
  126. }