docs: Move GValue documentation to Markdown

Helps: #3037
This commit is contained in:
Matthias Clasen 2023-10-09 23:17:55 +01:00 committed by Philip Withnall
parent e298f1a078
commit 4411023462
4 changed files with 110 additions and 116 deletions

View File

@ -45,6 +45,7 @@ content_files = [
"floating-refs.md", "floating-refs.md",
"boxed.md", "boxed.md",
"enum-types.md", "enum-types.md",
"gvalue.md",
] ]
content_images = [ content_images = [
] ]

View File

@ -0,0 +1,108 @@
Title: Generic value container
# Generic value container
The [`struct@GObject.Value`] structure is basically a variable container
that consists of a type identifier and a specific value of that type. The
type identifier within a `GValue` structure always determines the type of the
associated value.
To create an undefined `GValue` structure, simply create a zero-filled
GValue structure. To initialize the `GValue`, use the
[`method@GObject.Value.init`] function. A `GValue` cannot be used until it
is initialized.
Once you have finished using a `GValue`, you must call
[`method@GObject.Value.unset`] to ensure that all the resources associated
with the `GValue` are freed.
The basic type operations (such as freeing and copying) are determined by
the [`struct@GObject.TypeValueTable`] associated with the type ID stored in
the `GValue`. Other `GValue` operations (such as converting values between
types) are provided by this interface.
The code in the example program below demonstrates `GValue`'s features:
```c
#include <glib-object.h>
static void
int2string (const GValue *src_value,
GValue *dest_value)
{
if (g_value_get_int (src_value) == 42)
g_value_set_static_string (dest_value, "An important number");
else
g_value_set_static_string (dest_value, "What's that?");
}
int
main (int argc,
char *argv[])
{
// GValues must be initialized
GValue a = G_VALUE_INIT;
GValue b = G_VALUE_INIT;
const char *message;
// The GValue starts empty
g_assert (!G_VALUE_HOLDS_STRING (&a));
// Put a string in it
g_value_init (&a, G_TYPE_STRING);
g_assert (G_VALUE_HOLDS_STRING (&a));
g_value_set_static_string (&a, "Hello, world!");
g_printf ("%s\n", g_value_get_string (&a));
// Reset it to its pristine state
g_value_unset (&a);
// It can then be reused for another type
g_value_init (&a, G_TYPE_INT);
g_value_set_int (&a, 42);
// Attempt to transform it into a GValue of type STRING
g_value_init (&b, G_TYPE_STRING);
// An INT is transformable to a STRING
g_assert (g_value_type_transformable (G_TYPE_INT, G_TYPE_STRING));
g_value_transform (&a, &b);
g_printf ("%s\n", g_value_get_string (&b));
// Attempt to transform it again using a custom transform function
g_value_register_transform_func (G_TYPE_INT, G_TYPE_STRING, int2string);
g_value_transform (&a, &b);
g_printf ("%s\n", g_value_get_string (&b));
g_value_unset (&b);
g_value_unset (&a);
return 0;
}
```
For letting a `GValue` own (and memory manage) arbitrary types or pointers,
they need to become a [boxed type](boxed.html). The example below shows how
the pointer `mystruct` of type `MyStruct` is used as a [boxed type](boxed.html).
```c
typedef struct { ... } MyStruct;
G_DEFINE_BOXED_TYPE (MyStruct, my_struct, my_struct_copy, my_struct_free)
// These two lines normally go in a public header. By GObject convention,
// the naming scheme is NAMESPACE_TYPE_NAME:
#define MY_TYPE_STRUCT (my_struct_get_type ())
GType my_struct_get_type (void);
void
foo (void)
{
GValue *value = g_new0 (GValue, 1);
g_value_init (value, MY_TYPE_STRUCT);
g_value_set_boxed (value, mystruct);
// [... your code ....]
g_value_unset (value);
g_free (value);
}
```

View File

@ -74,6 +74,7 @@ expand_content_files = [
'boxed.md', 'boxed.md',
'enum-types.md', 'enum-types.md',
'floating-refs.md', 'floating-refs.md',
'gvalue.md',
] ]
gobject_gir = meson.current_source_dir() / 'GObject-2.0.gir' gobject_gir = meson.current_source_dir() / 'GObject-2.0.gir'

