2010-11-21 00:46:25 -08:00
|
|
|
#ifndef MOO_ARRAY_H
|
|
|
|
#define MOO_ARRAY_H
|
|
|
|
|
|
|
|
#include <mooutils/mooutils-mem.h>
|
2010-12-12 02:29:20 -08:00
|
|
|
#include <glib-object.h>
|
2010-11-21 00:46:25 -08:00
|
|
|
|
2010-12-12 02:29:20 -08:00
|
|
|
#define MOO_DECLARE_PTR_ARRAY_FULL(ArrayType, array_type, ElmType) \
|
2010-11-21 00:46:25 -08:00
|
|
|
\
|
|
|
|
typedef struct ArrayType ArrayType; \
|
2010-11-23 21:54:39 -08:00
|
|
|
\
|
2010-11-21 00:46:25 -08:00
|
|
|
struct ArrayType { \
|
|
|
|
MOO_IP_ARRAY_ELMS (ElmType*, elms); \
|
|
|
|
}; \
|
|
|
|
\
|
2010-11-23 21:54:39 -08:00
|
|
|
ArrayType *array_type##_new (void); \
|
|
|
|
void array_type##_free (ArrayType *ar); \
|
|
|
|
void array_type##_append (ArrayType *ar, ElmType *elm); \
|
|
|
|
void array_type##_take (ArrayType *ar, ElmType *elm); \
|
|
|
|
void array_type##_append_array (ArrayType *ar, ArrayType *ar2); \
|
|
|
|
ArrayType *array_type##_copy (ArrayType *ar); \
|
|
|
|
\
|
|
|
|
typedef void (*ArrayType##Foreach) (ElmType *elm, \
|
|
|
|
gpointer data); \
|
|
|
|
\
|
2013-04-20 22:14:56 -07:00
|
|
|
G_INLINE_FUNC void \
|
2010-11-23 21:54:39 -08:00
|
|
|
array_type##_foreach (const ArrayType *ar, \
|
|
|
|
ArrayType##Foreach func, \
|
|
|
|
gpointer data) \
|
|
|
|
{ \
|
|
|
|
guint i; \
|
|
|
|
g_return_if_fail (ar != NULL && func != NULL); \
|
|
|
|
for (i = 0; i < ar->n_elms; ++i) \
|
|
|
|
func (ar->elms[i], data); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
void array_type##_sort (ArrayType *ar, GCompareFunc func); \
|
|
|
|
int array_type##_find (const ArrayType *ar, ElmType *elm); \
|
|
|
|
void array_type##_remove (ArrayType *ar, ElmType *elm); \
|
2011-01-17 01:13:11 -08:00
|
|
|
void array_type##_clear (ArrayType *ar); \
|
2010-11-23 21:54:39 -08:00
|
|
|
guint array_type##_insert_sorted (ArrayType *ar, ElmType *elm, \
|
|
|
|
GCompareFunc func); \
|
|
|
|
\
|
2013-04-20 22:14:56 -07:00
|
|
|
G_INLINE_FUNC gboolean array_type##_is_empty (ArrayType *ar) \
|
2010-11-23 21:54:39 -08:00
|
|
|
{ \
|
|
|
|
return !ar || !ar->n_elms; \
|
|
|
|
} \
|
|
|
|
\
|
2013-04-20 22:14:56 -07:00
|
|
|
G_INLINE_FUNC gsize array_type##_get_size (ArrayType *ar) \
|
2010-11-23 21:54:39 -08:00
|
|
|
{ \
|
|
|
|
return ar ? ar->n_elms : 0; \
|
|
|
|
}
|
|
|
|
|
2010-12-12 02:29:20 -08:00
|
|
|
#define MOO_DECLARE_PTR_ARRAY(Element, element) \
|
|
|
|
MOO_DECLARE_PTR_ARRAY_FULL(Element##Array, element##_array, Element)
|
|
|
|
|
|
|
|
#define MOO_DEFINE_PTR_ARRAY_FULL(ArrayType, array_type, ElmType, \
|
|
|
|
copy_elm, free_elm) \
|
2010-11-23 21:54:39 -08:00
|
|
|
\
|
|
|
|
ArrayType * \
|
2010-11-21 00:46:25 -08:00
|
|
|
array_type##_new (void) \
|
|
|
|
{ \
|
|
|
|
ArrayType *ar = g_slice_new0 (ArrayType); \
|
2010-11-23 21:54:39 -08:00
|
|
|
MOO_IP_ARRAY_INIT (ElmType*, ar, elms, 0); \
|
2010-11-21 00:46:25 -08:00
|
|
|
return ar; \
|
|
|
|
} \
|
|
|
|
\
|
2010-11-23 21:54:39 -08:00
|
|
|
void \
|
2010-11-21 00:46:25 -08:00
|
|
|
array_type##_free (ArrayType *ar) \
|
|
|
|
{ \
|
|
|
|
if (ar) \
|
|
|
|
{ \
|
|
|
|
gsize i; \
|
|
|
|
for (i = 0; i < ar->n_elms; ++i) \
|
|
|
|
free_elm (ar->elms[i]); \
|
|
|
|
MOO_IP_ARRAY_DESTROY (ar, elms); \
|
|
|
|
g_slice_free (ArrayType, ar); \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
\
|
2010-11-23 21:54:39 -08:00
|
|
|
void \
|
2010-11-21 00:46:25 -08:00
|
|
|
array_type##_append (ArrayType *ar, ElmType *elm) \
|
|
|
|
{ \
|
|
|
|
g_return_if_fail (ar != NULL && elm != NULL); \
|
2010-11-23 21:54:39 -08:00
|
|
|
MOO_IP_ARRAY_GROW (ElmType*, ar, elms, 1); \
|
2010-11-21 00:46:25 -08:00
|
|
|
ar->elms[ar->n_elms - 1] = copy_elm (elm); \
|
|
|
|
} \
|
|
|
|
\
|
2010-11-23 21:54:39 -08:00
|
|
|
void array_type##_append_array (ArrayType *ar, ArrayType *ar2) \
|
|
|
|
{ \
|
|
|
|
guint i, old_size; \
|
|
|
|
g_return_if_fail (ar != NULL && ar2 != NULL); \
|
|
|
|
if (!ar2->n_elms) \
|
|
|
|
return; \
|
|
|
|
old_size = ar->n_elms; \
|
|
|
|
MOO_IP_ARRAY_GROW (ElmType*, ar, elms, ar2->n_elms); \
|
|
|
|
for (i = 0; i < ar2->n_elms; ++i) \
|
|
|
|
ar->elms[old_size + i] = copy_elm (ar2->elms[i]); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
void \
|
2010-11-21 00:46:25 -08:00
|
|
|
array_type##_take (ArrayType *ar, ElmType *elm) \
|
|
|
|
{ \
|
|
|
|
g_return_if_fail (ar != NULL && elm != NULL); \
|
2010-11-23 21:54:39 -08:00
|
|
|
MOO_IP_ARRAY_GROW (ElmType*, ar, elms, 1); \
|
2010-11-21 00:46:25 -08:00
|
|
|
ar->elms[ar->n_elms - 1] = elm; \
|
|
|
|
} \
|
|
|
|
\
|
2010-11-23 21:54:39 -08:00
|
|
|
ArrayType * \
|
2010-11-21 00:46:25 -08:00
|
|
|
array_type##_copy (ArrayType *ar) \
|
|
|
|
{ \
|
|
|
|
ArrayType *copy; \
|
|
|
|
\
|
|
|
|
g_return_val_if_fail (ar != NULL, NULL); \
|
|
|
|
\
|
|
|
|
copy = array_type##_new (); \
|
|
|
|
\
|
|
|
|
if (ar->n_elms) \
|
|
|
|
{ \
|
|
|
|
guint i; \
|
2010-11-23 21:54:39 -08:00
|
|
|
MOO_IP_ARRAY_GROW (ElmType*, copy, elms, ar->n_elms); \
|
2010-11-21 00:46:25 -08:00
|
|
|
for (i = 0; i < ar->n_elms; ++i) \
|
|
|
|
copy->elms[i] = copy_elm (ar->elms[i]); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
return copy; \
|
|
|
|
} \
|
|
|
|
\
|
2010-11-23 21:54:39 -08:00
|
|
|
void array_type##_remove (ArrayType *ar, ElmType *elm) \
|
2010-11-21 00:46:25 -08:00
|
|
|
{ \
|
|
|
|
guint i; \
|
2010-11-23 21:54:39 -08:00
|
|
|
\
|
|
|
|
g_return_if_fail (ar != NULL); \
|
|
|
|
\
|
|
|
|
for (i = 0; i < ar->n_elms; ++i) \
|
|
|
|
{ \
|
|
|
|
if (ar->elms[i] == elm) \
|
|
|
|
{ \
|
|
|
|
MOO_IP_ARRAY_REMOVE_INDEX (ar, elms, i); \
|
|
|
|
free_elm (elm); \
|
|
|
|
return; \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
\
|
2011-01-17 01:13:11 -08:00
|
|
|
void array_type##_clear (ArrayType *ar) \
|
|
|
|
{ \
|
|
|
|
g_return_if_fail (ar != NULL); \
|
|
|
|
\
|
|
|
|
if (ar->n_elms) \
|
|
|
|
{ \
|
|
|
|
guint i; \
|
|
|
|
guint n_elms = ar->n_elms; \
|
|
|
|
ElmType **elms = ar->elms; \
|
|
|
|
MOO_IP_ARRAY_INIT (ElmType*, ar, elms, 0); \
|
|
|
|
\
|
|
|
|
for (i = 0; i < n_elms; ++i) \
|
|
|
|
free_elm (elms[i]); \
|
|
|
|
\
|
|
|
|
g_free (elms); \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
\
|
2010-11-23 21:54:39 -08:00
|
|
|
static int \
|
|
|
|
array_type##_gcompare_data_func (gconstpointer a, \
|
|
|
|
gconstpointer b, \
|
|
|
|
gpointer user_data) \
|
|
|
|
{ \
|
|
|
|
GCompareFunc func = (GCompareFunc) user_data; \
|
|
|
|
ElmType **ea = (ElmType **) a; \
|
|
|
|
ElmType **eb = (ElmType **) b; \
|
|
|
|
return func (*ea, *eb); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
void \
|
|
|
|
array_type##_sort (ArrayType *ar, GCompareFunc func) \
|
|
|
|
{ \
|
2010-11-21 00:46:25 -08:00
|
|
|
g_return_if_fail (ar != NULL && func != NULL); \
|
2010-11-23 21:54:39 -08:00
|
|
|
\
|
|
|
|
if (ar->n_elms <= 1) \
|
|
|
|
return; \
|
|
|
|
\
|
|
|
|
g_qsort_with_data (ar->elms, ar->n_elms, sizeof (*ar->elms), \
|
|
|
|
array_type##_gcompare_data_func, \
|
|
|
|
func); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
int array_type##_find (const ArrayType *ar, ElmType *elm) \
|
|
|
|
{ \
|
|
|
|
guint i; \
|
|
|
|
g_return_val_if_fail (ar != NULL && elm != NULL, -1); \
|
2010-11-21 00:46:25 -08:00
|
|
|
for (i = 0; i < ar->n_elms; ++i) \
|
2010-11-23 21:54:39 -08:00
|
|
|
if (ar->elms[i] == elm) \
|
|
|
|
return i; \
|
|
|
|
return -1; \
|
2010-11-21 00:46:25 -08:00
|
|
|
}
|
|
|
|
|
2010-12-12 02:29:20 -08:00
|
|
|
#define MOO_DEFINE_PTR_ARRAY_C(Element, element) \
|
|
|
|
MOO_DEFINE_PTR_ARRAY_FULL (Element##Array, element##_array, Element, element##_copy, element##_free)
|
|
|
|
|
|
|
|
#define MOO_DECLARE_OBJECT_ARRAY_FULL(ArrayType, array_type, ElmType) \
|
|
|
|
MOO_DECLARE_PTR_ARRAY_FULL (ArrayType, array_type, ElmType)
|
2010-11-21 00:46:25 -08:00
|
|
|
|
2010-12-12 02:29:20 -08:00
|
|
|
#define MOO_DECLARE_OBJECT_ARRAY(Element, element) \
|
|
|
|
MOO_DECLARE_OBJECT_ARRAY_FULL (Element##Array, element##_array, Element)
|
2010-11-21 00:46:25 -08:00
|
|
|
|
2010-12-12 02:29:20 -08:00
|
|
|
#define MOO_DEFINE_OBJECT_ARRAY_FULL(ArrayType, array_type, ElmType) \
|
2013-04-20 22:14:56 -07:00
|
|
|
G_INLINE_FUNC ElmType * \
|
2010-11-23 21:54:39 -08:00
|
|
|
array_type##_ref_elm__ (ElmType *elm) \
|
|
|
|
{ \
|
|
|
|
return (ElmType*) g_object_ref (elm); \
|
|
|
|
} \
|
2010-11-21 00:46:25 -08:00
|
|
|
\
|
2013-04-20 22:14:56 -07:00
|
|
|
G_INLINE_FUNC void \
|
2010-11-23 21:54:39 -08:00
|
|
|
array_type##_unref_elm__ (ElmType *elm) \
|
|
|
|
{ \
|
|
|
|
g_object_unref (elm); \
|
|
|
|
} \
|
2010-11-21 00:46:25 -08:00
|
|
|
\
|
2010-12-12 02:29:20 -08:00
|
|
|
MOO_DEFINE_PTR_ARRAY_FULL (ArrayType, array_type, ElmType, \
|
|
|
|
array_type##_ref_elm__, \
|
|
|
|
array_type##_unref_elm__)
|
|
|
|
|
|
|
|
#define MOO_DEFINE_OBJECT_ARRAY(Element, element) \
|
|
|
|
MOO_DEFINE_OBJECT_ARRAY_FULL (Element##Array, element##_array, Element)
|
|
|
|
|
|
|
|
G_BEGIN_DECLS
|
|
|
|
|
|
|
|
MOO_DECLARE_OBJECT_ARRAY_FULL (MooObjectArray, moo_object_array, GObject)
|
|
|
|
MOO_DECLARE_PTR_ARRAY_FULL (MooPtrArray, moo_ptr_array, gpointer)
|
2010-11-21 00:46:25 -08:00
|
|
|
|
2010-12-12 02:29:20 -08:00
|
|
|
G_END_DECLS
|
2010-12-09 01:39:15 -08:00
|
|
|
|
2010-11-21 00:46:25 -08:00
|
|
|
#endif /* MOO_ARRAY_H */
|