[glib/wip/otte/interface-types: 4/5] gtype: Add g_type_interface_instantiable_prerequisite()
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/wip/otte/interface-types: 4/5] gtype: Add g_type_interface_instantiable_prerequisite()
- Date: Mon, 25 Nov 2019 23:57:35 +0000 (UTC)
commit b823bc5d26b7020bdeff1de684179421e0334785
Author: Benjamin Otte <otte redhat com>
Date: Mon Nov 25 19:40:39 2019 +0100
gtype: Add g_type_interface_instantiable_prerequisite()
There is (at most) a single GType that is instantiable and a
prerequisite for an interface. This function returns that type.
This type is necessary in particular when dealing with GValues because a
GValue contains an instance of a type.
docs/reference/gobject/gobject-sections.txt | 1 +
gobject/gtype.c | 45 +++++++++++++++++++++++++++++
gobject/gtype.h | 3 ++
gobject/tests/type.c | 1 +
4 files changed, 50 insertions(+)
---
diff --git a/docs/reference/gobject/gobject-sections.txt b/docs/reference/gobject/gobject-sections.txt
index bed38e4c5..81db1b576 100644
--- a/docs/reference/gobject/gobject-sections.txt
+++ b/docs/reference/gobject/gobject-sections.txt
@@ -65,6 +65,7 @@ g_type_default_interface_unref
g_type_children
g_type_interfaces
g_type_interface_prerequisites
+g_type_interface_instantiable_prerequisite
g_type_set_qdata
g_type_get_qdata
g_type_query
diff --git a/gobject/gtype.c b/gobject/gtype.c
index b5ef2d11e..f38f5d0be 100644
--- a/gobject/gtype.c
+++ b/gobject/gtype.c
@@ -1689,6 +1689,51 @@ g_type_interface_prerequisites (GType interface_type,
}
}
+/**
+ * g_type_interface_instantiable_prerequisite:
+ * @interface_type: an interface type
+ *
+ * Returns the instantiable prerequisite of an interface type.
+ *
+ * If the interface type has no instantiable prerequisite, 0 is returned.
+ *
+ * Since: 2.64
+ *
+ * Returns: the instantiable prerequisite type or 0 if none
+ **/
+GType
+g_type_interface_instantiable_prerequisite (GType interface_type)
+{
+ TypeNode *inode = NULL;
+ TypeNode *iface;
+ guint i;
+
+ g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface_type), G_TYPE_INVALID);
+
+ iface = lookup_type_node_I (interface_type);
+ if (iface == NULL)
+ return 0;
+
+ G_READ_LOCK (&type_rw_lock);
+
+ for (i = 0; i < IFACE_NODE_N_PREREQUISITES (iface); i++)
+ {
+ GType prerequisite = IFACE_NODE_PREREQUISITES (iface)[i];
+ TypeNode *node = lookup_type_node_I (prerequisite);
+ if (node->is_instantiatable)
+ {
+ if (!inode || type_node_is_a_L (node, inode))
+ inode = node;
+ }
+ }
+
+ G_READ_UNLOCK (&type_rw_lock);
+
+ if (inode)
+ return NODE_TYPE (inode);
+ else
+ return 0;
+}
static IFaceHolder*
type_iface_peek_holder_L (TypeNode *iface,
diff --git a/gobject/gtype.h b/gobject/gtype.h
index 797ab48ee..b092f7f2b 100644
--- a/gobject/gtype.h
+++ b/gobject/gtype.h
@@ -1304,6 +1304,9 @@ void g_type_interface_add_prerequisite (GType interface_type,
GLIB_AVAILABLE_IN_ALL
GType*g_type_interface_prerequisites (GType interface_type,
guint *n_prerequisites);
+GLIB_AVAILABLE_IN_2_64
+GType g_type_interface_instantiable_prerequisite
+ (GType interface_type);
GLIB_DEPRECATED_IN_2_58
void g_type_class_add_private (gpointer g_class,
gsize private_size);
diff --git a/gobject/tests/type.c b/gobject/tests/type.c
index c5db7e992..9ed1806e9 100644
--- a/gobject/tests/type.c
+++ b/gobject/tests/type.c
@@ -52,6 +52,7 @@ test_interface_prerequisite (void)
g_assert_cmpint (n_prereqs, ==, 2);
g_assert (prereqs[0] == bar_get_type ());
g_assert (prereqs[1] == G_TYPE_OBJECT);
+ g_assert (g_type_interface_instantiable_prerequisite (foo_get_type ()) == G_TYPE_OBJECT);
iface = g_type_default_interface_ref (foo_get_type ());
parent = g_type_interface_peek_parent (iface);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]