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.
This commit is contained in:
Benjamin Otte 2019-11-25 19:40:39 +01:00
parent ebec0dd359
commit eb20dec144
4 changed files with 50 additions and 0 deletions

View File

@ -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

View File

@ -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,

View File

@ -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);

View File

@ -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);