Mercurial > hg > octave-shane > gnulib-hg
annotate lib/gl_array_oset.c @ 7304:1c4ed7637c24
Include <config.h> unconditionally.
author | Bruno Haible <bruno@clisp.org> |
---|---|
date | Thu, 14 Sep 2006 14:18:36 +0000 |
parents | c77399b5682d |
children | 3d5bd6899004 |
rev | line source |
---|---|
6976
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
1 /* Ordered set data type implemented by an array. |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
2 Copyright (C) 2006 Free Software Foundation, Inc. |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
3 Written by Bruno Haible <bruno@clisp.org>, 2006. |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
4 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
5 This program is free software; you can redistribute it and/or modify |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
6 it under the terms of the GNU General Public License as published by |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
7 the Free Software Foundation; either version 2, or (at your option) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
8 any later version. |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
9 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
10 This program is distributed in the hope that it will be useful, |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
11 but WITHOUT ANY WARRANTY; without even the implied warranty of |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
13 GNU General Public License for more details. |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
14 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
15 You should have received a copy of the GNU General Public License |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
16 along with this program; if not, write to the Free Software Foundation, |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
18 |
7304
1c4ed7637c24
Include <config.h> unconditionally.
Bruno Haible <bruno@clisp.org>
parents:
6976
diff
changeset
|
19 #include <config.h> |
6976
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
20 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
21 /* Specification. */ |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
22 #include "gl_array_oset.h" |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
23 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
24 #include <stdlib.h> |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
25 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
26 #include "xalloc.h" |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
27 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
28 /* Checked size_t computations. */ |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
29 #include "xsize.h" |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
30 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
31 /* -------------------------- gl_oset_t Data Type -------------------------- */ |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
32 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
33 /* Concrete gl_oset_impl type, valid for this file only. */ |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
34 struct gl_oset_impl |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
35 { |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
36 struct gl_oset_impl_base base; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
37 /* An array of ALLOCATED elements, of which the first COUNT are used. |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
38 0 <= COUNT <= ALLOCATED. */ |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
39 const void **elements; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
40 size_t count; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
41 size_t allocated; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
42 }; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
43 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
44 static gl_oset_t |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
45 gl_array_create_empty (gl_oset_implementation_t implementation, |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
46 gl_setelement_compar_fn compar_fn) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
47 { |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
48 struct gl_oset_impl *set = |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
49 (struct gl_oset_impl *) xmalloc (sizeof (struct gl_oset_impl)); |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
50 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
51 set->base.vtable = implementation; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
52 set->base.compar_fn = compar_fn; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
53 set->elements = NULL; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
54 set->count = 0; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
55 set->allocated = 0; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
56 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
57 return set; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
58 } |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
59 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
60 static size_t |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
61 gl_array_size (gl_oset_t set) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
62 { |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
63 return set->count; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
64 } |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
65 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
66 static size_t |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
67 gl_array_indexof (gl_oset_t set, const void *elt) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
68 { |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
69 size_t count = set->count; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
70 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
71 if (count > 0) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
72 { |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
73 gl_setelement_compar_fn compar = set->base.compar_fn; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
74 size_t low = 0; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
75 size_t high = count; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
76 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
77 /* At each loop iteration, low < high; for indices < low the values |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
78 are smaller than ELT; for indices >= high the values are greater |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
79 than ELT. So, if the element occurs in the list, is at |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
80 low <= position < high. */ |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
81 do |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
82 { |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
83 size_t mid = low + (high - low) / 2; /* low <= mid < high */ |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
84 int cmp = (compar != NULL |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
85 ? compar (set->elements[mid], elt) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
86 : (set->elements[mid] > elt ? 1 : |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
87 set->elements[mid] < elt ? -1 : 0)); |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
88 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
89 if (cmp < 0) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
90 low = mid + 1; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
91 else if (cmp > 0) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
92 high = mid; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
93 else /* cmp == 0 */ |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
94 /* We have an element equal to ELT at index MID. */ |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
95 return mid; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
96 } |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
97 while (low < high); |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
98 } |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
99 return (size_t)(-1); |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
100 } |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
101 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
102 static bool |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
103 gl_array_search (gl_oset_t set, const void *elt) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
104 { |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
105 return gl_array_indexof (set, elt) != (size_t)(-1); |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
106 } |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
107 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
108 /* Ensure that set->allocated > set->count. */ |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
109 static void |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
110 grow (gl_oset_t set) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
111 { |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
112 size_t new_allocated; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
113 size_t memory_size; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
114 const void **memory; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
115 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
116 new_allocated = xtimes (set->allocated, 2); |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
117 new_allocated = xsum (new_allocated, 1); |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
118 memory_size = xtimes (new_allocated, sizeof (const void *)); |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
119 if (size_overflow_p (memory_size)) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
120 /* Overflow, would lead to out of memory. */ |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
121 xalloc_die (); |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
122 memory = (const void **) xrealloc (set->elements, memory_size); |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
123 if (memory == NULL) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
124 /* Out of memory. */ |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
125 xalloc_die (); |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
126 set->elements = memory; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
127 set->allocated = new_allocated; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
128 } |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
129 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
130 /* Add the given element ELT at the given position, |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
131 0 <= position <= gl_oset_size (set). */ |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
132 static inline void |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
133 gl_array_add_at (gl_oset_t set, size_t position, const void *elt) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
134 { |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
135 size_t count = set->count; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
136 const void **elements; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
137 size_t i; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
138 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
139 if (count == set->allocated) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
140 grow (set); |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
141 elements = set->elements; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
142 for (i = count; i > position; i--) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
143 elements[i] = elements[i - 1]; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
144 elements[position] = elt; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
145 set->count = count + 1; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
146 } |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
147 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
148 /* Remove the element at the given position, |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
149 0 <= position < gl_oset_size (set). */ |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
150 static inline void |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
151 gl_array_remove_at (gl_oset_t set, size_t position) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
152 { |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
153 size_t count = set->count; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
154 const void **elements; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
155 size_t i; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
156 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
157 elements = set->elements; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
158 for (i = position + 1; i < count; i++) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
159 elements[i - 1] = elements[i]; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
160 set->count = count - 1; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
161 } |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
162 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
163 static bool |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
164 gl_array_add (gl_oset_t set, const void *elt) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
165 { |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
166 size_t count = set->count; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
167 size_t low = 0; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
168 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
169 if (count > 0) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
170 { |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
171 gl_setelement_compar_fn compar = set->base.compar_fn; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
172 size_t high = count; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
173 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
174 /* At each loop iteration, low < high; for indices < low the values |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
175 are smaller than ELT; for indices >= high the values are greater |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
176 than ELT. So, if the element occurs in the list, is at |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
177 low <= position < high. */ |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
178 do |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
179 { |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
180 size_t mid = low + (high - low) / 2; /* low <= mid < high */ |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
181 int cmp = (compar != NULL |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
182 ? compar (set->elements[mid], elt) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
183 : (set->elements[mid] > elt ? 1 : |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
184 set->elements[mid] < elt ? -1 : 0)); |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
185 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
186 if (cmp < 0) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
187 low = mid + 1; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
188 else if (cmp > 0) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
189 high = mid; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
190 else /* cmp == 0 */ |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
191 return false; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
192 } |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
193 while (low < high); |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
194 } |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
195 gl_array_add_at (set, low, elt); |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
196 return true; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
197 } |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
198 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
199 static bool |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
200 gl_array_remove (gl_oset_t set, const void *elt) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
201 { |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
202 size_t index = gl_array_indexof (set, elt); |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
203 if (index != (size_t)(-1)) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
204 { |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
205 gl_array_remove_at (set, index); |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
206 return true; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
207 } |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
208 else |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
209 return false; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
210 } |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
211 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
212 static void |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
213 gl_array_free (gl_oset_t set) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
214 { |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
215 if (set->elements != NULL) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
216 free (set->elements); |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
217 free (set); |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
218 } |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
219 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
220 /* --------------------- gl_oset_iterator_t Data Type --------------------- */ |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
221 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
222 static gl_oset_iterator_t |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
223 gl_array_iterator (gl_oset_t set) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
224 { |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
225 gl_oset_iterator_t result; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
226 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
227 result.vtable = set->base.vtable; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
228 result.set = set; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
229 result.count = set->count; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
230 result.p = set->elements + 0; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
231 result.q = set->elements + set->count; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
232 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
233 return result; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
234 } |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
235 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
236 static bool |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
237 gl_array_iterator_next (gl_oset_iterator_t *iterator, const void **eltp) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
238 { |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
239 gl_oset_t set = iterator->set; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
240 if (iterator->count != set->count) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
241 { |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
242 if (iterator->count != set->count + 1) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
243 /* Concurrent modifications were done on the set. */ |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
244 abort (); |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
245 /* The last returned element was removed. */ |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
246 iterator->count--; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
247 iterator->p--; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
248 iterator->q--; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
249 } |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
250 if (iterator->p < iterator->q) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
251 { |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
252 const void **p = (const void **) iterator->p; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
253 *eltp = *p; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
254 iterator->p = p + 1; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
255 return true; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
256 } |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
257 else |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
258 return false; |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
259 } |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
260 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
261 static void |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
262 gl_array_iterator_free (gl_oset_iterator_t *iterator) |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
263 { |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
264 } |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
265 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
266 |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
267 const struct gl_oset_implementation gl_array_oset_implementation = |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
268 { |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
269 gl_array_create_empty, |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
270 gl_array_size, |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
271 gl_array_search, |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
272 gl_array_add, |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
273 gl_array_remove, |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
274 gl_array_free, |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
275 gl_array_iterator, |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
276 gl_array_iterator_next, |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
277 gl_array_iterator_free |
c77399b5682d
Ordered set data type implemented by an array.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
278 }; |