mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-23 18:52:09 +01:00
arraylist: add g_array_list_move()
This function will do a more optimzed move of an item within the list than its equivelent, g_array_list_remove() and g_array_list_prepend().
This commit is contained in:
parent
dad8c25e9d
commit
4232c04655
@ -644,3 +644,51 @@ g_array_list_copy_reversed (GArrayList *self,
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_array_list_move:
|
||||
* @self: A #GListArray
|
||||
* @src: the index of the item to move
|
||||
* @dest: the new index to place the item.
|
||||
*
|
||||
* This function is analagous to calling g_array_list_remove_index() followed
|
||||
* by g_array_list_insert() but allows for avoiding the need to copy the item
|
||||
* as well as re-build the linked list twice.
|
||||
*/
|
||||
void
|
||||
g_array_list_move (GArrayList *self,
|
||||
gsize src,
|
||||
gsize dest)
|
||||
{
|
||||
GArrayListAny *any = (GArrayListAny *)self;
|
||||
GArrayListEmbed *embed = (GArrayListEmbed *)self;
|
||||
GArrayListAlloc *alloc = (GArrayListAlloc *)self;
|
||||
GList *items;
|
||||
gpointer src_data;
|
||||
gsize i;
|
||||
|
||||
g_return_if_fail (self != NULL);
|
||||
g_return_if_fail (src < any->len);
|
||||
g_return_if_fail (dest < any->len);
|
||||
|
||||
if (src == dest)
|
||||
return;
|
||||
|
||||
items = (any->mode == MODE_EMBED) ? embed->items : alloc->items;
|
||||
|
||||
src_data = items [src].data;
|
||||
|
||||
if (dest < src)
|
||||
{
|
||||
for (i = src; i > dest; i--)
|
||||
items [i].data = items [i - 1].data;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = src; i < dest; i++)
|
||||
items [i].data = items [i + 1].data;
|
||||
}
|
||||
|
||||
items [dest].data = src_data;
|
||||
_g_array_list_update_pointers (items, any->len);
|
||||
}
|
||||
|
@ -95,6 +95,11 @@ gpointer *g_array_list_copy_reversed(GArrayList *list,
|
||||
GCopyFunc copy_func,
|
||||
gpointer copy_data);
|
||||
|
||||
GLIB_AVAILABLE_IN_2_46
|
||||
void g_array_list_move (GArrayList *list,
|
||||
gsize src,
|
||||
gsize dest);
|
||||
|
||||
#define g_array_list_empty(list) ((list)->len == 0)
|
||||
#define g_array_list_first(list) (((list)->len == 0) ? NULL : g_array_list_index((list),0))
|
||||
#define g_array_list_last(list) (((list)->len == 0) ? NULL : g_array_list_index((list),(list)->len-1))
|
||||
|
@ -76,13 +76,23 @@ test_basic (GArrayList *al)
|
||||
|
||||
g_assert_cmpint (al->len, ==, 500);
|
||||
g_assert_cmpint (test_basic_counter, ==, 500);
|
||||
g_assert_cmpint (GPOINTER_TO_SIZE (g_array_list_last (al)), ==, 1000);
|
||||
|
||||
g_array_list_prepend (al, GSIZE_TO_POINTER (191919));
|
||||
g_assert_cmpint (GPOINTER_TO_SIZE (g_array_list_index (al, 0)), ==, 191919);
|
||||
g_assert_cmpint (GPOINTER_TO_SIZE (g_array_list_last (al)), ==, 1000);
|
||||
|
||||
g_array_list_move (al, 0, al->len - 1);
|
||||
g_assert_cmpint (GPOINTER_TO_SIZE (g_array_list_index (al, 0)), ==, 501);
|
||||
g_assert_cmpint (GPOINTER_TO_SIZE (g_array_list_last (al)), ==, 191919);
|
||||
|
||||
g_array_list_move (al, al->len - 1, 0);
|
||||
g_assert_cmpint (GPOINTER_TO_SIZE (g_array_list_index (al, 0)), ==, 191919);
|
||||
g_assert_cmpint (GPOINTER_TO_SIZE (g_array_list_last (al)), ==, 1000);
|
||||
|
||||
g_array_list_clear (al);
|
||||
g_assert_cmpint (al->len, ==, 0);
|
||||
g_assert_cmpint (test_basic_counter, ==, 1000);
|
||||
g_assert_cmpint (test_basic_counter, ==, 1001);
|
||||
|
||||
g_array_list_destroy (al);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user