src/iterator.c

Sun, 23 Nov 2025 13:15:19 +0100

author
Mike Becker <universe@uap-core.de>
date
Sun, 23 Nov 2025 13:15:19 +0100
changeset 1508
dfc0ddd9571e
parent 1429
6e0c3a8a914a
permissions
-rw-r--r--

optimize sorted insertion by using the infimum instead of the supremum

The reason is that the supremum returns the equal element with the smallest index, and we want the largest.
Therefore, we use the infimum, which already gives us the largest index when there are equal elements, and increase the index by one. The infimum is also guaranteed to exist in that case.

850
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
1 /*
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
3 *
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
4 * Copyright 2024 Mike Becker, Olaf Wintermann All rights reserved.
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
5 *
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
6 * Redistribution and use in source and binary forms, with or without
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
7 * modification, are permitted provided that the following conditions are met:
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
8 *
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
9 * 1. Redistributions of source code must retain the above copyright
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
10 * notice, this list of conditions and the following disclaimer.
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
11 *
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
12 * 2. Redistributions in binary form must reproduce the above copyright
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
13 * notice, this list of conditions and the following disclaimer in the
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
14 * documentation and/or other materials provided with the distribution.
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
15 *
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
26 * POSSIBILITY OF SUCH DAMAGE.
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
27 */
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
28
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
29 #include "cx/iterator.h"
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
30
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
31 #include <string.h>
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
32
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 854
diff changeset
33 static bool cx_iter_valid(const void *it) {
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 854
diff changeset
34 const struct cx_iterator_s *iter = it;
850
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
35 return iter->index < iter->elem_count;
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
36 }
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
37
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 854
diff changeset
38 static void *cx_iter_current(const void *it) {
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 854
diff changeset
39 const struct cx_iterator_s *iter = it;
850
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
40 return iter->elem_handle;
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
41 }
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
42
1070
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
43 static void *cx_iter_current_ptr(const void *it) {
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
44 const struct cx_iterator_s *iter = it;
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
45 return *(void**)iter->elem_handle;
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
46 }
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
47
850
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
48 static void cx_iter_next_fast(void *it) {
853
d4baf4dd55c3 simplify iterator structures
Mike Becker <universe@uap-core.de>
parents: 851
diff changeset
49 struct cx_iterator_s *iter = it;
854
fe0d69d72bcd fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents: 853
diff changeset
50 if (iter->base.remove) {
fe0d69d72bcd fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents: 853
diff changeset
51 iter->base.remove = false;
850
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
52 iter->elem_count--;
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
53 // only move the last element when we are not currently aiming
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
54 // at the last element already
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
55 if (iter->index < iter->elem_count) {
1429
6e0c3a8a914a remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents: 1070
diff changeset
56 void *last = ((char *) iter->src_handle)
850
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
57 + iter->elem_count * iter->elem_size;
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
58 memcpy(iter->elem_handle, last, iter->elem_size);
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
59 }
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
60 } else {
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
61 iter->index++;
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
62 iter->elem_handle = ((char *) iter->elem_handle) + iter->elem_size;
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
63 }
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
64 }
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
65
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
66 static void cx_iter_next_slow(void *it) {
853
d4baf4dd55c3 simplify iterator structures
Mike Becker <universe@uap-core.de>
parents: 851
diff changeset
67 struct cx_iterator_s *iter = it;
854
fe0d69d72bcd fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents: 853
diff changeset
68 if (iter->base.remove) {
fe0d69d72bcd fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents: 853
diff changeset
69 iter->base.remove = false;
850
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
70 iter->elem_count--;
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
71
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
72 // number of elements to move
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
73 size_t remaining = iter->elem_count - iter->index;
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
74 if (remaining > 0) {
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
75 memmove(
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
76 iter->elem_handle,
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
77 ((char *) iter->elem_handle) + iter->elem_size,
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
78 remaining * iter->elem_size
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
79 );
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
80 }
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
81 } else {
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
82 iter->index++;
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
83 iter->elem_handle = ((char *) iter->elem_handle) + iter->elem_size;
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
84 }
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
85 }
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
86
1429
6e0c3a8a914a remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents: 1070
diff changeset
87 CxIterator cxIterator(
6e0c3a8a914a remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents: 1070
diff changeset
88 const void *array,
850
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
89 size_t elem_size,
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
90 size_t elem_count,
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
91 bool remove_keeps_order
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
92 ) {
853
d4baf4dd55c3 simplify iterator structures
Mike Becker <universe@uap-core.de>
parents: 851
diff changeset
93 CxIterator iter;
850
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
94
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
95 iter.index = 0;
1429
6e0c3a8a914a remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents: 1070
diff changeset
96 iter.src_handle = (void*) array;
6e0c3a8a914a remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents: 1070
diff changeset
97 iter.elem_handle = (void*) array;
850
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
98 iter.elem_size = elem_size;
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
99 iter.elem_count = array == NULL ? 0 : elem_count;
854
fe0d69d72bcd fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents: 853
diff changeset
100 iter.base.valid = cx_iter_valid;
fe0d69d72bcd fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents: 853
diff changeset
101 iter.base.current = cx_iter_current;
fe0d69d72bcd fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents: 853
diff changeset
102 iter.base.next = remove_keeps_order ? cx_iter_next_slow : cx_iter_next_fast;
fe0d69d72bcd fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents: 853
diff changeset
103 iter.base.remove = false;
1429
6e0c3a8a914a remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents: 1070
diff changeset
104 iter.base.allow_remove = true;
851
adb4e0737c33 issue #389 : add separate function for immutable arrays
Mike Becker <universe@uap-core.de>
parents: 850
diff changeset
105
1070
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
106 return iter;
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
107 }
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
108
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
109 CxIterator cxIteratorPtr(
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
110 const void *array,
1429
6e0c3a8a914a remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents: 1070
diff changeset
111 size_t elem_count,
6e0c3a8a914a remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents: 1070
diff changeset
112 bool remove_keeps_order
1070
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
113 ) {
1429
6e0c3a8a914a remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents: 1070
diff changeset
114 CxIterator iter = cxIterator(array, sizeof(void*), elem_count, remove_keeps_order);
6e0c3a8a914a remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents: 1070
diff changeset
115 iter.base.current = cx_iter_current_ptr;
1070
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
116 return iter;
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
117 }

mercurial