View File

@ -31,122 +31,6 @@
#include "gtype-private.h" #include "gtype-private.h"
/**
* SECTION:generic_values
* @short_description: A polymorphic type that can hold values of any
* other type
* @see_also: The fundamental types which all support #GValue
* operations and thus can be used as a type initializer for
* g_value_init() are defined by a separate interface. See the
* [standard values API][gobject-Standard-Parameter-and-Value-Types]
* for details
* @title: Generic values
*
* The #GValue structure is basically a variable container that consists
* of a type identifier and a specific value of that type.
*
* The type identifier within a #GValue structure always determines the
* type of the associated value.
*
* To create an undefined #GValue structure, simply create a zero-filled
* #GValue structure. To initialize the #GValue, use the g_value_init()
* function. A #GValue cannot be used until it is initialized. Before
* destruction you must always use g_value_unset() to make sure allocated
* memory is freed.
*
* The basic type operations (such as freeing and copying) are determined
* by the #GTypeValueTable associated with the type ID stored in the #GValue.
* Other #GValue operations (such as converting values between types) are
* provided by this interface.
*
* The code in the example program below demonstrates #GValue's
* features.
*
* |[<!-- language="C" -->
* #include <glib-object.h>
*
* static void
* int2string (const GValue *src_value,
* GValue *dest_value)
* {
* if (g_value_get_int (src_value) == 42)
* g_value_set_static_string (dest_value, "An important number");
* else
* g_value_set_static_string (dest_value, "What's that?");
* }
*
* int
* main (int argc,
* char *argv[])
* {
* // GValues must be initialized
* GValue a = G_VALUE_INIT;
* GValue b = G_VALUE_INIT;
* const gchar *message;
*
* // The GValue starts empty
* g_assert (!G_VALUE_HOLDS_STRING (&a));
*
* // Put a string in it
* g_value_init (&a, G_TYPE_STRING);
* g_assert (G_VALUE_HOLDS_STRING (&a));
* g_value_set_static_string (&a, "Hello, world!");
* g_printf ("%s\n", g_value_get_string (&a));
*
* // Reset it to its pristine state
* g_value_unset (&a);
*
* // It can then be reused for another type
* g_value_init (&a, G_TYPE_INT);
* g_value_set_int (&a, 42);
*
* // Attempt to transform it into a GValue of type STRING
* g_value_init (&b, G_TYPE_STRING);
*
* // An INT is transformable to a STRING
* g_assert (g_value_type_transformable (G_TYPE_INT, G_TYPE_STRING));
*
* g_value_transform (&a, &b);
* g_printf ("%s\n", g_value_get_string (&b));
*
* // Attempt to transform it again using a custom transform function
* g_value_register_transform_func (G_TYPE_INT, G_TYPE_STRING, int2string);
* g_value_transform (&a, &b);
* g_printf ("%s\n", g_value_get_string (&b));
* return 0;
* }
* ]|
*
* See also [gobject-Standard-Parameter-and-Value-Types] for more information on
* validation of #GValue.
*
* For letting a #GValue own (and memory manage) arbitrary types or pointers,
* they need to become a [boxed type][gboxed]. The example below shows how
* the pointer `mystruct` of type `MyStruct` is used as a [boxed type][gboxed].
*
* |[<!-- language="C" -->
* typedef struct { ... } MyStruct;
* G_DEFINE_BOXED_TYPE (MyStruct, my_struct, my_struct_copy, my_struct_free)
*
* // These two lines normally go in a public header. By GObject convention,
* // the naming scheme is NAMESPACE_TYPE_NAME:
* #define MY_TYPE_STRUCT (my_struct_get_type ())
* GType my_struct_get_type (void);
*
* void
* foo ()
* {
* GValue *value = g_new0 (GValue, 1);
* g_value_init (value, MY_TYPE_STRUCT);
* g_value_set_boxed (value, mystruct);
* // [... your code ....]
* g_value_unset (value);
* g_free (value);
* }
* ]|
*/
/* --- typedefs & structures --- */ /* --- typedefs & structures --- */
typedef struct { typedef struct {
GType src_type; GType src_type;