[glib/ebassi/final-flag: 1/4] gtype: Add a "final" flag




commit c07dd416cffc9e57fc282b2bf89375bdb2df9c95
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Tue Feb 9 10:45:00 2021 +0000

    gtype: Add a "final" flag
    
    We want to have the ability to mark types that should not be derivable
    even if they are in a deeply derivable type hierarchy; in other words,
    leaf nodes in the types tree.

 gobject/gtype.c |  9 ++++++++-
 gobject/gtype.h | 19 +++++++++++++++++--
 2 files changed, 25 insertions(+), 3 deletions(-)
---
diff --git a/gobject/gtype.c b/gobject/gtype.c
index 2cdbe7ce4..422e1cae4 100644
--- a/gobject/gtype.c
+++ b/gobject/gtype.c
@@ -143,7 +143,7 @@
                                    G_TYPE_FLAG_INSTANTIATABLE | \
                                    G_TYPE_FLAG_DERIVABLE | \
                                    G_TYPE_FLAG_DEEP_DERIVABLE)
-#define        TYPE_FLAG_MASK             (G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT)
+#define        TYPE_FLAG_MASK             (G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT | 
G_TYPE_FLAG_FINAL)
 #define        SIZEOF_FUNDAMENTAL_INFO    ((gssize) MAX (MAX (sizeof (GTypeFundamentalInfo), \
                                                       sizeof (gpointer)), \
                                                   sizeof (glong)))
@@ -804,6 +804,13 @@ check_derivation_I (GType        parent_type,
                 NODE_NAME (pnode));
       return FALSE;
     }
+  if ((G_TYPE_FLAG_FINAL & GPOINTER_TO_UINT (type_get_qdata_L (pnode, static_quark_type_flags))) == 
G_TYPE_FLAG_FINAL)
+    {
+      g_warning ("cannot derive '%s' from final parent type '%s'",
+                 type_name,
+                 NODE_NAME (pnode));
+      return FALSE;
+    }
   
   return TRUE;
 }
diff --git a/gobject/gtype.h b/gobject/gtype.h
index f38b4cf4c..9dfd85ac9 100644
--- a/gobject/gtype.h
+++ b/gobject/gtype.h
@@ -370,6 +370,18 @@ G_BEGIN_DECLS
  * Returns: %TRUE on success
  */
 #define G_TYPE_HAS_VALUE_TABLE(type)            (g_type_value_table_peek (type) != NULL)
+/**
+ * G_TYPE_IS_FINAL:
+ * @type: a #GType value
+ *
+ * Checks if @type is a final type. A final type cannot be derived any
+ * further.
+ *
+ * Returns: %TRUE on success
+ *
+ * Since: 2.70
+ */
+#define G_TYPE_IS_FINAL(type)                   (g_type_test_flags ((type), G_TYPE_FLAG_FINAL)) 
GLIB_AVAILABLE_MACRO_IN_2_70
 
 
 /* Typedefs
@@ -1002,13 +1014,16 @@ typedef enum    /*< skip >*/
  * @G_TYPE_FLAG_VALUE_ABSTRACT: Indicates an abstract value type, i.e. a type
  *  that introduces a value table, but can't be used for
  *  g_value_init()
+ * @G_TYPE_FLAG_FINAL: Indicates a final type. A final type is a non-derivable
+ *  leaf node in a deep derivable type hierarchy tree. Since: 2.70
  * 
  * Bit masks used to check or determine characteristics of a type.
  */
 typedef enum    /*< skip >*/
 {
-  G_TYPE_FLAG_ABSTRACT         = (1 << 4),
-  G_TYPE_FLAG_VALUE_ABSTRACT   = (1 << 5)
+  G_TYPE_FLAG_ABSTRACT = (1 << 4),
+  G_TYPE_FLAG_VALUE_ABSTRACT = (1 << 5),
+  G_TYPE_FLAG_FINAL GLIB_AVAILABLE_ENUMERATOR_IN_2_70 = (1 << 6)
 } GTypeFlags;
 /**
  * GTypeInfo:


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]