From e062ed7a99ca4e88a93db19362800a3326a462ea Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Fri, 16 Mar 2007 00:30:06 +0000 Subject: [PATCH] Allow the use of a destructor for the values stored in the list. --- ChangeLog | 44 ++++++++++++++++++++++++++++ NEWS | 4 +++ lib/clean-temp.c | 9 ++++-- lib/gl_anyavltree_list2.h | 6 +++- lib/gl_anylinked_list2.h | 13 ++++++++- lib/gl_anyrbtree_list2.h | 6 +++- lib/gl_anytree_list2.h | 6 +++- lib/gl_anytreehash_list2.h | 4 ++- lib/gl_array_list.c | 28 ++++++++++++++++-- lib/gl_carray_list.c | 67 +++++++++++++++++++++++++++++++++++++------ lib/gl_list.c | 8 ++++-- lib/gl_list.h | 19 ++++++++++-- lib/gl_sublist.c | 5 +++- tests/test-array_list.c | 4 +-- tests/test-array_oset.c | 2 +- tests/test-avltree_list.c | 6 ++-- tests/test-avltreehash_list.c | 6 ++-- tests/test-carray_list.c | 6 ++-- tests/test-linked_list.c | 6 ++-- tests/test-linkedhash_list.c | 6 ++-- tests/test-rbtree_list.c | 6 ++-- tests/test-rbtreehash_list.c | 6 ++-- 22 files changed, 217 insertions(+), 50 deletions(-) diff --git a/ChangeLog b/ChangeLog index 61e31fa1c..523a19cc3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,49 @@ 2007-03-15 Bruno Haible + * lib/gl_list.h (gl_listelement_dispose_fn): New type. + (gl_list_create_empty, gl_list_create): Add dispose_fn argument. + (struct gl_list_implementation): Add dispose_fn argument to the + 'create_empty', 'create' methods. + (struct gl_list_impl_base): Add field 'dispose_fn'. + * lib/gl_list.c (gl_list_create_empty, gl_list_create): Add dispose_fn + argument. + * lib/gl_array_list.c (gl_array_create_empty, gl_array_create): Add + dispose_fn argument. + (gl_array_remove_node, gl_array_remove_at, gl_array_list_free): Call + dispose_fn on the dropped values. + * lib/gl_carray_list.c (gl_carray_create_empty, gl_carray_create): Add + dispose_fn argument. + (gl_carray_remove_at, gl_carray_list_free): Call dispose_fn on the + dropped values. + * lib/gl_anyavltree_list2.h (gl_tree_create): Add dispose_fn argument. + (gl_tree_remove_node): Call dispose_fn on the dropped value. + * lib/gl_anyrbtree_list2.h (gl_tree_create): Add dispose_fn argument. + (gl_tree_remove_node): Call dispose_fn on the dropped value. + * lib/gl_anytree_list2.h (gl_tree_create_empty): Add dispose_fn + argument. + (gl_tree_list_free): Call dispose_fn on the dropped values. + * lib/gl_anytreehash_list2.h (gl_tree_list_free): Call dispose_fn on + the dropped values. + * lib/gl_anylinked_list2.h (gl_linked_create_empty, gl_linked_create): + Add dispose_fn argument. + (gl_linked_remove_node, gl_linked_remove_at, gl_linked_list_free): + Call dispose_fn on the dropped values. + * lib/gl_sublist.c (gl_sublist_create_empty, gl_sublist_create_fill): + Add dispose_fn argument. + (gl_sublist_create): Initialize the 'dispose_fn' field. + * lib/clean-temp.c (create_temp_dir, register_fd): Update. + * tests/test-array_list.c (main): Update. + * tests/test-carray_list.c (main): Update. + * tests/test-avltree_list.c (main): Update. + * tests/test-rbtree_list.c (main): Update. + * tests/test-avltreehash_list.c (main): Update. + * tests/test-rbtreehash_list.c (main): Update. + * tests/test-linked_list.c (main): Update. + * tests/test-linkedhash_list.c (main): Update. + * tests/test-array_oset.c (main): Update. + +2007-03-15 Bruno Haible + * lib/gl_oset.h (gl_setelement_dispose_fn): New type. (gl_oset_create_empty): Add dispose_fn argument. (struct gl_oset_implementation): Add dispose_fn argument to diff --git a/NEWS b/NEWS index e9bbe8d3d..5aa7375b6 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,10 @@ User visible incompatible changes Date Modules Changes +2007-03-15 list The functions gl_list_create_empty and + gl_list_create now take an extra fourth argument. + You can pass NULL. + 2007-03-15 oset The function gl_oset_create_empty now takes a array-oset third argument. You can pass NULL. avltree-oset diff --git a/lib/clean-temp.c b/lib/clean-temp.c index 823a93267..c84063610 100644 --- a/lib/clean-temp.c +++ b/lib/clean-temp.c @@ -320,9 +320,11 @@ create_temp_dir (const char *prefix, const char *parentdir, tmpdir->dirname = NULL; tmpdir->cleanup_verbose = cleanup_verbose; tmpdir->subdirs = gl_list_create_empty (GL_LINKEDHASH_LIST, - string_equals, string_hash, false); + string_equals, string_hash, NULL, + false); tmpdir->files = gl_list_create_empty (GL_LINKEDHASH_LIST, - string_equals, string_hash, false); + string_equals, string_hash, NULL, + false); /* Create the temporary directory. */ xtemplate = (char *) xallocsa (PATH_MAX); @@ -599,7 +601,8 @@ static void register_fd (int fd) { if (descriptors == NULL) - descriptors = gl_list_create_empty (GL_LINKEDHASH_LIST, NULL, NULL, false); + descriptors = gl_list_create_empty (GL_LINKEDHASH_LIST, NULL, NULL, NULL, + false); gl_list_add_first (descriptors, (void *) (uintptr_t) fd); } diff --git a/lib/gl_anyavltree_list2.h b/lib/gl_anyavltree_list2.h index 5a73158b8..6a838e65b 100644 --- a/lib/gl_anyavltree_list2.h +++ b/lib/gl_anyavltree_list2.h @@ -1,5 +1,5 @@ /* Sequential list data type implemented by a binary tree. - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006-2007 Free Software Foundation, Inc. Written by Bruno Haible , 2006. This program is free software; you can redistribute it and/or modify @@ -63,6 +63,7 @@ static gl_list_t gl_tree_create (gl_list_implementation_t implementation, gl_listelement_equals_fn equals_fn, gl_listelement_hashcode_fn hashcode_fn, + gl_listelement_dispose_fn dispose_fn, bool allow_duplicates, size_t count, const void **contents) { @@ -71,6 +72,7 @@ gl_tree_create (gl_list_implementation_t implementation, list->base.vtable = implementation; list->base.equals_fn = equals_fn; list->base.hashcode_fn = hashcode_fn; + list->base.dispose_fn = dispose_fn; list->base.allow_duplicates = allow_duplicates; #if WITH_HASHTABLE { @@ -738,6 +740,8 @@ gl_tree_remove_node (gl_list_t list, gl_list_node_t node) rebalance (list, child, -1, subst_parent != node ? subst_parent : subst); } + if (list->base.dispose_fn != NULL) + list->base.dispose_fn (node->value); free (node); return true; } diff --git a/lib/gl_anylinked_list2.h b/lib/gl_anylinked_list2.h index 718dfb713..8b264d7fa 100644 --- a/lib/gl_anylinked_list2.h +++ b/lib/gl_anylinked_list2.h @@ -1,5 +1,5 @@ /* Sequential list data type implemented by a linked list. - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006-2007 Free Software Foundation, Inc. Written by Bruno Haible , 2006. This program is free software; you can redistribute it and/or modify @@ -41,6 +41,7 @@ static gl_list_t gl_linked_create_empty (gl_list_implementation_t implementation, gl_listelement_equals_fn equals_fn, gl_listelement_hashcode_fn hashcode_fn, + gl_listelement_dispose_fn dispose_fn, bool allow_duplicates) { struct gl_list_impl *list = XMALLOC (struct gl_list_impl); @@ -48,6 +49,7 @@ gl_linked_create_empty (gl_list_implementation_t implementation, list->base.vtable = implementation; list->base.equals_fn = equals_fn; list->base.hashcode_fn = hashcode_fn; + list->base.dispose_fn = dispose_fn; list->base.allow_duplicates = allow_duplicates; #if WITH_HASHTABLE list->table_size = 11; @@ -64,6 +66,7 @@ static gl_list_t gl_linked_create (gl_list_implementation_t implementation, gl_listelement_equals_fn equals_fn, gl_listelement_hashcode_fn hashcode_fn, + gl_listelement_dispose_fn dispose_fn, bool allow_duplicates, size_t count, const void **contents) { @@ -73,6 +76,7 @@ gl_linked_create (gl_list_implementation_t implementation, list->base.vtable = implementation; list->base.equals_fn = equals_fn; list->base.hashcode_fn = hashcode_fn; + list->base.dispose_fn = dispose_fn; list->base.allow_duplicates = allow_duplicates; #if WITH_HASHTABLE { @@ -684,6 +688,8 @@ gl_linked_remove_node (gl_list_t list, gl_list_node_t node) next->prev = prev; list->count--; + if (list->base.dispose_fn != NULL) + list->base.dispose_fn (node->value); free (node); return true; } @@ -730,6 +736,8 @@ gl_linked_remove_at (gl_list_t list, size_t position) #endif list->count--; + if (list->base.dispose_fn != NULL) + list->base.dispose_fn (removed_node->value); free (removed_node); return true; } @@ -748,11 +756,14 @@ gl_linked_remove (gl_list_t list, const void *elt) static void gl_linked_list_free (gl_list_t list) { + gl_listelement_dispose_fn dispose = list->base.dispose_fn; gl_list_node_t node; for (node = list->root.next; node != &list->root; ) { gl_list_node_t next = node->next; + if (dispose != NULL) + dispose (node->value); free (node); node = next; } diff --git a/lib/gl_anyrbtree_list2.h b/lib/gl_anyrbtree_list2.h index 7ede9a65a..6d1e6b092 100644 --- a/lib/gl_anyrbtree_list2.h +++ b/lib/gl_anyrbtree_list2.h @@ -1,5 +1,5 @@ /* Sequential list data type implemented by a binary tree. - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006-2007 Free Software Foundation, Inc. Written by Bruno Haible , 2006. This program is free software; you can redistribute it and/or modify @@ -68,6 +68,7 @@ static gl_list_t gl_tree_create (gl_list_implementation_t implementation, gl_listelement_equals_fn equals_fn, gl_listelement_hashcode_fn hashcode_fn, + gl_listelement_dispose_fn dispose_fn, bool allow_duplicates, size_t count, const void **contents) { @@ -76,6 +77,7 @@ gl_tree_create (gl_list_implementation_t implementation, list->base.vtable = implementation; list->base.equals_fn = equals_fn; list->base.hashcode_fn = hashcode_fn; + list->base.dispose_fn = dispose_fn; list->base.allow_duplicates = allow_duplicates; #if WITH_HASHTABLE { @@ -959,6 +961,8 @@ gl_tree_remove_node (gl_list_t list, gl_list_node_t node) } } + if (list->base.dispose_fn != NULL) + list->base.dispose_fn (node->value); free (node); return true; } diff --git a/lib/gl_anytree_list2.h b/lib/gl_anytree_list2.h index fba2845fa..81d2a18cf 100644 --- a/lib/gl_anytree_list2.h +++ b/lib/gl_anytree_list2.h @@ -1,5 +1,5 @@ /* Sequential list data type implemented by a binary tree. - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006-2007 Free Software Foundation, Inc. Written by Bruno Haible , 2006. This program is free software; you can redistribute it and/or modify @@ -23,6 +23,7 @@ static gl_list_t gl_tree_create_empty (gl_list_implementation_t implementation, gl_listelement_equals_fn equals_fn, gl_listelement_hashcode_fn hashcode_fn, + gl_listelement_dispose_fn dispose_fn, bool allow_duplicates) { struct gl_list_impl *list = XMALLOC (struct gl_list_impl); @@ -30,6 +31,7 @@ gl_tree_create_empty (gl_list_implementation_t implementation, list->base.vtable = implementation; list->base.equals_fn = equals_fn; list->base.hashcode_fn = hashcode_fn; + list->base.dispose_fn = dispose_fn; list->base.allow_duplicates = allow_duplicates; #if WITH_HASHTABLE list->table_size = 11; @@ -457,6 +459,8 @@ gl_tree_list_free (gl_list_t list) if (!stack_ptr->rightp) break; /* Free the current node. */ + if (list->base.dispose_fn != NULL) + list->base.dispose_fn (node->value); free (node); } /* Descend on right branch. */ diff --git a/lib/gl_anytreehash_list2.h b/lib/gl_anytreehash_list2.h index f69f98399..89cdb068c 100644 --- a/lib/gl_anytreehash_list2.h +++ b/lib/gl_anytreehash_list2.h @@ -1,5 +1,5 @@ /* Sequential list data type implemented by a hash table with a binary tree. - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006-2007 Free Software Foundation, Inc. Written by Bruno Haible , 2006. This program is free software; you can redistribute it and/or modify @@ -198,6 +198,8 @@ gl_tree_list_free (gl_list_t list) if (!stack_ptr->rightp) break; /* Free the current node. */ + if (list->base.dispose_fn != NULL) + list->base.dispose_fn (node->value); free (node); } /* Descend on right branch. */ diff --git a/lib/gl_array_list.c b/lib/gl_array_list.c index 9537b1fb5..661cf79c4 100644 --- a/lib/gl_array_list.c +++ b/lib/gl_array_list.c @@ -1,5 +1,5 @@ /* Sequential list data type implemented by an array. - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006-2007 Free Software Foundation, Inc. Written by Bruno Haible , 2006. This program is free software; you can redistribute it and/or modify @@ -56,6 +56,7 @@ static gl_list_t gl_array_create_empty (gl_list_implementation_t implementation, gl_listelement_equals_fn equals_fn, gl_listelement_hashcode_fn hashcode_fn, + gl_listelement_dispose_fn dispose_fn, bool allow_duplicates) { struct gl_list_impl *list = XMALLOC (struct gl_list_impl); @@ -63,6 +64,7 @@ gl_array_create_empty (gl_list_implementation_t implementation, list->base.vtable = implementation; list->base.equals_fn = equals_fn; list->base.hashcode_fn = hashcode_fn; + list->base.dispose_fn = dispose_fn; list->base.allow_duplicates = allow_duplicates; list->elements = NULL; list->count = 0; @@ -75,6 +77,7 @@ static gl_list_t gl_array_create (gl_list_implementation_t implementation, gl_listelement_equals_fn equals_fn, gl_listelement_hashcode_fn hashcode_fn, + gl_listelement_dispose_fn dispose_fn, bool allow_duplicates, size_t count, const void **contents) { @@ -83,6 +86,7 @@ gl_array_create (gl_list_implementation_t implementation, list->base.vtable = implementation; list->base.equals_fn = equals_fn; list->base.hashcode_fn = hashcode_fn; + list->base.dispose_fn = dispose_fn; list->base.allow_duplicates = allow_duplicates; if (count > 0) { @@ -345,6 +349,8 @@ gl_array_remove_node (gl_list_t list, gl_list_node_t node) abort (); position = index; elements = list->elements; + if (list->base.dispose_fn != NULL) + list->base.dispose_fn (elements[position]); for (i = position + 1; i < count; i++) elements[i - 1] = elements[i]; list->count = count - 1; @@ -362,6 +368,8 @@ gl_array_remove_at (gl_list_t list, size_t position) /* Invalid argument. */ abort (); elements = list->elements; + if (list->base.dispose_fn != NULL) + list->base.dispose_fn (elements[position]); for (i = position + 1; i < count; i++) elements[i - 1] = elements[i]; list->count = count - 1; @@ -382,7 +390,23 @@ static void gl_array_list_free (gl_list_t list) { if (list->elements != NULL) - free (list->elements); + { + if (list->base.dispose_fn != NULL) + { + size_t count = list->count; + + if (count > 0) + { + gl_listelement_dispose_fn dispose = list->base.dispose_fn; + const void **elements = list->elements; + + do + dispose (*elements++); + while (--count > 0); + } + } + free (list->elements); + } free (list); } diff --git a/lib/gl_carray_list.c b/lib/gl_carray_list.c index 7630c2a72..90113e030 100644 --- a/lib/gl_carray_list.c +++ b/lib/gl_carray_list.c @@ -1,5 +1,5 @@ /* Sequential list data type implemented by a circular array. - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006-2007 Free Software Foundation, Inc. Written by Bruno Haible , 2006. This program is free software; you can redistribute it and/or modify @@ -57,15 +57,17 @@ struct gl_list_impl static gl_list_t gl_carray_create_empty (gl_list_implementation_t implementation, - gl_listelement_equals_fn equals_fn, - gl_listelement_hashcode_fn hashcode_fn, - bool allow_duplicates) + gl_listelement_equals_fn equals_fn, + gl_listelement_hashcode_fn hashcode_fn, + gl_listelement_dispose_fn dispose_fn, + bool allow_duplicates) { struct gl_list_impl *list = XMALLOC (struct gl_list_impl); list->base.vtable = implementation; list->base.equals_fn = equals_fn; list->base.hashcode_fn = hashcode_fn; + list->base.dispose_fn = dispose_fn; list->base.allow_duplicates = allow_duplicates; list->elements = NULL; list->offset = 0; @@ -77,16 +79,18 @@ gl_carray_create_empty (gl_list_implementation_t implementation, static gl_list_t gl_carray_create (gl_list_implementation_t implementation, - gl_listelement_equals_fn equals_fn, - gl_listelement_hashcode_fn hashcode_fn, - bool allow_duplicates, - size_t count, const void **contents) + gl_listelement_equals_fn equals_fn, + gl_listelement_hashcode_fn hashcode_fn, + gl_listelement_dispose_fn dispose_fn, + bool allow_duplicates, + size_t count, const void **contents) { struct gl_list_impl *list = XMALLOC (struct gl_list_impl); list->base.vtable = implementation; list->base.equals_fn = equals_fn; list->base.hashcode_fn = hashcode_fn; + list->base.dispose_fn = dispose_fn; list->base.allow_duplicates = allow_duplicates; if (count > 0) { @@ -448,6 +452,8 @@ gl_carray_remove_at (gl_list_t list, size_t position) /* Here we must have list->offset > 0, hence list->allocated > 0. */ size_t i1 = list->allocated - 1; i2 -= list->allocated; + if (list->base.dispose_fn != NULL) + list->base.dispose_fn (elements[i2]); for (i = i2; i > 0; i--) elements[i] = elements[i - 1]; elements[0] = elements[i1]; @@ -456,6 +462,8 @@ gl_carray_remove_at (gl_list_t list, size_t position) } else { + if (list->base.dispose_fn != NULL) + list->base.dispose_fn (elements[i2]); for (i = i2; i > i0; i--) elements[i] = elements[i - 1]; } @@ -474,6 +482,8 @@ gl_carray_remove_at (gl_list_t list, size_t position) { i1 -= list->allocated; i3 -= list->allocated; + if (list->base.dispose_fn != NULL) + list->base.dispose_fn (elements[i1]); for (i = i1; i < i3; i++) elements[i] = elements[i + 1]; } @@ -482,6 +492,8 @@ gl_carray_remove_at (gl_list_t list, size_t position) /* Here we must have list->offset > 0, hence list->allocated > 0. */ size_t i2 = list->allocated - 1; i3 -= list->allocated; + if (list->base.dispose_fn != NULL) + list->base.dispose_fn (elements[i1]); for (i = i1; i < i2; i++) elements[i] = elements[i + 1]; elements[i2] = elements[0]; @@ -490,6 +502,8 @@ gl_carray_remove_at (gl_list_t list, size_t position) } else { + if (list->base.dispose_fn != NULL) + list->base.dispose_fn (elements[i1]); for (i = i1; i < i3; i++) elements[i] = elements[i + 1]; } @@ -524,7 +538,42 @@ static void gl_carray_list_free (gl_list_t list) { if (list->elements != NULL) - free (list->elements); + { + if (list->base.dispose_fn != NULL) + { + size_t count = list->count; + + if (count > 0) + { + gl_listelement_dispose_fn dispose = list->base.dispose_fn; + const void **elements = list->elements; + size_t i1 = list->offset; + size_t i3 = list->offset + count - 1; + + if (i3 >= list->allocated) + { + /* Here we must have list->offset > 0, hence + list->allocated > 0. */ + size_t i2 = list->allocated - 1; + size_t i; + + i3 -= list->allocated; + for (i = i1; i <= i2; i++) + dispose (elements[i]); + for (i = 0; i <= i3; i++) + dispose (elements[i]); + } + else + { + size_t i; + + for (i = i1; i <= i3; i++) + dispose (elements[i]); + } + } + } + free (list->elements); + } free (list); } diff --git a/lib/gl_list.c b/lib/gl_list.c index cbc765a94..80a1bbe3b 100644 --- a/lib/gl_list.c +++ b/lib/gl_list.c @@ -1,5 +1,5 @@ /* Abstract sequential list data type. - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006-2007 Free Software Foundation, Inc. Written by Bruno Haible , 2006. This program is free software; you can redistribute it and/or modify @@ -31,21 +31,23 @@ gl_list_t gl_list_create_empty (gl_list_implementation_t implementation, gl_listelement_equals_fn equals_fn, gl_listelement_hashcode_fn hashcode_fn, + gl_listelement_dispose_fn dispose_fn, bool allow_duplicates) { return implementation->create_empty (implementation, equals_fn, hashcode_fn, - allow_duplicates); + dispose_fn, allow_duplicates); } gl_list_t gl_list_create (gl_list_implementation_t implementation, gl_listelement_equals_fn equals_fn, gl_listelement_hashcode_fn hashcode_fn, + gl_listelement_dispose_fn dispose_fn, bool allow_duplicates, size_t count, const void **contents) { return implementation->create (implementation, equals_fn, hashcode_fn, - allow_duplicates, count, contents); + dispose_fn, allow_duplicates, count, contents); } size_t diff --git a/lib/gl_list.h b/lib/gl_list.h index b97a6a42a..e58fc3bcd 100644 --- a/lib/gl_list.h +++ b/lib/gl_list.h @@ -1,5 +1,5 @@ /* Abstract sequential list data type. - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006-2007 Free Software Foundation, Inc. Written by Bruno Haible , 2006. This program is free software; you can redistribute it and/or modify @@ -102,6 +102,10 @@ typedef bool (*gl_listelement_equals_fn) (const void *elt1, const void *elt2); NULL denotes a function that depends only on the pointer itself. */ typedef size_t (*gl_listelement_hashcode_fn) (const void *elt); +/* Type of function used to dispose an element once it's removed from a list. + NULL denotes a no-op. */ +typedef void (*gl_listelement_dispose_fn) (const void *elt); + struct gl_list_impl; /* Type representing an entire list. */ typedef struct gl_list_impl * gl_list_t; @@ -122,11 +126,13 @@ typedef const struct gl_list_implementation * gl_list_implementation_t; GL_RBTREEHASH_LIST. EQUALS_FN is an element comparison function or NULL. HASHCODE_FN is an element hash code function or NULL. + DISPOSE_FN is an element disposal function or NULL. ALLOW_DUPLICATES is false if duplicate elements shall not be allowed in the list. The implementation may verify this at runtime. */ extern gl_list_t gl_list_create_empty (gl_list_implementation_t implementation, gl_listelement_equals_fn equals_fn, gl_listelement_hashcode_fn hashcode_fn, + gl_listelement_dispose_fn dispose_fn, bool allow_duplicates); /* Create a list with given contents. @@ -135,6 +141,7 @@ extern gl_list_t gl_list_create_empty (gl_list_implementation_t implementation, GL_RBTREEHASH_LIST. EQUALS_FN is an element comparison function or NULL. HASHCODE_FN is an element hash code function or NULL. + DISPOSE_FN is an element disposal function or NULL. ALLOW_DUPLICATES is false if duplicate elements shall not be allowed in the list. The implementation may verify this at runtime. COUNT is the number of initial elements. @@ -142,6 +149,7 @@ extern gl_list_t gl_list_create_empty (gl_list_implementation_t implementation, extern gl_list_t gl_list_create (gl_list_implementation_t implementation, gl_listelement_equals_fn equals_fn, gl_listelement_hashcode_fn hashcode_fn, + gl_listelement_dispose_fn dispose_fn, bool allow_duplicates, size_t count, const void **contents); @@ -364,10 +372,12 @@ struct gl_list_implementation gl_list_t (*create_empty) (gl_list_implementation_t implementation, gl_listelement_equals_fn equals_fn, gl_listelement_hashcode_fn hashcode_fn, + gl_listelement_dispose_fn dispose_fn, bool allow_duplicates); gl_list_t (*create) (gl_list_implementation_t implementation, gl_listelement_equals_fn equals_fn, gl_listelement_hashcode_fn hashcode_fn, + gl_listelement_dispose_fn dispose_fn, bool allow_duplicates, size_t count, const void **contents); size_t (*size) (gl_list_t list); @@ -429,6 +439,7 @@ struct gl_list_impl_base const struct gl_list_implementation *vtable; gl_listelement_equals_fn equals_fn; gl_listelement_hashcode_fn hashcode_fn; + gl_listelement_dispose_fn dispose_fn; bool allow_duplicates; }; @@ -443,10 +454,11 @@ static inline gl_list_t gl_list_create_empty (gl_list_implementation_t implementation, gl_listelement_equals_fn equals_fn, gl_listelement_hashcode_fn hashcode_fn, + gl_listelement_dispose_fn dispose_fn, bool allow_duplicates) { return implementation->create_empty (implementation, equals_fn, hashcode_fn, - allow_duplicates); + dispose_fn, allow_duplicates); } # define gl_list_create gl_list_create_inline @@ -454,11 +466,12 @@ static inline gl_list_t gl_list_create (gl_list_implementation_t implementation, gl_listelement_equals_fn equals_fn, gl_listelement_hashcode_fn hashcode_fn, + gl_listelement_dispose_fn dispose_fn, bool allow_duplicates, size_t count, const void **contents) { return implementation->create (implementation, equals_fn, hashcode_fn, - allow_duplicates, count, contents); + dispose_fn, allow_duplicates, count, contents); } # define gl_list_size gl_list_size_inline diff --git a/lib/gl_sublist.c b/lib/gl_sublist.c index 87eb6e121..da7099beb 100644 --- a/lib/gl_sublist.c +++ b/lib/gl_sublist.c @@ -1,5 +1,5 @@ /* Sequential list data type backed by another list. - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006-2007 Free Software Foundation, Inc. Written by Bruno Haible , 2006. This program is free software; you can redistribute it and/or modify @@ -53,6 +53,7 @@ static gl_list_t gl_sublist_create_empty (gl_list_implementation_t implementation, gl_listelement_equals_fn equals_fn, gl_listelement_hashcode_fn hashcode_fn, + gl_listelement_dispose_fn dispose_fn, bool allow_duplicates) { /* Shouldn't be called. */ @@ -63,6 +64,7 @@ static gl_list_t gl_sublist_create_fill (gl_list_implementation_t implementation, gl_listelement_equals_fn equals_fn, gl_listelement_hashcode_fn hashcode_fn, + gl_listelement_dispose_fn dispose_fn, bool allow_duplicates, size_t count, const void **contents) { @@ -435,6 +437,7 @@ gl_sublist_create (gl_list_t whole_list, size_t start_index, size_t end_index) list->base.vtable = &gl_sublist_list_implementation; list->base.equals_fn = whole_list->base.equals_fn; /* actually unused */ list->base.hashcode_fn = whole_list->base.hashcode_fn; /* actually unused */ + list->base.dispose_fn = whole_list->base.dispose_fn; /* actually unused */ list->base.allow_duplicates = whole_list->base.allow_duplicates; /* unused */ if (whole_list->base.vtable == &gl_sublist_list_implementation) { diff --git a/tests/test-array_list.c b/tests/test-array_list.c index 335456ebd..b9de7cef0 100644 --- a/tests/test-array_list.c +++ b/tests/test-array_list.c @@ -71,10 +71,10 @@ main (int argc, char *argv[]) contents[i] = RANDOM_OBJECT (); /* Create list1. */ - list1 = gl_list_create (GL_ARRAY_LIST, NULL, NULL, true, + list1 = gl_list_create (GL_ARRAY_LIST, NULL, NULL, NULL, true, initial_size, contents); /* Create list2. */ - list2 = gl_list_create_empty (GL_ARRAY_LIST, NULL, NULL, true); + list2 = gl_list_create_empty (GL_ARRAY_LIST, NULL, NULL, NULL, true); for (i = 0; i < initial_size; i++) gl_list_add_last (list2, contents[i]); diff --git a/tests/test-array_oset.c b/tests/test-array_oset.c index c114c86ca..646e90842 100644 --- a/tests/test-array_oset.c +++ b/tests/test-array_oset.c @@ -91,7 +91,7 @@ main (int argc, char *argv[]) set1 = gl_oset_create_empty (GL_ARRAY_OSET, (gl_setelement_compar_fn) strcmp, NULL); /* Create set2. */ - set2 = gl_list_create_empty (GL_ARRAY_LIST, NULL, NULL, false); + set2 = gl_list_create_empty (GL_ARRAY_LIST, NULL, NULL, NULL, false); check_all (set1, set2); diff --git a/tests/test-avltree_list.c b/tests/test-avltree_list.c index b8bd0df2f..af608cef8 100644 --- a/tests/test-avltree_list.c +++ b/tests/test-avltree_list.c @@ -81,15 +81,15 @@ main (int argc, char *argv[]) contents[i] = RANDOM_OBJECT (); /* Create list1. */ - list1 = gl_list_create (GL_ARRAY_LIST, NULL, NULL, true, + list1 = gl_list_create (GL_ARRAY_LIST, NULL, NULL, NULL, true, initial_size, contents); /* Create list2. */ - list2 = gl_list_create_empty (GL_AVLTREE_LIST, NULL, NULL, true); + list2 = gl_list_create_empty (GL_AVLTREE_LIST, NULL, NULL, NULL, true); for (i = 0; i < initial_size; i++) gl_list_add_last (list2, contents[i]); /* Create list3. */ - list3 = gl_list_create (GL_AVLTREE_LIST, NULL, NULL, true, + list3 = gl_list_create (GL_AVLTREE_LIST, NULL, NULL, NULL, true, initial_size, contents); check_all (list1, list2, list3); diff --git a/tests/test-avltreehash_list.c b/tests/test-avltreehash_list.c index 1d0fa49aa..f5ea12990 100644 --- a/tests/test-avltreehash_list.c +++ b/tests/test-avltreehash_list.c @@ -111,17 +111,17 @@ main (int argc, char *argv[]) /* Create list1. */ list1 = gl_list_create (GL_ARRAY_LIST, - string_equals, string_hash, true, + string_equals, string_hash, NULL, true, initial_size, contents); /* Create list2. */ list2 = gl_list_create_empty (GL_AVLTREEHASH_LIST, - string_equals, string_hash, true); + string_equals, string_hash, NULL, true); for (i = 0; i < initial_size; i++) gl_list_add_last (list2, contents[i]); /* Create list3. */ list3 = gl_list_create (GL_AVLTREEHASH_LIST, - string_equals, string_hash, true, + string_equals, string_hash, NULL, true, initial_size, contents); check_all (list1, list2, list3); diff --git a/tests/test-carray_list.c b/tests/test-carray_list.c index 6026cd063..4aeece932 100644 --- a/tests/test-carray_list.c +++ b/tests/test-carray_list.c @@ -79,15 +79,15 @@ main (int argc, char *argv[]) contents[i] = RANDOM_OBJECT (); /* Create list1. */ - list1 = gl_list_create (GL_ARRAY_LIST, NULL, NULL, true, + list1 = gl_list_create (GL_ARRAY_LIST, NULL, NULL, NULL, true, initial_size, contents); /* Create list2. */ - list2 = gl_list_create_empty (GL_CARRAY_LIST, NULL, NULL, true); + list2 = gl_list_create_empty (GL_CARRAY_LIST, NULL, NULL, NULL, true); for (i = 0; i < initial_size; i++) gl_list_add_last (list2, contents[i]); /* Create list3. */ - list3 = gl_list_create (GL_CARRAY_LIST, NULL, NULL, true, + list3 = gl_list_create (GL_CARRAY_LIST, NULL, NULL, NULL, true, initial_size, contents); check_all (list1, list2, list3); diff --git a/tests/test-linked_list.c b/tests/test-linked_list.c index bf5ed4b0b..059b2eef6 100644 --- a/tests/test-linked_list.c +++ b/tests/test-linked_list.c @@ -79,15 +79,15 @@ main (int argc, char *argv[]) contents[i] = RANDOM_OBJECT (); /* Create list1. */ - list1 = gl_list_create (GL_ARRAY_LIST, NULL, NULL, true, + list1 = gl_list_create (GL_ARRAY_LIST, NULL, NULL, NULL, true, initial_size, contents); /* Create list2. */ - list2 = gl_list_create_empty (GL_LINKED_LIST, NULL, NULL, true); + list2 = gl_list_create_empty (GL_LINKED_LIST, NULL, NULL, NULL, true); for (i = 0; i < initial_size; i++) gl_list_add_last (list2, contents[i]); /* Create list3. */ - list3 = gl_list_create (GL_LINKED_LIST, NULL, NULL, true, + list3 = gl_list_create (GL_LINKED_LIST, NULL, NULL, NULL, true, initial_size, contents); check_all (list1, list2, list3); diff --git a/tests/test-linkedhash_list.c b/tests/test-linkedhash_list.c index f368b58df..22b67b330 100644 --- a/tests/test-linkedhash_list.c +++ b/tests/test-linkedhash_list.c @@ -107,17 +107,17 @@ main (int argc, char *argv[]) /* Create list1. */ list1 = gl_list_create (GL_ARRAY_LIST, - string_equals, string_hash, true, + string_equals, string_hash, NULL, true, initial_size, contents); /* Create list2. */ list2 = gl_list_create_empty (GL_LINKEDHASH_LIST, - string_equals, string_hash, true); + string_equals, string_hash, NULL, true); for (i = 0; i < initial_size; i++) gl_list_add_last (list2, contents[i]); /* Create list3. */ list3 = gl_list_create (GL_LINKEDHASH_LIST, - string_equals, string_hash, true, + string_equals, string_hash, NULL, true, initial_size, contents); check_all (list1, list2, list3); diff --git a/tests/test-rbtree_list.c b/tests/test-rbtree_list.c index d07e9e46f..d6080c05e 100644 --- a/tests/test-rbtree_list.c +++ b/tests/test-rbtree_list.c @@ -83,15 +83,15 @@ main (int argc, char *argv[]) contents[i] = RANDOM_OBJECT (); /* Create list1. */ - list1 = gl_list_create (GL_ARRAY_LIST, NULL, NULL, true, + list1 = gl_list_create (GL_ARRAY_LIST, NULL, NULL, NULL, true, initial_size, contents); /* Create list2. */ - list2 = gl_list_create_empty (GL_RBTREE_LIST, NULL, NULL, true); + list2 = gl_list_create_empty (GL_RBTREE_LIST, NULL, NULL, NULL, true); for (i = 0; i < initial_size; i++) gl_list_add_last (list2, contents[i]); /* Create list3. */ - list3 = gl_list_create (GL_RBTREE_LIST, NULL, NULL, true, + list3 = gl_list_create (GL_RBTREE_LIST, NULL, NULL, NULL, true, initial_size, contents); check_all (list1, list2, list3); diff --git a/tests/test-rbtreehash_list.c b/tests/test-rbtreehash_list.c index 4d98451c7..7a0cf9665 100644 --- a/tests/test-rbtreehash_list.c +++ b/tests/test-rbtreehash_list.c @@ -111,17 +111,17 @@ main (int argc, char *argv[]) /* Create list1. */ list1 = gl_list_create (GL_ARRAY_LIST, - string_equals, string_hash, true, + string_equals, string_hash, NULL, true, initial_size, contents); /* Create list2. */ list2 = gl_list_create_empty (GL_RBTREEHASH_LIST, - string_equals, string_hash, true); + string_equals, string_hash, NULL, true); for (i = 0; i < initial_size; i++) gl_list_add_last (list2, contents[i]); /* Create list3. */ list3 = gl_list_create (GL_RBTREEHASH_LIST, - string_equals, string_hash, true, + string_equals, string_hash, NULL, true, initial_size, contents); check_all (list1, list2, list3); -- 2.11.0