GType: add accessor for instance private offset

Since instance private data is now always at a constant offset to the
instance pointer, we can add an accessor for it that doesn't also
require an instance.

The idea is that classes can call this from their class_init and store
it in a file-scoped static variable and use that to find their private
data on instances very quickly, without a priv pointer.

https://bugzilla.gnome.org/show_bug.cgi?id=698056
This commit is contained in:
Ryan Lortie 2013-04-23 10:38:23 -04:00
parent eb860fd898
commit c30c0bb34d
3 changed files with 51 additions and 0 deletions

View File

@ -125,6 +125,7 @@ g_type_check_is_value_type
g_type_check_value
g_type_check_value_holds
g_type_instance_get_private
g_type_class_get_instance_private_offset
g_type_class_get_private
g_type_test_flags
g_type_name_from_instance

View File

@ -4528,6 +4528,54 @@ g_type_instance_get_private (GTypeInstance *instance,
return ((gchar *) instance) - node->data->instance.private_size;
}
/**
* g_type_class_get_instance_private_offset: (skip)
* @g_class: a #GTypeClass
*
* Gets the offset of the private data for instances of @g_class.
*
* This is how many bytes you should add to the instance pointer of a
* class in order to get the private data for the type represented by
* @g_class.
*
* You can only call this function after you have registered a private
* data area for @g_class using g_type_class_add_private().
*
* Returns: the offset, in bytes
*
* Since: 2.38
**/
gint
g_type_class_get_instance_private_offset (gpointer g_class)
{
GType instance_type;
guint16 parent_size;
TypeNode *node;
g_assert (g_class != NULL);
instance_type = ((GTypeClass *) g_class)->g_type;
node = lookup_type_node_I (instance_type);
g_assert (node != NULL);
g_assert (node->is_instantiatable);
if (NODE_PARENT_TYPE (node))
{
TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node));
parent_size = pnode->data->instance.private_size;
}
else
parent_size = 0;
if (node->data->instance.private_size == parent_size)
g_error ("g_type_class_get_instance_private_offset() called on class %s but it has no private data",
g_type_name (instance_type));
return -(gint) node->data->instance.private_size;
}
/**
* g_type_add_class_private:
* @class_type: GType of an classed type.

View File

@ -1294,6 +1294,8 @@ void g_type_add_class_private (GType class_type,
GLIB_AVAILABLE_IN_ALL
gpointer g_type_class_get_private (GTypeClass *klass,
GType private_type);
GLIB_AVAILABLE_IN_2_38
gint g_type_class_get_instance_private_offset (gpointer g_class);
GLIB_AVAILABLE_IN_2_34
void g_type_ensure (GType type);