meta_func.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810
  1. #include <cstddef>
  2. #include <string_view>
  3. #include <type_traits>
  4. #include <utility>
  5. #include <gtest/gtest.h>
  6. #include <entt/core/hashed_string.hpp>
  7. #include <entt/core/utility.hpp>
  8. #include <entt/entity/registry.hpp>
  9. #include <entt/meta/factory.hpp>
  10. #include <entt/meta/meta.hpp>
  11. #include <entt/meta/policy.hpp>
  12. #include <entt/meta/range.hpp>
  13. #include <entt/meta/resolve.hpp>
  14. #include "../../common/config.h"
  15. #include "../../common/meta_traits.h"
  16. struct MetaFunc: ::testing::Test {
  17. struct base {
  18. base() = default;
  19. virtual ~base() = default;
  20. void setter(int iv) {
  21. value = iv;
  22. }
  23. [[nodiscard]] int getter() const {
  24. return value;
  25. }
  26. static void static_setter(base &ref, int iv) {
  27. ref.value = iv;
  28. }
  29. int value{3};
  30. };
  31. static void fake_member(base &instance, int value) {
  32. instance.value = value;
  33. }
  34. [[nodiscard]] static int fake_const_member(const base &instance) {
  35. return instance.value;
  36. }
  37. struct derived: base {
  38. derived() = default;
  39. };
  40. struct function {
  41. [[nodiscard]] int f(const base &, int val, int other) {
  42. return f(val, other);
  43. }
  44. [[nodiscard]] int f(int val, const int other) {
  45. value = val;
  46. return other * other;
  47. }
  48. [[nodiscard]] int f(int iv) const {
  49. return value * iv;
  50. }
  51. [[nodiscard]] int f(int iv) {
  52. return (value += iv);
  53. }
  54. void g(int iv) {
  55. value = iv * iv;
  56. }
  57. [[nodiscard]] static int h(int &iv, const function &instance) {
  58. return (iv *= instance.value);
  59. }
  60. static void k(int iv, function &instance) {
  61. instance.value = iv;
  62. }
  63. [[nodiscard]] const int &v(int &iv) const {
  64. return (iv = value);
  65. }
  66. [[nodiscard]] int &a() {
  67. return value;
  68. }
  69. [[nodiscard]] operator int() const {
  70. return value;
  71. }
  72. int value{};
  73. };
  74. static double double_member(const double &value) {
  75. return value * value;
  76. }
  77. void SetUp() override {
  78. using namespace entt::literals;
  79. entt::meta_factory<double>{}
  80. .type("double"_hs)
  81. .func<&double_member>("member"_hs);
  82. entt::meta_factory<base>{}
  83. .type("base"_hs)
  84. .func<&base::setter>("setter"_hs)
  85. .func<fake_member>("fake_member"_hs)
  86. .func<fake_const_member>("fake_const_member"_hs);
  87. entt::meta_factory<derived>{}
  88. .type("derived"_hs)
  89. .base<base>()
  90. .func<&base::setter>("setter_from_base"_hs)
  91. .func<&base::getter>("getter_from_base")
  92. .func<&base::static_setter>("static_setter_from_base"_hs, "static setter");
  93. entt::meta_factory<function>{}
  94. .type("func"_hs)
  95. .func<&entt::registry::emplace_or_replace<function>, entt::as_ref_t>("emplace"_hs)
  96. .traits(test::meta_traits::one | test::meta_traits::two | test::meta_traits::three)
  97. .func<entt::overload<int(const base &, int, int)>(&function::f)>("f3"_hs)
  98. .traits(test::meta_traits::three)
  99. .func<entt::overload<int(int, int)>(&function::f)>("f2"_hs)
  100. .traits(test::meta_traits::two)
  101. .custom<int>(2)
  102. .func<entt::overload<int(int) const>(&function::f)>("f1"_hs)
  103. .traits(test::meta_traits::one)
  104. .func<entt::overload<int(int) const>(&function::f)>("cf"_hs)
  105. .func<entt::overload<int(int)>(&function::f)>("cf"_hs)
  106. .func<entt::overload<int(int)>(&function::f)>("ncf"_hs)
  107. .func<entt::overload<int(int) const>(&function::f)>("ncf"_hs)
  108. .func<&function::g>("g"_hs)
  109. .custom<char>('c')
  110. .func<function::h>("h"_hs)
  111. .func<function::k>("k"_hs)
  112. .func<&function::v, entt::as_void_t>("v"_hs)
  113. .func<&function::a, entt::as_ref_t>("a"_hs)
  114. .func<&function::a, entt::as_cref_t>("ca"_hs)
  115. .conv<int>();
  116. entt::meta_factory<function>{}
  117. .func<&function::a, entt::as_is_t>("ar"_hs)
  118. .func<&function::v, entt::as_is_t>("vc"_hs)
  119. .func<&function::operator int, entt::as_is_t>("ov"_hs)
  120. .func<&function::g, entt::as_is_t>("ge"_hs);
  121. }
  122. void TearDown() override {
  123. entt::meta_reset();
  124. }
  125. std::size_t reset_and_check() {
  126. std::size_t count = 0;
  127. for(const auto &func: entt::resolve<function>().func()) {
  128. for(auto curr = func.second; curr; curr = curr.next()) {
  129. ++count;
  130. }
  131. }
  132. SetUp();
  133. for(const auto &func: entt::resolve<function>().func()) {
  134. for(auto curr = func.second; curr; curr = curr.next()) {
  135. --count;
  136. }
  137. }
  138. return count;
  139. };
  140. };
  141. using MetaFuncDeathTest = MetaFunc;
  142. TEST_F(MetaFunc, UserTraits) {
  143. using namespace entt::literals;
  144. ASSERT_EQ(entt::resolve<function>().func("h"_hs).traits<test::meta_traits>(), test::meta_traits::none);
  145. ASSERT_EQ(entt::resolve<function>().func("k"_hs).traits<test::meta_traits>(), test::meta_traits::none);
  146. ASSERT_EQ(entt::resolve<function>().func("emplace"_hs).traits<test::meta_traits>(), test::meta_traits::one | test::meta_traits::two | test::meta_traits::three);
  147. ASSERT_EQ(entt::resolve<function>().func("f1"_hs).traits<test::meta_traits>(), test::meta_traits::one);
  148. ASSERT_EQ(entt::resolve<function>().func("f2"_hs).traits<test::meta_traits>(), test::meta_traits::two);
  149. ASSERT_EQ(entt::resolve<function>().func("f3"_hs).traits<test::meta_traits>(), test::meta_traits::three);
  150. }
  151. ENTT_DEBUG_TEST_F(MetaFuncDeathTest, UserTraits) {
  152. using namespace entt::literals;
  153. using traits_type = entt::internal::meta_traits;
  154. constexpr auto value = traits_type{static_cast<std::underlying_type_t<traits_type>>(traits_type::_user_defined_traits) + 1u};
  155. ASSERT_DEATH(entt::meta_factory<function>{}.func<&function::g>("g"_hs).traits(value), "");
  156. }
  157. TEST_F(MetaFunc, Custom) {
  158. using namespace entt::literals;
  159. ASSERT_EQ(*static_cast<const char *>(entt::resolve<function>().func("g"_hs).custom()), 'c');
  160. ASSERT_EQ(static_cast<const char &>(entt::resolve<function>().func("g"_hs).custom()), 'c');
  161. ASSERT_EQ(static_cast<const int *>(entt::resolve<function>().func("g"_hs).custom()), nullptr);
  162. ASSERT_EQ(static_cast<const int *>(entt::resolve<function>().func("h"_hs).custom()), nullptr);
  163. }
  164. ENTT_DEBUG_TEST_F(MetaFuncDeathTest, Custom) {
  165. using namespace entt::literals;
  166. ASSERT_DEATH([[maybe_unused]] const int value = entt::resolve<function>().func("g"_hs).custom(), "");
  167. ASSERT_DEATH([[maybe_unused]] const char value = entt::resolve<function>().func("h"_hs).custom(), "");
  168. }
  169. TEST_F(MetaFunc, Name) {
  170. using namespace entt::literals;
  171. const entt::meta_type type = entt::resolve<derived>();
  172. ASSERT_EQ(type.func("setter_from_base"_hs).name(), std::string_view{});
  173. ASSERT_EQ(type.func("getter_from_base"_hs).name(), std::string_view{"getter_from_base"});
  174. ASSERT_EQ(type.func("static_setter_from_base"_hs).name(), std::string_view{"static setter"});
  175. }
  176. TEST_F(MetaFunc, Comparison) {
  177. using namespace entt::literals;
  178. auto func = entt::resolve<function>().func("f2"_hs);
  179. ASSERT_TRUE(func);
  180. ASSERT_EQ(func, func);
  181. ASSERT_NE(func, entt::meta_func{});
  182. ASSERT_FALSE(func != func);
  183. ASSERT_TRUE(func == func);
  184. }
  185. TEST_F(MetaFunc, Context) {
  186. using namespace entt::literals;
  187. const auto type = entt::resolve<function>();
  188. const auto func = type.func("f2"_hs);
  189. ASSERT_EQ(&func.context(), &type.context());
  190. }
  191. TEST_F(MetaFunc, NonConst) {
  192. using namespace entt::literals;
  193. auto func = entt::resolve<function>().func("f2"_hs);
  194. function instance{};
  195. ASSERT_TRUE(func);
  196. ASSERT_EQ(func.arity(), 2u);
  197. ASSERT_FALSE(func.is_const());
  198. ASSERT_FALSE(func.is_static());
  199. ASSERT_EQ(func.ret(), entt::resolve<int>());
  200. ASSERT_EQ(func.arg(0u), entt::resolve<int>());
  201. ASSERT_EQ(func.arg(1u), entt::resolve<int>());
  202. ASSERT_FALSE(func.arg(2u));
  203. auto any = func.invoke(instance, 3, 2);
  204. auto empty = func.invoke(instance);
  205. ASSERT_FALSE(empty);
  206. ASSERT_TRUE(any);
  207. ASSERT_EQ(any.type(), entt::resolve<int>());
  208. ASSERT_EQ(any.cast<int>(), 4);
  209. ASSERT_EQ(instance.value, 3);
  210. }
  211. TEST_F(MetaFunc, Const) {
  212. using namespace entt::literals;
  213. auto func = entt::resolve<function>().func("f1"_hs);
  214. function instance{2};
  215. ASSERT_TRUE(func);
  216. ASSERT_EQ(func.arity(), 1u);
  217. ASSERT_TRUE(func.is_const());
  218. ASSERT_FALSE(func.is_static());
  219. ASSERT_EQ(func.ret(), entt::resolve<int>());
  220. ASSERT_EQ(func.arg(0u), entt::resolve<int>());
  221. ASSERT_FALSE(func.arg(1u));
  222. auto any = func.invoke(instance, 4);
  223. auto empty = func.invoke(instance, derived{});
  224. ASSERT_FALSE(empty);
  225. ASSERT_TRUE(any);
  226. ASSERT_EQ(any.type(), entt::resolve<int>());
  227. ASSERT_EQ(any.cast<int>(), 8);
  228. }
  229. TEST_F(MetaFunc, RetVoid) {
  230. using namespace entt::literals;
  231. auto func = entt::resolve<function>().func("g"_hs);
  232. function instance{};
  233. ASSERT_TRUE(func);
  234. ASSERT_EQ(func.arity(), 1u);
  235. ASSERT_FALSE(func.is_const());
  236. ASSERT_FALSE(func.is_static());
  237. ASSERT_EQ(func.ret(), entt::resolve<void>());
  238. ASSERT_EQ(func.arg(0u), entt::resolve<int>());
  239. ASSERT_FALSE(func.arg(1u));
  240. auto any = func.invoke(instance, 4);
  241. ASSERT_TRUE(any);
  242. ASSERT_EQ(any.type(), entt::resolve<void>());
  243. ASSERT_EQ(instance.value, 16);
  244. }
  245. TEST_F(MetaFunc, Static) {
  246. using namespace entt::literals;
  247. auto func = entt::resolve<function>().func("h"_hs);
  248. function instance{2};
  249. ASSERT_TRUE(func);
  250. ASSERT_EQ(func.arity(), 2u);
  251. ASSERT_FALSE(func.is_const());
  252. ASSERT_TRUE(func.is_static());
  253. ASSERT_EQ(func.ret(), entt::resolve<int>());
  254. ASSERT_EQ(func.arg(0u), entt::resolve<int>());
  255. ASSERT_EQ(func.arg(1u), entt::resolve<function>());
  256. ASSERT_FALSE(func.arg(2u));
  257. auto any = func.invoke({}, 3, entt::forward_as_meta(instance));
  258. auto empty = func.invoke({}, derived{}, entt::forward_as_meta(instance));
  259. ASSERT_FALSE(empty);
  260. ASSERT_TRUE(any);
  261. ASSERT_EQ(any.type(), entt::resolve<int>());
  262. ASSERT_EQ(any.cast<int>(), 6);
  263. }
  264. TEST_F(MetaFunc, StaticRetVoid) {
  265. using namespace entt::literals;
  266. auto func = entt::resolve<function>().func("k"_hs);
  267. function instance{};
  268. ASSERT_TRUE(func);
  269. ASSERT_EQ(func.arity(), 2u);
  270. ASSERT_FALSE(func.is_const());
  271. ASSERT_TRUE(func.is_static());
  272. ASSERT_EQ(func.ret(), entt::resolve<void>());
  273. ASSERT_EQ(func.arg(0u), entt::resolve<int>());
  274. ASSERT_EQ(func.arg(1u), entt::resolve<function>());
  275. ASSERT_FALSE(func.arg(2u));
  276. auto any = func.invoke({}, 3, entt::forward_as_meta(instance));
  277. ASSERT_TRUE(any);
  278. ASSERT_EQ(any.type(), entt::resolve<void>());
  279. ASSERT_EQ(instance.value, 3);
  280. }
  281. TEST_F(MetaFunc, StaticAsMember) {
  282. using namespace entt::literals;
  283. base instance{};
  284. auto func = entt::resolve<base>().func("fake_member"_hs);
  285. auto any = func.invoke(instance, 3);
  286. ASSERT_TRUE(func);
  287. ASSERT_EQ(func.arity(), 1u);
  288. ASSERT_FALSE(func.is_const());
  289. ASSERT_FALSE(func.is_static());
  290. ASSERT_EQ(func.ret(), entt::resolve<void>());
  291. ASSERT_EQ(func.arg(0u), entt::resolve<int>());
  292. ASSERT_FALSE(func.arg(1u));
  293. ASSERT_FALSE(func.invoke({}, 3));
  294. ASSERT_FALSE(func.invoke(std::as_const(instance), 3));
  295. ASSERT_TRUE(any);
  296. ASSERT_EQ(any.type(), entt::resolve<void>());
  297. ASSERT_EQ(instance.value, 3);
  298. }
  299. TEST_F(MetaFunc, StaticAsConstMember) {
  300. using namespace entt::literals;
  301. base instance{};
  302. auto func = entt::resolve<base>().func("fake_const_member"_hs);
  303. auto any = func.invoke(std::as_const(instance));
  304. ASSERT_TRUE(func);
  305. ASSERT_EQ(func.arity(), 0u);
  306. ASSERT_TRUE(func.is_const());
  307. ASSERT_FALSE(func.is_static());
  308. ASSERT_EQ(func.ret(), entt::resolve<int>());
  309. ASSERT_FALSE(func.arg(0u));
  310. ASSERT_FALSE(func.invoke({}));
  311. ASSERT_TRUE(func.invoke(instance));
  312. ASSERT_TRUE(any);
  313. ASSERT_EQ(any.type(), entt::resolve<int>());
  314. ASSERT_EQ(any.cast<int>(), 3);
  315. }
  316. TEST_F(MetaFunc, NonClassTypeMember) {
  317. using namespace entt::literals;
  318. double instance = 3.;
  319. auto func = entt::resolve<double>().func("member"_hs);
  320. auto any = func.invoke(instance);
  321. ASSERT_TRUE(func);
  322. ASSERT_EQ(func.arity(), 0u);
  323. ASSERT_TRUE(func.is_const());
  324. ASSERT_FALSE(func.is_static());
  325. ASSERT_EQ(func.ret(), entt::resolve<double>());
  326. ASSERT_FALSE(func.arg(0u));
  327. ASSERT_FALSE(func.invoke({}));
  328. ASSERT_TRUE(func.invoke(instance));
  329. ASSERT_TRUE(any);
  330. ASSERT_EQ(any.type(), entt::resolve<double>());
  331. ASSERT_EQ(any.cast<double>(), instance * instance);
  332. }
  333. TEST_F(MetaFunc, MetaAnyArgs) {
  334. using namespace entt::literals;
  335. function instance{3};
  336. auto any = entt::resolve<function>().func("f1"_hs).invoke(instance, 3);
  337. ASSERT_TRUE(any);
  338. ASSERT_EQ(any.type(), entt::resolve<int>());
  339. ASSERT_EQ(any.cast<int>(), 9);
  340. }
  341. TEST_F(MetaFunc, InvalidArgs) {
  342. using namespace entt::literals;
  343. int value = 3;
  344. ASSERT_FALSE(entt::resolve<function>().func("f1"_hs).invoke(value, 'c'));
  345. }
  346. TEST_F(MetaFunc, CastAndConvert) {
  347. using namespace entt::literals;
  348. function instance;
  349. instance.value = 3;
  350. auto any = entt::resolve<function>().func("f3"_hs).invoke(instance, derived{}, 0, instance);
  351. ASSERT_TRUE(any);
  352. ASSERT_EQ(any.type(), entt::resolve<int>());
  353. ASSERT_EQ(any.cast<int>(), 9);
  354. ASSERT_EQ(instance.value, 0);
  355. }
  356. TEST_F(MetaFunc, ArithmeticConversion) {
  357. using namespace entt::literals;
  358. function instance;
  359. auto any = entt::resolve<function>().func("f2"_hs).invoke(instance, true, 4.2);
  360. ASSERT_TRUE(any);
  361. ASSERT_EQ(any.type(), entt::resolve<int>());
  362. ASSERT_EQ(any.cast<int>(), 16);
  363. ASSERT_EQ(instance.value, 1);
  364. }
  365. TEST_F(MetaFunc, ArgsByRef) {
  366. using namespace entt::literals;
  367. auto func = entt::resolve<function>().func("h"_hs);
  368. function instance{2};
  369. entt::meta_any any{3};
  370. int value = 4;
  371. ASSERT_EQ(func.invoke({}, entt::forward_as_meta(value), entt::forward_as_meta(instance)).cast<int>(), 8);
  372. ASSERT_EQ(func.invoke({}, any.as_ref(), entt::forward_as_meta(instance)).cast<int>(), 6);
  373. ASSERT_EQ(any.cast<int>(), 6);
  374. ASSERT_EQ(value, 8);
  375. }
  376. TEST_F(MetaFunc, ArgsByConstRef) {
  377. using namespace entt::literals;
  378. function instance{};
  379. auto func = entt::resolve<function>().func("g"_hs);
  380. entt::meta_any any{2};
  381. int value = 3;
  382. ASSERT_TRUE(func.invoke(instance, entt::forward_as_meta(std::as_const(value))));
  383. ASSERT_EQ(instance.value, 9);
  384. ASSERT_TRUE(func.invoke(instance, std::as_const(any).as_ref()));
  385. ASSERT_EQ(instance.value, 4);
  386. }
  387. TEST_F(MetaFunc, ConstInstance) {
  388. using namespace entt::literals;
  389. function instance{2};
  390. auto any = entt::resolve<function>().func("f1"_hs).invoke(std::as_const(instance), 2);
  391. ASSERT_FALSE(entt::resolve<function>().func("g"_hs).invoke(std::as_const(instance), 1));
  392. ASSERT_TRUE(any);
  393. ASSERT_EQ(any.cast<int>(), 4);
  394. }
  395. TEST_F(MetaFunc, AsVoid) {
  396. using namespace entt::literals;
  397. auto func = entt::resolve<function>().func("v"_hs);
  398. function instance{3};
  399. int value{2};
  400. ASSERT_EQ(func.invoke(instance, entt::forward_as_meta(value)), entt::meta_any{std::in_place_type<void>});
  401. ASSERT_EQ(func.ret(), entt::resolve<void>());
  402. ASSERT_EQ(value, instance.value);
  403. }
  404. TEST_F(MetaFunc, AsIs) {
  405. using namespace entt::literals;
  406. auto type = entt::resolve<function>();
  407. entt::meta_func func{};
  408. function instance{3};
  409. func = type.func("ar"_hs);
  410. ASSERT_TRUE(func);
  411. ASSERT_EQ(func.ret(), entt::resolve<int>());
  412. ASSERT_EQ(func.invoke(instance).base().policy(), entt::any_policy::ref);
  413. func = type.func("vc"_hs);
  414. ASSERT_TRUE(func);
  415. ASSERT_EQ(func.ret(), entt::resolve<int>());
  416. ASSERT_EQ(func.invoke(instance, 3).base().policy(), entt::any_policy::cref);
  417. func = type.func("ov"_hs);
  418. ASSERT_TRUE(func);
  419. ASSERT_EQ(func.ret(), entt::resolve<int>());
  420. ASSERT_EQ(func.invoke(instance).base().policy(), entt::any_policy::embedded);
  421. func = type.func("ge"_hs);
  422. ASSERT_TRUE(func);
  423. ASSERT_EQ(func.ret(), entt::resolve<void>());
  424. ASSERT_EQ(func.invoke(instance).base().policy(), entt::any_policy::empty);
  425. }
  426. TEST_F(MetaFunc, AsRef) {
  427. using namespace entt::literals;
  428. function instance{};
  429. auto func = entt::resolve<function>().func("a"_hs);
  430. func.invoke(instance).cast<int &>() = 3;
  431. ASSERT_EQ(func.ret(), entt::resolve<int>());
  432. ASSERT_EQ(instance.value, 3);
  433. }
  434. TEST_F(MetaFunc, AsConstRef) {
  435. using namespace entt::literals;
  436. function instance{3};
  437. auto func = entt::resolve<function>().func("ca"_hs);
  438. ASSERT_EQ(func.ret(), entt::resolve<int>());
  439. ASSERT_EQ(func.invoke(instance).cast<const int &>(), 3);
  440. ASSERT_EQ(func.invoke(instance).cast<int>(), 3);
  441. }
  442. ENTT_DEBUG_TEST_F(MetaFuncDeathTest, AsConstRef) {
  443. using namespace entt::literals;
  444. function instance{};
  445. auto func = entt::resolve<function>().func("ca"_hs);
  446. ASSERT_DEATH((func.invoke(instance).cast<int &>() = 3), "");
  447. }
  448. TEST_F(MetaFunc, InvokeBaseFunction) {
  449. using namespace entt::literals;
  450. auto type = entt::resolve<derived>();
  451. derived instance{};
  452. ASSERT_TRUE(type.func("setter"_hs));
  453. ASSERT_EQ(instance.value, 3);
  454. type.func("setter"_hs).invoke(instance, 1);
  455. ASSERT_EQ(instance.value, 1);
  456. }
  457. TEST_F(MetaFunc, InvokeFromBase) {
  458. using namespace entt::literals;
  459. auto type = entt::resolve<derived>();
  460. derived instance{};
  461. auto setter_from_base = type.func("setter_from_base"_hs);
  462. ASSERT_TRUE(setter_from_base);
  463. ASSERT_EQ(instance.value, 3);
  464. setter_from_base.invoke(instance, 1);
  465. ASSERT_EQ(instance.value, 1);
  466. auto getter_from_base = type.func("getter_from_base"_hs);
  467. ASSERT_TRUE(getter_from_base);
  468. ASSERT_EQ(getter_from_base.invoke(instance).cast<int>(), 1);
  469. auto static_setter_from_base = type.func("static_setter_from_base"_hs);
  470. ASSERT_TRUE(static_setter_from_base);
  471. ASSERT_EQ(instance.value, 1);
  472. static_setter_from_base.invoke(instance, 3);
  473. ASSERT_EQ(instance.value, 3);
  474. }
  475. TEST_F(MetaFunc, ExternalMemberFunction) {
  476. using namespace entt::literals;
  477. auto func = entt::resolve<function>().func("emplace"_hs);
  478. ASSERT_TRUE(func);
  479. ASSERT_EQ(func.arity(), 2u);
  480. ASSERT_FALSE(func.is_const());
  481. ASSERT_TRUE(func.is_static());
  482. ASSERT_EQ(func.ret(), entt::resolve<function>());
  483. ASSERT_EQ(func.arg(0u), entt::resolve<entt::registry>());
  484. ASSERT_EQ(func.arg(1u), entt::resolve<entt::entity>());
  485. ASSERT_FALSE(func.arg(2u));
  486. entt::registry registry;
  487. const auto entity = registry.create();
  488. ASSERT_FALSE(registry.all_of<function>(entity));
  489. func.invoke({}, entt::forward_as_meta(registry), entity);
  490. ASSERT_TRUE(registry.all_of<function>(entity));
  491. }
  492. TEST_F(MetaFunc, Overloaded) {
  493. using namespace entt::literals;
  494. auto type = entt::resolve<function>();
  495. ASSERT_FALSE(type.func("f2"_hs).next());
  496. entt::meta_factory<function>{}
  497. // this should not overwrite traits and custom data
  498. .func<entt::overload<int(int, int)>(&function::f)>("f2"_hs)
  499. // this should put traits and custom data on the new overload instead
  500. .func<entt::overload<int(int) const>(&function::f)>("f2"_hs)
  501. .traits(test::meta_traits::three)
  502. .custom<int>(3);
  503. ASSERT_TRUE(type.func("f2"_hs).next());
  504. ASSERT_FALSE(type.func("f2"_hs).next().next());
  505. ASSERT_EQ(type.func("f2"_hs).traits<test::meta_traits>(), test::meta_traits::two);
  506. ASSERT_EQ(type.func("f2"_hs).next().traits<test::meta_traits>(), test::meta_traits::three);
  507. ASSERT_NE(static_cast<const int *>(type.func("f2"_hs).custom()), nullptr);
  508. ASSERT_NE(static_cast<const int *>(type.func("f2"_hs).next().custom()), nullptr);
  509. ASSERT_EQ(static_cast<const int &>(type.func("f2"_hs).custom()), 2);
  510. ASSERT_EQ(static_cast<const int &>(type.func("f2"_hs).next().custom()), 3);
  511. }
  512. TEST_F(MetaFunc, OverloadedConstFirst) {
  513. using namespace entt::literals;
  514. auto func = entt::resolve<function>().func("cf"_hs);
  515. auto next = func.next();
  516. function instance{2};
  517. ASSERT_TRUE(func);
  518. ASSERT_EQ(func.arity(), 1u);
  519. ASSERT_TRUE(func.is_const());
  520. ASSERT_EQ(func.ret(), entt::resolve<int>());
  521. ASSERT_EQ(func.arg(0u), entt::resolve<int>());
  522. ASSERT_TRUE(next);
  523. ASSERT_EQ(next.arity(), 1u);
  524. ASSERT_FALSE(next.is_const());
  525. ASSERT_EQ(next.ret(), entt::resolve<int>());
  526. ASSERT_EQ(next.arg(0u), entt::resolve<int>());
  527. ASSERT_EQ(func.invoke(instance, 1).cast<int>(), 2);
  528. ASSERT_EQ(next.invoke(instance, 1).cast<int>(), 3);
  529. ASSERT_EQ(func.invoke(std::as_const(instance), 1).cast<int>(), 3);
  530. ASSERT_FALSE(next.invoke(std::as_const(instance), 1));
  531. ASSERT_EQ(func.invoke(entt::meta_handle{instance}, entt::meta_any{1}).cast<int>(), 3);
  532. ASSERT_EQ(next.invoke(entt::meta_handle{instance}, entt::meta_any{1}).cast<int>(), 4);
  533. ASSERT_EQ(func.invoke(entt::meta_handle{std::as_const(instance)}, entt::meta_any{1}).cast<int>(), 4);
  534. ASSERT_FALSE(next.invoke(entt::meta_handle{std::as_const(instance)}, entt::meta_any{1}));
  535. }
  536. TEST_F(MetaFunc, OverloadedNonConstFirst) {
  537. using namespace entt::literals;
  538. auto func = entt::resolve<function>().func("ncf"_hs);
  539. auto next = func.next();
  540. function instance{2};
  541. ASSERT_TRUE(func);
  542. ASSERT_EQ(func.arity(), 1u);
  543. ASSERT_FALSE(func.is_const());
  544. ASSERT_EQ(func.ret(), entt::resolve<int>());
  545. ASSERT_EQ(func.arg(0u), entt::resolve<int>());
  546. ASSERT_TRUE(next);
  547. ASSERT_EQ(next.arity(), 1u);
  548. ASSERT_TRUE(next.is_const());
  549. ASSERT_EQ(next.ret(), entt::resolve<int>());
  550. ASSERT_EQ(next.arg(0u), entt::resolve<int>());
  551. ASSERT_EQ(func.invoke(instance, 1).cast<int>(), 3);
  552. ASSERT_EQ(next.invoke(instance, 1).cast<int>(), 3);
  553. ASSERT_FALSE(func.invoke(std::as_const(instance), 1));
  554. ASSERT_EQ(next.invoke(std::as_const(instance), 1).cast<int>(), 3);
  555. ASSERT_EQ(func.invoke(entt::meta_handle{instance}, entt::meta_any{1}).cast<int>(), 4);
  556. ASSERT_EQ(next.invoke(entt::meta_handle{instance}, entt::meta_any{1}).cast<int>(), 4);
  557. ASSERT_FALSE(func.invoke(entt::meta_handle{std::as_const(instance)}, entt::meta_any{1}));
  558. ASSERT_EQ(next.invoke(entt::meta_handle{std::as_const(instance)}, entt::meta_any{1}).cast<int>(), 4);
  559. }
  560. TEST_F(MetaFunc, OverloadedOrder) {
  561. using namespace entt::literals;
  562. entt::meta_factory<function>{}
  563. .func<entt::overload<int(int, int)>(&function::f)>("f2"_hs)
  564. .func<entt::overload<int(int) const>(&function::f)>("f2"_hs);
  565. auto type = entt::resolve<function>();
  566. auto func = type.func("f2"_hs);
  567. ASSERT_TRUE(func);
  568. ASSERT_EQ(func.arity(), 2u);
  569. ASSERT_FALSE(func.is_const());
  570. ASSERT_EQ(func.ret(), entt::resolve<int>());
  571. func = func.next();
  572. ASSERT_TRUE(func);
  573. ASSERT_EQ(func.arity(), 1u);
  574. ASSERT_TRUE(func.is_const());
  575. ASSERT_EQ(func.ret(), entt::resolve<int>());
  576. func = func.next();
  577. ASSERT_FALSE(func);
  578. }
  579. TEST_F(MetaFunc, ReRegistration) {
  580. using namespace entt::literals;
  581. ASSERT_EQ(reset_and_check(), 0u);
  582. function instance{};
  583. auto type = entt::resolve<function>();
  584. ASSERT_TRUE(type.func("f2"_hs));
  585. ASSERT_FALSE(type.invoke("f2"_hs, instance, 0));
  586. ASSERT_TRUE(type.invoke("f2"_hs, instance, 0, 0));
  587. ASSERT_TRUE(type.func("f1"_hs));
  588. ASSERT_TRUE(type.invoke("f1"_hs, instance, 0));
  589. ASSERT_FALSE(type.invoke("f1"_hs, instance, 0, 0));
  590. entt::meta_factory<function>{}
  591. .func<entt::overload<int(int, int)>(&function::f)>("f"_hs)
  592. .func<entt::overload<int(int) const>(&function::f)>("f"_hs);
  593. ASSERT_TRUE(type.func("f1"_hs));
  594. ASSERT_TRUE(type.func("f2"_hs));
  595. ASSERT_TRUE(type.func("f"_hs));
  596. ASSERT_TRUE(type.invoke("f"_hs, instance, 0));
  597. ASSERT_TRUE(type.invoke("f"_hs, instance, 0, 0));
  598. entt::meta_factory<function>{}
  599. .func<entt::overload<int(int, int)>(&function::f)>("f"_hs)
  600. .traits(test::meta_traits::one)
  601. .custom<int>(3)
  602. // this should not overwrite traits and custom data
  603. .func<entt::overload<int(int, int)>(&function::f)>("f"_hs);
  604. ASSERT_EQ(type.func("f"_hs).traits<test::meta_traits>(), test::meta_traits::one);
  605. ASSERT_NE(static_cast<const int *>(type.func("f"_hs).custom()), nullptr);
  606. ASSERT_EQ(reset_and_check(), 0u);
  607. }