resource.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. #include <memory>
  2. #include <utility>
  3. #include <gtest/gtest.h>
  4. #include <entt/core/type_info.hpp>
  5. #include <entt/resource/resource.hpp>
  6. #include "../../common/linter.hpp"
  7. struct base {
  8. virtual ~base() noexcept = default;
  9. [[nodiscard]] virtual const entt::type_info &type() const noexcept {
  10. return entt::type_id<base>();
  11. }
  12. };
  13. struct derived: base {
  14. [[nodiscard]] const entt::type_info &type() const noexcept override {
  15. return entt::type_id<derived>();
  16. }
  17. };
  18. template<typename Type, typename Other>
  19. entt::resource<Type> dynamic_resource_cast(const entt::resource<Other> &other) {
  20. if(other->type() == entt::type_id<Type>()) {
  21. return entt::resource<Type>{other, static_cast<Type &>(*other)};
  22. }
  23. return {};
  24. }
  25. TEST(Resource, Functionalities) {
  26. const entt::resource<derived> resource{};
  27. ASSERT_FALSE(resource);
  28. ASSERT_EQ(resource.operator->(), nullptr);
  29. ASSERT_EQ(resource.handle().use_count(), 0l);
  30. const auto value = std::make_shared<derived>();
  31. entt::resource<derived> other{value};
  32. ASSERT_TRUE(other);
  33. ASSERT_EQ(other.operator->(), value.get());
  34. ASSERT_EQ(&static_cast<derived &>(other), value.get());
  35. ASSERT_EQ(&*other, value.get());
  36. ASSERT_EQ(other.handle().use_count(), 2l);
  37. entt::resource<derived> copy{resource};
  38. entt::resource<derived> move{std::move(other)};
  39. ASSERT_FALSE(copy);
  40. ASSERT_TRUE(move);
  41. copy = std::move(move);
  42. move = copy;
  43. ASSERT_TRUE(copy);
  44. ASSERT_TRUE(move);
  45. ASSERT_EQ(copy, move);
  46. copy.reset(std::make_shared<derived>());
  47. ASSERT_TRUE(copy);
  48. ASSERT_TRUE(move);
  49. ASSERT_NE(copy, move);
  50. move.reset();
  51. ASSERT_TRUE(copy);
  52. ASSERT_FALSE(move);
  53. ASSERT_NE(copy, move);
  54. }
  55. TEST(Resource, Swap) {
  56. entt::resource<int> resource{};
  57. entt::resource<int> other{};
  58. ASSERT_FALSE(resource);
  59. ASSERT_FALSE(other);
  60. resource.swap(other);
  61. ASSERT_FALSE(resource);
  62. ASSERT_FALSE(other);
  63. resource.reset(std::make_shared<int>(1));
  64. ASSERT_TRUE(resource);
  65. ASSERT_EQ(*resource, 1);
  66. ASSERT_FALSE(other);
  67. resource.swap(other);
  68. ASSERT_FALSE(resource);
  69. ASSERT_TRUE(other);
  70. ASSERT_EQ(*other, 1);
  71. }
  72. TEST(Resource, DerivedToBase) {
  73. const entt::resource<derived> resource{std::make_shared<derived>()};
  74. entt::resource<base> other{resource};
  75. entt::resource<const base> cother{resource};
  76. ASSERT_TRUE(resource);
  77. ASSERT_TRUE(other);
  78. ASSERT_TRUE(cother);
  79. ASSERT_EQ(resource, other);
  80. ASSERT_EQ(other, cother);
  81. other = resource;
  82. cother = resource;
  83. ASSERT_EQ(resource, other);
  84. ASSERT_EQ(other, cother);
  85. }
  86. TEST(Resource, ConstNonConstAndAllInBetween) {
  87. entt::resource<derived> resource{std::make_shared<derived>()};
  88. entt::resource<derived> other{resource};
  89. testing::StaticAssertTypeEq<decltype(*resource), derived &>();
  90. testing::StaticAssertTypeEq<decltype(*entt::resource<const derived>{other}), const derived &>();
  91. testing::StaticAssertTypeEq<decltype(*std::as_const(resource)), derived &>();
  92. entt::resource<const derived> copy{resource};
  93. entt::resource<const derived> move{std::move(other)};
  94. test::is_initialized(other);
  95. ASSERT_TRUE(resource);
  96. ASSERT_FALSE(other);
  97. ASSERT_TRUE(copy);
  98. ASSERT_EQ(copy, resource);
  99. ASSERT_NE(copy, entt::resource<derived>{});
  100. ASSERT_EQ(copy.handle().use_count(), 3);
  101. ASSERT_TRUE(move);
  102. ASSERT_EQ(move, resource);
  103. ASSERT_NE(move, entt::resource<derived>{});
  104. ASSERT_EQ(move.handle().use_count(), 3);
  105. copy = resource;
  106. move = std::move(resource);
  107. test::is_initialized(resource);
  108. ASSERT_FALSE(resource);
  109. ASSERT_FALSE(other);
  110. ASSERT_TRUE(copy);
  111. ASSERT_TRUE(move);
  112. ASSERT_EQ(copy.handle().use_count(), 2);
  113. }
  114. TEST(Resource, DynamicResourceHandleCast) {
  115. const entt::resource<derived> resource{std::make_shared<derived>()};
  116. entt::resource<const base> other = resource;
  117. ASSERT_TRUE(other);
  118. ASSERT_EQ(resource.handle().use_count(), 2);
  119. ASSERT_EQ(resource, other);
  120. entt::resource<const derived> cast = dynamic_resource_cast<const derived>(other);
  121. ASSERT_TRUE(cast);
  122. ASSERT_EQ(resource.handle().use_count(), 3);
  123. ASSERT_EQ(resource, cast);
  124. other = entt::resource<base>{std::make_shared<base>()};
  125. cast = dynamic_resource_cast<const derived>(other);
  126. ASSERT_FALSE(cast);
  127. ASSERT_EQ(resource.handle().use_count(), 1);
  128. }
  129. TEST(Resource, Comparison) {
  130. const entt::resource<derived> resource{std::make_shared<derived>()};
  131. const entt::resource<const base> other = resource;
  132. ASSERT_TRUE(resource == other);
  133. ASSERT_FALSE(resource != other);
  134. ASSERT_FALSE(resource < other);
  135. ASSERT_FALSE(resource > other);
  136. ASSERT_TRUE(resource <= other);
  137. ASSERT_TRUE(resource >= other);
  138. }