Bladeren bron

meta: support for key-only properties

Michele Caini 6 jaren geleden
bovenliggende
commit
ed89d94d7a
2 gewijzigde bestanden met toevoegingen van 30 en 12 verwijderingen
  1. 14 11
      src/entt/meta/factory.hpp
  2. 16 1
      test/entt/meta/meta.cpp

+ 14 - 11
src/entt/meta/factory.hpp

@@ -704,31 +704,34 @@ public:
     /**
      * @brief Assigns properties to the last meta object created.
      *
-     * Both the key and the value must be at least copy constructible.
+     * Both the key and the value (if any) must be at least copy constructible.
      *
      * @tparam Key Type of the property key.
-     * @tparam Value Type of the property value.
+     * @tparam Value Optional type of the property value.
      * @param pkey Property key.
-     * @param pvalue Property value.
+     * @param pvalue Optional property value.
      * @return A meta factory for the parent type.
      */
-    template<typename Key, typename Value>
-    auto prop(Key &&pkey, Value &&pvalue) {
-        ENTT_ASSERT(props);
-        static auto key{std::forward<Key>(pkey)};
-        static auto value{std::forward<Value>(pvalue)};
+    template<typename Key, typename... Value>
+    auto prop(Key &&pkey, Value &&... pvalue) {
+        static_assert(sizeof...(Value) <= 1);
+        static auto property{std::make_tuple(std::forward<Key>(pkey), std::forward<Value>(pvalue)...)};
 
         static internal::meta_prop_node node{
             *props,
             []() -> meta_any {
-                return key;
+                return std::get<0>(property);
             },
             []() -> meta_any {
-                return value;
+                if constexpr(sizeof...(Value) == 0) {
+                    return {};
+                } else {
+                    return std::get<1>(property);
+                }
             }
         };
 
-        ENTT_ASSERT(!duplicate(key, *props));
+        ENTT_ASSERT(!duplicate(node.key(), *props));
         *props = &node;
 
         return *this;

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

@@ -19,7 +19,8 @@ Type get(Type &prop) {
 
 enum class properties {
     prop_int,
-    prop_bool
+    prop_bool,
+    key_only
 };
 
 struct empty_type {
@@ -156,6 +157,9 @@ struct Meta: ::testing::Test {
                 .data<properties::prop_int>("prop_int"_hs)
                     .prop(properties::prop_bool, true)
                     .prop(properties::prop_int, 0)
+                    .prop(properties::key_only)
+                .data<properties::key_only>("key_only"_hs)
+                    .prop(properties::key_only)
                 .data<&set<properties>, &get<properties>>("value"_hs);
 
         entt::meta<unsigned int>().data<0u>("min"_hs).data<100u>("max"_hs);
@@ -2013,6 +2017,17 @@ TEST_F(Meta, SharedProperties) {
     ASSERT_TRUE(prop_int.prop(properties::prop_bool));
 }
 
+TEST_F(Meta, KeyOnlyProperties) {
+    const auto type = entt::resolve<properties>();
+    const auto prop = type.data("key_only"_hs).prop(properties::key_only);
+
+    ASSERT_TRUE(prop);
+    ASSERT_TRUE(prop.key());
+    ASSERT_EQ(prop.key().type(), entt::resolve<properties>());
+    ASSERT_EQ(prop.key().cast<properties>(), properties::key_only);
+    ASSERT_FALSE(prop.value());
+}
+
 TEST_F(Meta, Reset) {
     ASSERT_NE(*entt::internal::meta_info<>::global, nullptr);
     ASSERT_NE(entt::internal::meta_info<>::local, nullptr);