poly_defined.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  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 = as_ref(in_place);
  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. }
  88. TEST(PolyDefined, Owned) {
  89. entt::poly<Defined> poly{impl{}};
  90. auto *ptr = static_cast<impl *>(poly.data());
  91. ASSERT_TRUE(poly);
  92. ASSERT_NE(poly.data(), nullptr);
  93. ASSERT_NE(std::as_const(poly).data(), nullptr);
  94. ASSERT_EQ(ptr->value, 0);
  95. ASSERT_EQ(poly->get(), 0);
  96. poly->set(1);
  97. poly->incr();
  98. ASSERT_EQ(ptr->value, 2);
  99. ASSERT_EQ(poly->get(), 2);
  100. ASSERT_EQ(poly->mul(3), 6);
  101. poly->decr();
  102. ASSERT_EQ(ptr->value, 1);
  103. ASSERT_EQ(poly->get(), 1);
  104. ASSERT_EQ(poly->mul(3), 3);
  105. }
  106. TEST(PolyDefined, Reference) {
  107. impl instance{};
  108. entt::poly<Defined> poly{std::ref(instance)};
  109. ASSERT_TRUE(poly);
  110. ASSERT_NE(poly.data(), nullptr);
  111. ASSERT_NE(std::as_const(poly).data(), nullptr);
  112. ASSERT_EQ(instance.value, 0);
  113. ASSERT_EQ(poly->get(), 0);
  114. poly->set(1);
  115. poly->incr();
  116. ASSERT_EQ(instance.value, 2);
  117. ASSERT_EQ(poly->get(), 2);
  118. ASSERT_EQ(poly->mul(3), 6);
  119. poly->decr();
  120. ASSERT_EQ(instance.value, 1);
  121. ASSERT_EQ(poly->get(), 1);
  122. ASSERT_EQ(poly->mul(3), 3);
  123. }
  124. TEST(PolyDefined, ConstReference) {
  125. impl instance{};
  126. entt::poly<Defined> poly{std::cref(instance)};
  127. ASSERT_TRUE(poly);
  128. ASSERT_EQ(poly.data(), nullptr);
  129. ASSERT_NE(std::as_const(poly).data(), nullptr);
  130. ASSERT_EQ(instance.value, 0);
  131. ASSERT_EQ(poly->get(), 0);
  132. ASSERT_DEATH(poly->set(1), ".*");
  133. ASSERT_DEATH(poly->incr(), ".*");
  134. ASSERT_EQ(instance.value, 0);
  135. ASSERT_EQ(poly->get(), 0);
  136. ASSERT_EQ(poly->mul(3), 0);
  137. ASSERT_DEATH(poly->decr(), ".*");
  138. ASSERT_EQ(instance.value, 0);
  139. ASSERT_EQ(poly->get(), 0);
  140. ASSERT_EQ(poly->mul(3), 0);
  141. }
  142. TEST(PolyDefined, AsRef) {
  143. entt::poly<Defined> poly{impl{}};
  144. auto ref = as_ref(poly);
  145. auto cref = as_ref(std::as_const(poly));
  146. ASSERT_NE(poly.data(), nullptr);
  147. ASSERT_NE(ref.data(), nullptr);
  148. ASSERT_EQ(cref.data(), nullptr);
  149. ASSERT_NE(std::as_const(cref).data(), nullptr);
  150. std::swap(ref, cref);
  151. ASSERT_EQ(ref.data(), nullptr);
  152. ASSERT_NE(std::as_const(ref).data(), nullptr);
  153. ASSERT_NE(cref.data(), nullptr);
  154. ref = as_ref(ref);
  155. cref = as_ref(std::as_const(cref));
  156. ASSERT_EQ(ref.data(), nullptr);
  157. ASSERT_NE(std::as_const(ref).data(), nullptr);
  158. ASSERT_EQ(cref.data(), nullptr);
  159. ASSERT_NE(std::as_const(cref).data(), nullptr);
  160. ref = impl{};
  161. cref = impl{};
  162. ASSERT_NE(ref.data(), nullptr);
  163. ASSERT_NE(cref.data(), nullptr);
  164. }