summaryrefslogtreecommitdiff
path: root/gobject
diff options
context:
space:
mode:
authorRyan Lortie <desrt@desrt.ca>2013-04-23 10:38:23 -0400
committerRyan Lortie <desrt@desrt.ca>2013-04-23 14:39:09 -0400
commitc30c0bb34d80013489897c49bef36cc56972d5d9 (patch)
tree115ff297d5b8c9b70a3295e60e146869b07187e0 /gobject
parenteb860fd898a6a2bd86c11d245294cd0e8cd4304b (diff)
downloadglib-c30c0bb34d80013489897c49bef36cc56972d5d9.tar.gz
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
Diffstat (limited to 'gobject')
-rw-r--r--gobject/gtype.c48
-rw-r--r--gobject/gtype.h2
2 files changed, 50 insertions, 0 deletions
diff --git a/gobject/gtype.c b/gobject/gtype.c
index c3f4374b1..6cd8ac46b 100644
--- a/gobject/gtype.c
+++ b/gobject/gtype.c
@@ -4529,6 +4529,54 @@ g_type_instance_get_private (GTypeInstance *instance,
}
/**
+ * 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.
* @private_size: size of private structure.
diff --git a/gobject/gtype.h b/gobject/gtype.h
index f6f6f9338..a0a57f03e 100644
--- a/gobject/gtype.h
+++ b/gobject/gtype.h
@@ -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);