src/iterator.c

Fri, 23 May 2025 12:44:24 +0200

author
Mike Becker <universe@uap-core.de>
date
Fri, 23 May 2025 12:44:24 +0200
changeset 1327
ed75dc1db503
parent 1070
0a5a356a4486
permissions
-rw-r--r--

make test-compile depend on both static and shared

the shared lib is not needed for the tests,
but when run with coverage, gcov will be confused
when outdated line information is available from
a previous shared build

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) {
853
d4baf4dd55c3 simplify iterator structures
Mike Becker <universe@uap-core.de>
parents: 851
diff changeset
56 void *last = ((char *) iter->src_handle.m)
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
853
d4baf4dd55c3 simplify iterator structures
Mike Becker <universe@uap-core.de>
parents: 851
diff changeset
87 CxIterator cxMutIterator(
850
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
88 void *array,
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;
853
d4baf4dd55c3 simplify iterator structures
Mike Becker <universe@uap-core.de>
parents: 851
diff changeset
96 iter.src_handle.m = array;
850
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
97 iter.elem_handle = array;
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;
fe0d69d72bcd fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents: 853
diff changeset
104 iter.base.mutating = true;
850
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
105
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
106 return iter;
b2bc48c2b251 add iterator over raw C arrays - closes #389
Mike Becker <universe@uap-core.de>
parents:
diff changeset
107 }
851
adb4e0737c33 issue #389 : add separate function for immutable arrays
Mike Becker <universe@uap-core.de>
parents: 850
diff changeset
108
adb4e0737c33 issue #389 : add separate function for immutable arrays
Mike Becker <universe@uap-core.de>
parents: 850
diff changeset
109 CxIterator cxIterator(
890
54565fd74e74 move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents: 854
diff changeset
110 const void *array,
851
adb4e0737c33 issue #389 : add separate function for immutable arrays
Mike Becker <universe@uap-core.de>
parents: 850
diff changeset
111 size_t elem_size,
adb4e0737c33 issue #389 : add separate function for immutable arrays
Mike Becker <universe@uap-core.de>
parents: 850
diff changeset
112 size_t elem_count
adb4e0737c33 issue #389 : add separate function for immutable arrays
Mike Becker <universe@uap-core.de>
parents: 850
diff changeset
113 ) {
853
d4baf4dd55c3 simplify iterator structures
Mike Becker <universe@uap-core.de>
parents: 851
diff changeset
114 CxIterator iter = cxMutIterator((void*)array, elem_size, elem_count, false);
854
fe0d69d72bcd fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents: 853
diff changeset
115 iter.base.mutating = false;
853
d4baf4dd55c3 simplify iterator structures
Mike Becker <universe@uap-core.de>
parents: 851
diff changeset
116 return iter;
851
adb4e0737c33 issue #389 : add separate function for immutable arrays
Mike Becker <universe@uap-core.de>
parents: 850
diff changeset
117 }
1070
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
118
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
119 CxIterator cxMutIteratorPtr(
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
120 void *array,
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
121 size_t elem_count,
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
122 bool remove_keeps_order
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
123 ) {
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
124 CxIterator iter = cxMutIterator(array, sizeof(void*), elem_count, remove_keeps_order);
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
125 iter.base.current = cx_iter_current_ptr;
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
126 return iter;
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
127 }
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
128
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
129 CxIterator cxIteratorPtr(
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
130 const void *array,
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
131 size_t elem_count
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
132 ) {
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
133 CxIterator iter = cxMutIteratorPtr((void*) array, elem_count, false);
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
134 iter.base.mutating = false;
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
135 return iter;
0a5a356a4486 add array iterator over pointer arrays
Mike Becker <universe@uap-core.de>
parents: 890
diff changeset
136 }

mercurial