Просмотр исходного кода

meta: all function arguments are taken by alias (close #301)

Michele Caini 6 лет назад
Родитель
Сommit
ac111224ae
2 измененных файлов с 18 добавлено и 4 удалено
  1. 2 1
      src/entt/meta/meta.hpp
  2. 16 3
      test/entt/meta/meta.cpp

+ 2 - 1
src/entt/meta/meta.hpp

@@ -1457,7 +1457,8 @@ public:
      */
     template<typename... Args>
     meta_any invoke(meta_handle handle, Args &&... args) const {
-        std::array<meta_any, sizeof...(Args)> arguments{{std::forward<Args>(args)...}};
+        // makes aliasing on the values and passes forward references if any
+        std::array<meta_any, sizeof...(Args)> arguments{{meta_handle{args}...}};
         meta_any any{};
 
         if(sizeof...(Args) == size()) {

+ 16 - 3
test/entt/meta/meta.cpp

@@ -98,7 +98,7 @@ struct func_type {
     int f(int v) const { return v*v; }
     void g(int v) { value = v*v; }
 
-    static int h(int v) { return v; }
+    static int h(int &v) { return (v *= value); }
     static void k(int v) { value = v; }
 
     int v(int v) const { return (value = v); }
@@ -1526,6 +1526,7 @@ TEST_F(Meta, MetaFuncRetVoid) {
 
 TEST_F(Meta, MetaFuncStatic) {
     auto func = entt::resolve<func_type>().func("h"_hs);
+    func_type::value = 2;
 
     ASSERT_TRUE(func);
     ASSERT_EQ(func.parent(), entt::resolve("func"_hs));
@@ -1537,13 +1538,13 @@ TEST_F(Meta, MetaFuncStatic) {
     ASSERT_EQ(func.arg(entt::meta_func::size_type{0}), entt::resolve<int>());
     ASSERT_FALSE(func.arg(entt::meta_func::size_type{1}));
 
-    auto any = func.invoke({}, 42);
+    auto any = func.invoke({}, 3);
     auto empty = func.invoke({}, 'c');
 
     ASSERT_FALSE(empty);
     ASSERT_TRUE(any);
     ASSERT_EQ(any.type(), entt::resolve<int>());
-    ASSERT_EQ(any.cast<int>(), 42);
+    ASSERT_EQ(any.cast<int>(), 6);
 
     func.prop([](auto prop) {
         ASSERT_TRUE(prop);
@@ -1641,6 +1642,18 @@ TEST_F(Meta, MetaFuncAsAlias) {
     ASSERT_EQ(instance.value, 3);
 }
 
+TEST_F(Meta, MetaFuncByReference) {
+    auto func = entt::resolve<func_type>().func("h"_hs);
+    func_type::value = 2;
+    entt::meta_any any{3};
+    int value = 4;
+
+    ASSERT_EQ(func.invoke({}, value).cast<int>(), 8);
+    ASSERT_EQ(func.invoke({}, any).cast<int>(), 6);
+    ASSERT_EQ(any.cast<int>(), 6);
+    ASSERT_EQ(value, 8);
+}
+
 TEST_F(Meta, MetaType) {
     auto type = entt::resolve<derived_type>();