poly_defined.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. #include <functional>
  2. #include <type_traits>
  3. #include <gtest/gtest.h>
  4. #include <entt/core/type_traits.hpp>
  5. #include <entt/poly/poly.hpp>
  6. struct Defined: entt::type_list<
  7. void(),
  8. void(int),
  9. int() const,
  10. void(),
  11. int(int) const
  12. > {
  13. template<typename Base>
  14. struct type: Base {
  15. void incr() { entt::poly_call<0>(*this); }
  16. void set(int v) { entt::poly_call<1>(*this, v); }
  17. int get() const { return entt::poly_call<2>(*this); }
  18. void decr() { entt::poly_call<3>(*this); }
  19. int mul(int v) const { return entt::poly_call<4>(*this, v); }
  20. };
  21. template<typename Type>
  22. struct members {
  23. static void decr(Type &self) { self.decrement(); }
  24. static double mul(const Type &self, double v) { return self.multiply(v); }
  25. };
  26. template<typename Type>
  27. using impl = entt::value_list<
  28. &Type::incr,
  29. &Type::set,
  30. &Type::get,
  31. &members<Type>::decr,
  32. &members<Type>::mul
  33. >;
  34. };
  35. struct impl {
  36. impl() = default;
  37. impl(int v): value{v} {}
  38. void incr() { ++value; }
  39. void set(int v) { value = v; }
  40. int get() const { return value; }
  41. void decrement() { --value; }
  42. double multiply(double v) const { return v * value; }
  43. int value{};
  44. };
  45. TEST(PolyDefined, Functionalities) {
  46. impl instance{};
  47. entt::poly<Defined> empty{};
  48. entt::poly<Defined> in_place{std::in_place_type<impl>, 3};
  49. entt::poly<Defined> alias{std::ref(instance)};
  50. entt::poly<Defined> value{impl{}};
  51. ASSERT_FALSE(empty);
  52. ASSERT_TRUE(in_place);
  53. ASSERT_TRUE(alias);
  54. ASSERT_TRUE(value);
  55. ASSERT_EQ(empty.type(), entt::type_info{});
  56. ASSERT_EQ(in_place.type(), entt::type_id<impl>());
  57. ASSERT_EQ(alias.type(), entt::type_id<impl>());
  58. ASSERT_EQ(value.type(), entt::type_id<impl>());
  59. ASSERT_EQ(alias.data(), &instance);
  60. ASSERT_EQ(std::as_const(alias).data(), &instance);
  61. empty = impl{};
  62. ASSERT_TRUE(empty);
  63. ASSERT_NE(empty.data(), nullptr);
  64. ASSERT_NE(std::as_const(empty).data(), nullptr);
  65. ASSERT_EQ(empty.type(), entt::type_id<impl>());
  66. ASSERT_EQ(empty->get(), 0);
  67. empty.template emplace<impl>(3);
  68. ASSERT_TRUE(empty);
  69. ASSERT_EQ(empty->get(), 3);
  70. entt::poly<Defined> ref = in_place.as_ref();
  71. ASSERT_TRUE(ref);
  72. ASSERT_NE(ref.data(), nullptr);
  73. ASSERT_EQ(ref.data(), in_place.data());
  74. ASSERT_EQ(std::as_const(ref).data(), std::as_const(in_place).data());
  75. ASSERT_EQ(ref.type(), entt::type_id<impl>());
  76. ASSERT_EQ(ref->get(), 3);
  77. entt::poly<Defined> null{};
  78. std::swap(empty, null);
  79. ASSERT_FALSE(empty);
  80. entt::poly<Defined> copy = in_place;
  81. ASSERT_TRUE(copy);
  82. ASSERT_EQ(copy->get(), 3);
  83. entt::poly<Defined> move = std::move(copy);
  84. ASSERT_TRUE(move);
  85. ASSERT_FALSE(copy);
  86. ASSERT_EQ(move->get(), 3);
  87. move.reset();
  88. ASSERT_FALSE(move);
  89. ASSERT_EQ(move.type(), entt::type_info{});
  90. }
  91. TEST(PolyDefined, Owned) {
  92. entt::poly<Defined> poly{impl{}};
  93. auto *ptr = static_cast<impl *>(poly.data());
  94. ASSERT_TRUE(poly);
  95. ASSERT_NE(poly.data(), nullptr);
  96. ASSERT_NE(std::as_const(poly).data(), nullptr);
  97. ASSERT_EQ(ptr->value, 0);
  98. ASSERT_EQ(poly->get(), 0);
  99. poly->set(1);
  100. poly->incr();
  101. ASSERT_EQ(ptr->value, 2);
  102. ASSERT_EQ(poly->get(), 2);
  103. ASSERT_EQ(poly->mul(3), 6);
  104. poly->decr();
  105. ASSERT_EQ(ptr->value, 1);
  106. ASSERT_EQ(poly->get(), 1);
  107. ASSERT_EQ(poly->mul(3), 3);
  108. }
  109. TEST(PolyDefined, Reference) {
  110. impl instance{};
  111. entt::poly<Defined> poly{std::ref(instance)};
  112. ASSERT_TRUE(poly);
  113. ASSERT_NE(poly.data(), nullptr);
  114. ASSERT_NE(std::as_const(poly).data(), nullptr);
  115. ASSERT_EQ(instance.value, 0);
  116. ASSERT_EQ(poly->get(), 0);
  117. poly->set(1);
  118. poly->incr();
  119. ASSERT_EQ(instance.value, 2);
  120. ASSERT_EQ(poly->get(), 2);
  121. ASSERT_EQ(poly->mul(3), 6);
  122. poly->decr();
  123. ASSERT_EQ(instance.value, 1);
  124. ASSERT_EQ(poly->get(), 1);
  125. ASSERT_EQ(poly->mul(3), 3);
  126. }
  127. TEST(PolyDefined, ConstReference) {
  128. impl instance{};
  129. entt::poly<Defined> poly{std::cref(instance)};
  130. ASSERT_TRUE(poly);
  131. ASSERT_EQ(poly.data(), nullptr);
  132. ASSERT_NE(std::as_const(poly).data(), nullptr);
  133. ASSERT_EQ(instance.value, 0);
  134. ASSERT_EQ(poly->get(), 0);
  135. ASSERT_DEATH(poly->set(1), ".*");
  136. ASSERT_DEATH(poly->incr(), ".*");
  137. ASSERT_EQ(instance.value, 0);
  138. ASSERT_EQ(poly->get(), 0);
  139. ASSERT_EQ(poly->mul(3), 0);
  140. ASSERT_DEATH(poly->decr(), ".*");
  141. ASSERT_EQ(instance.value, 0);
  142. ASSERT_EQ(poly->get(), 0);
  143. ASSERT_EQ(poly->mul(3), 0);
  144. }
  145. TEST(PolyDefined, AsRef) {
  146. entt::poly<Defined> poly{impl{}};
  147. auto ref = poly.as_ref();
  148. auto cref = std::as_const(poly).as_ref();
  149. ASSERT_NE(poly.data(), nullptr);
  150. ASSERT_NE(ref.data(), nullptr);
  151. ASSERT_EQ(cref.data(), nullptr);
  152. ASSERT_NE(std::as_const(cref).data(), nullptr);
  153. std::swap(ref, cref);
  154. ASSERT_EQ(ref.data(), nullptr);
  155. ASSERT_NE(std::as_const(ref).data(), nullptr);
  156. ASSERT_NE(cref.data(), nullptr);
  157. ref = ref.as_ref();
  158. cref = std::as_const(cref).as_ref();
  159. ASSERT_EQ(ref.data(), nullptr);
  160. ASSERT_NE(std::as_const(ref).data(), nullptr);
  161. ASSERT_EQ(cref.data(), nullptr);
  162. ASSERT_NE(std::as_const(cref).data(), nullptr);
  163. ref = impl{};
  164. cref = impl{};
  165. ASSERT_NE(ref.data(), nullptr);
  166. ASSERT_NE(cref.data(), nullptr);
  167. }