Fri, 23 May 2025 12:44:24 +0200
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
606 | 1 | /* |
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. | |
3 | * | |
4 | * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved. | |
5 | * | |
6 | * Redistribution and use in source and binary forms, with or without | |
7 | * modification, are permitted provided that the following conditions are met: | |
8 | * | |
9 | * 1. Redistributions of source code must retain the above copyright | |
10 | * notice, this list of conditions and the following disclaimer. | |
11 | * | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | |
15 | * | |
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | |
20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
26 | * POSSIBILITY OF SUCH DAMAGE. | |
27 | */ | |
28 | ||
29 | #include "cx/array_list.h" | |
763
741a2040fa33
make cx_cmp_ptr default comparator for pointer lists - relates to #340
Mike Becker <universe@uap-core.de>
parents:
735
diff
changeset
|
30 | #include "cx/compare.h" |
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
31 | #include <assert.h> |
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
32 | #include <string.h> |
998
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
33 | #include <errno.h> |
606 | 34 | |
817
949908c97474
add cx_array_default_reallocator
Mike Becker <universe@uap-core.de>
parents:
807
diff
changeset
|
35 | // Default array reallocator |
949908c97474
add cx_array_default_reallocator
Mike Becker <universe@uap-core.de>
parents:
807
diff
changeset
|
36 | |
949908c97474
add cx_array_default_reallocator
Mike Becker <universe@uap-core.de>
parents:
807
diff
changeset
|
37 | static void *cx_array_default_realloc( |
949908c97474
add cx_array_default_reallocator
Mike Becker <universe@uap-core.de>
parents:
807
diff
changeset
|
38 | void *array, |
1322
7be10b57f658
fix critical memory overflow in the stack-based array reallocator
Mike Becker <universe@uap-core.de>
parents:
1319
diff
changeset
|
39 | cx_attr_unused size_t old_capacity, |
7be10b57f658
fix critical memory overflow in the stack-based array reallocator
Mike Becker <universe@uap-core.de>
parents:
1319
diff
changeset
|
40 | size_t new_capacity, |
817
949908c97474
add cx_array_default_reallocator
Mike Becker <universe@uap-core.de>
parents:
807
diff
changeset
|
41 | size_t elem_size, |
985
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
42 | cx_attr_unused CxArrayReallocator *alloc |
817
949908c97474
add cx_array_default_reallocator
Mike Becker <universe@uap-core.de>
parents:
807
diff
changeset
|
43 | ) { |
1040
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
44 | size_t n; |
1322
7be10b57f658
fix critical memory overflow in the stack-based array reallocator
Mike Becker <universe@uap-core.de>
parents:
1319
diff
changeset
|
45 | if (cx_szmul(new_capacity, elem_size, &n)) { |
1040
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
46 | errno = EOVERFLOW; |
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
47 | return NULL; |
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
48 | } |
1319
aa1f580f8f59
add convenience macros for using the default allocator - relates to #669
Mike Becker <universe@uap-core.de>
parents:
1318
diff
changeset
|
49 | return cxReallocDefault(array, n); |
817
949908c97474
add cx_array_default_reallocator
Mike Becker <universe@uap-core.de>
parents:
807
diff
changeset
|
50 | } |
949908c97474
add cx_array_default_reallocator
Mike Becker <universe@uap-core.de>
parents:
807
diff
changeset
|
51 | |
953
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
52 | CxArrayReallocator cx_array_default_reallocator_impl = { |
817
949908c97474
add cx_array_default_reallocator
Mike Becker <universe@uap-core.de>
parents:
807
diff
changeset
|
53 | cx_array_default_realloc, NULL, NULL, 0, 0 |
949908c97474
add cx_array_default_reallocator
Mike Becker <universe@uap-core.de>
parents:
807
diff
changeset
|
54 | }; |
949908c97474
add cx_array_default_reallocator
Mike Becker <universe@uap-core.de>
parents:
807
diff
changeset
|
55 | |
953
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
56 | CxArrayReallocator *cx_array_default_reallocator = &cx_array_default_reallocator_impl; |
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
57 | |
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
58 | // Stack-aware array reallocator |
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
59 | |
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
60 | static void *cx_array_advanced_realloc( |
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
61 | void *array, |
1322
7be10b57f658
fix critical memory overflow in the stack-based array reallocator
Mike Becker <universe@uap-core.de>
parents:
1319
diff
changeset
|
62 | size_t old_capacity, |
7be10b57f658
fix critical memory overflow in the stack-based array reallocator
Mike Becker <universe@uap-core.de>
parents:
1319
diff
changeset
|
63 | size_t new_capacity, |
953
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
64 | size_t elem_size, |
985
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
65 | cx_attr_unused CxArrayReallocator *alloc |
953
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
66 | ) { |
1040
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
67 | // check for overflow |
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
68 | size_t n; |
1322
7be10b57f658
fix critical memory overflow in the stack-based array reallocator
Mike Becker <universe@uap-core.de>
parents:
1319
diff
changeset
|
69 | if (cx_szmul(new_capacity, elem_size, &n)) { |
1040
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
70 | errno = EOVERFLOW; |
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
71 | return NULL; |
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
72 | } |
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
73 | |
953
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
74 | // retrieve the pointer to the actual allocator |
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
75 | const CxAllocator *al = alloc->ptr1; |
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
76 | |
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
77 | // check if the array is still located on the stack |
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
78 | void *newmem; |
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
79 | if (array == alloc->ptr2) { |
1040
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
80 | newmem = cxMalloc(al, n); |
995
d3d4f245b843
fix cx_array_advanced_realloc to handle reallocation of NULL arrays, consistent with standard realloc behavior
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
986
diff
changeset
|
81 | if (newmem != NULL && array != NULL) { |
1322
7be10b57f658
fix critical memory overflow in the stack-based array reallocator
Mike Becker <universe@uap-core.de>
parents:
1319
diff
changeset
|
82 | memcpy(newmem, array, old_capacity*elem_size); |
953
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
83 | } |
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
84 | } else { |
1040
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
85 | newmem = cxRealloc(al, array, n); |
953
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
86 | } |
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
87 | return newmem; |
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
88 | } |
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
89 | |
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
90 | struct cx_array_reallocator_s cx_array_reallocator( |
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
91 | const struct cx_allocator_s *allocator, |
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
92 | const void *stackmem |
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
93 | ) { |
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
94 | if (allocator == NULL) { |
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
95 | allocator = cxDefaultAllocator; |
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
96 | } |
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
97 | return (struct cx_array_reallocator_s) { |
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
98 | cx_array_advanced_realloc, |
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
99 | (void*) allocator, (void*) stackmem, |
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
100 | 0, 0 |
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
101 | }; |
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
102 | } |
818
2be8fe3d5a2d
add cx_array_add() + fix type of cx_array_default_reallocator
Mike Becker <universe@uap-core.de>
parents:
817
diff
changeset
|
103 | |
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
104 | // LOW LEVEL ARRAY LIST FUNCTIONS |
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
105 | |
1040
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
106 | static size_t cx_array_align_capacity( |
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
107 | size_t cap, |
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
108 | size_t alignment, |
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
109 | size_t max |
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
110 | ) { |
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
111 | if (cap > max - alignment) { |
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
112 | return cap; |
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
113 | } else { |
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
114 | return cap - (cap % alignment) + alignment; |
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
115 | } |
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
116 | } |
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
117 | |
999
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
118 | int cx_array_reserve( |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
119 | void **array, |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
120 | void *size, |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
121 | void *capacity, |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
122 | unsigned width, |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
123 | size_t elem_size, |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
124 | size_t elem_count, |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
125 | CxArrayReallocator *reallocator |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
126 | ) { |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
127 | // assert pointers |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
128 | assert(array != NULL); |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
129 | assert(size != NULL); |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
130 | assert(capacity != NULL); |
1089
865c84fef6b4
refine docs for array_list.h - issue #548
Mike Becker <universe@uap-core.de>
parents:
1084
diff
changeset
|
131 | |
865c84fef6b4
refine docs for array_list.h - issue #548
Mike Becker <universe@uap-core.de>
parents:
1084
diff
changeset
|
132 | // default reallocator |
865c84fef6b4
refine docs for array_list.h - issue #548
Mike Becker <universe@uap-core.de>
parents:
1084
diff
changeset
|
133 | if (reallocator == NULL) { |
865c84fef6b4
refine docs for array_list.h - issue #548
Mike Becker <universe@uap-core.de>
parents:
1084
diff
changeset
|
134 | reallocator = cx_array_default_reallocator; |
865c84fef6b4
refine docs for array_list.h - issue #548
Mike Becker <universe@uap-core.de>
parents:
1084
diff
changeset
|
135 | } |
999
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
136 | |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
137 | // determine size and capacity |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
138 | size_t oldcap; |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
139 | size_t oldsize; |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
140 | size_t max_size; |
1084
0bcd71d2615a
change cx_array_reserve() and cx_array_copy() to accept width in bytes instead of bits
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
141 | if (width == 0 || width == sizeof(size_t)) { |
999
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
142 | oldcap = *(size_t*) capacity; |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
143 | oldsize = *(size_t*) size; |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
144 | max_size = SIZE_MAX; |
1084
0bcd71d2615a
change cx_array_reserve() and cx_array_copy() to accept width in bytes instead of bits
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
145 | } else if (width == sizeof(uint16_t)) { |
999
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
146 | oldcap = *(uint16_t*) capacity; |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
147 | oldsize = *(uint16_t*) size; |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
148 | max_size = UINT16_MAX; |
1084
0bcd71d2615a
change cx_array_reserve() and cx_array_copy() to accept width in bytes instead of bits
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
149 | } else if (width == sizeof(uint8_t)) { |
999
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
150 | oldcap = *(uint8_t*) capacity; |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
151 | oldsize = *(uint8_t*) size; |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
152 | max_size = UINT8_MAX; |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
153 | } |
1018
c773da859bad
fix compilation for compilers which don't set __WORDSIZE
Mike Becker <universe@uap-core.de>
parents:
999
diff
changeset
|
154 | #if CX_WORDSIZE == 64 |
1084
0bcd71d2615a
change cx_array_reserve() and cx_array_copy() to accept width in bytes instead of bits
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
155 | else if (width == sizeof(uint32_t)) { |
999
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
156 | oldcap = *(uint32_t*) capacity; |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
157 | oldsize = *(uint32_t*) size; |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
158 | max_size = UINT32_MAX; |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
159 | } |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
160 | #endif |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
161 | else { |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
162 | errno = EINVAL; |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
163 | return 1; |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
164 | } |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
165 | |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
166 | // assert that the array is allocated when it has capacity |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
167 | assert(*array != NULL || oldcap == 0); |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
168 | |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
169 | // check for overflow |
1040
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
170 | if (elem_count > max_size - oldsize) { |
999
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
171 | errno = EOVERFLOW; |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
172 | return 1; |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
173 | } |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
174 | |
1040
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
175 | // determine new capacity |
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
176 | size_t newcap = oldsize + elem_count; |
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
177 | |
999
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
178 | // reallocate if possible |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
179 | if (newcap > oldcap) { |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
180 | // calculate new capacity (next number divisible by 16) |
1040
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
181 | newcap = cx_array_align_capacity(newcap, 16, max_size); |
999
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
182 | |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
183 | // perform reallocation |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
184 | void *newmem = reallocator->realloc( |
1322
7be10b57f658
fix critical memory overflow in the stack-based array reallocator
Mike Becker <universe@uap-core.de>
parents:
1319
diff
changeset
|
185 | *array, oldcap, newcap, elem_size, reallocator |
999
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
186 | ); |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
187 | if (newmem == NULL) { |
1065
6eb7b54975ee
improve coverage metrics
Mike Becker <universe@uap-core.de>
parents:
1047
diff
changeset
|
188 | return 1; // LCOV_EXCL_LINE |
999
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
189 | } |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
190 | |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
191 | // store new pointer |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
192 | *array = newmem; |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
193 | |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
194 | // store new capacity |
1084
0bcd71d2615a
change cx_array_reserve() and cx_array_copy() to accept width in bytes instead of bits
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
195 | if (width == 0 || width == sizeof(size_t)) { |
999
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
196 | *(size_t*) capacity = newcap; |
1084
0bcd71d2615a
change cx_array_reserve() and cx_array_copy() to accept width in bytes instead of bits
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
197 | } else if (width == sizeof(uint16_t)) { |
1019
09c6fe8fe3b9
add explicit casts to silence warnings
Mike Becker <universe@uap-core.de>
parents:
1018
diff
changeset
|
198 | *(uint16_t*) capacity = (uint16_t) newcap; |
1084
0bcd71d2615a
change cx_array_reserve() and cx_array_copy() to accept width in bytes instead of bits
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
199 | } else if (width == sizeof(uint8_t)) { |
1019
09c6fe8fe3b9
add explicit casts to silence warnings
Mike Becker <universe@uap-core.de>
parents:
1018
diff
changeset
|
200 | *(uint8_t*) capacity = (uint8_t) newcap; |
999
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
201 | } |
1018
c773da859bad
fix compilation for compilers which don't set __WORDSIZE
Mike Becker <universe@uap-core.de>
parents:
999
diff
changeset
|
202 | #if CX_WORDSIZE == 64 |
1084
0bcd71d2615a
change cx_array_reserve() and cx_array_copy() to accept width in bytes instead of bits
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
203 | else if (width == sizeof(uint32_t)) { |
1019
09c6fe8fe3b9
add explicit casts to silence warnings
Mike Becker <universe@uap-core.de>
parents:
1018
diff
changeset
|
204 | *(uint32_t*) capacity = (uint32_t) newcap; |
999
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
205 | } |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
206 | #endif |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
207 | } |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
208 | |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
209 | return 0; |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
210 | } |
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
211 | |
986
38fa7e41194c
simplify cx_array_copy() - fixes #474
Mike Becker <universe@uap-core.de>
parents:
985
diff
changeset
|
212 | int cx_array_copy( |
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
213 | void **target, |
998
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
214 | void *size, |
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
215 | void *capacity, |
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
216 | unsigned width, |
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
217 | size_t index, |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
218 | const void *src, |
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
219 | size_t elem_size, |
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
220 | size_t elem_count, |
953
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
221 | CxArrayReallocator *reallocator |
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
222 | ) { |
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
223 | // assert pointers |
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
224 | assert(target != NULL); |
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
225 | assert(size != NULL); |
986
38fa7e41194c
simplify cx_array_copy() - fixes #474
Mike Becker <universe@uap-core.de>
parents:
985
diff
changeset
|
226 | assert(capacity != NULL); |
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
227 | assert(src != NULL); |
1089
865c84fef6b4
refine docs for array_list.h - issue #548
Mike Becker <universe@uap-core.de>
parents:
1084
diff
changeset
|
228 | |
865c84fef6b4
refine docs for array_list.h - issue #548
Mike Becker <universe@uap-core.de>
parents:
1084
diff
changeset
|
229 | // default reallocator |
865c84fef6b4
refine docs for array_list.h - issue #548
Mike Becker <universe@uap-core.de>
parents:
1084
diff
changeset
|
230 | if (reallocator == NULL) { |
865c84fef6b4
refine docs for array_list.h - issue #548
Mike Becker <universe@uap-core.de>
parents:
1084
diff
changeset
|
231 | reallocator = cx_array_default_reallocator; |
865c84fef6b4
refine docs for array_list.h - issue #548
Mike Becker <universe@uap-core.de>
parents:
1084
diff
changeset
|
232 | } |
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
233 | |
998
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
234 | // determine size and capacity |
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
235 | size_t oldcap; |
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
236 | size_t oldsize; |
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
237 | size_t max_size; |
1084
0bcd71d2615a
change cx_array_reserve() and cx_array_copy() to accept width in bytes instead of bits
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
238 | if (width == 0 || width == sizeof(size_t)) { |
998
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
239 | oldcap = *(size_t*) capacity; |
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
240 | oldsize = *(size_t*) size; |
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
241 | max_size = SIZE_MAX; |
1084
0bcd71d2615a
change cx_array_reserve() and cx_array_copy() to accept width in bytes instead of bits
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
242 | } else if (width == sizeof(uint16_t)) { |
998
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
243 | oldcap = *(uint16_t*) capacity; |
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
244 | oldsize = *(uint16_t*) size; |
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
245 | max_size = UINT16_MAX; |
1084
0bcd71d2615a
change cx_array_reserve() and cx_array_copy() to accept width in bytes instead of bits
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
246 | } else if (width == sizeof(uint8_t)) { |
998
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
247 | oldcap = *(uint8_t*) capacity; |
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
248 | oldsize = *(uint8_t*) size; |
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
249 | max_size = UINT8_MAX; |
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
250 | } |
1018
c773da859bad
fix compilation for compilers which don't set __WORDSIZE
Mike Becker <universe@uap-core.de>
parents:
999
diff
changeset
|
251 | #if CX_WORDSIZE == 64 |
1084
0bcd71d2615a
change cx_array_reserve() and cx_array_copy() to accept width in bytes instead of bits
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
252 | else if (width == sizeof(uint32_t)) { |
998
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
253 | oldcap = *(uint32_t*) capacity; |
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
254 | oldsize = *(uint32_t*) size; |
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
255 | max_size = UINT32_MAX; |
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
256 | } |
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
257 | #endif |
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
258 | else { |
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
259 | errno = EINVAL; |
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
260 | return 1; |
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
261 | } |
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
262 | |
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
263 | // assert that the array is allocated when it has capacity |
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
264 | assert(*target != NULL || oldcap == 0); |
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
265 | |
1040
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
266 | // check for overflow |
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
267 | if (index > max_size || elem_count > max_size - index) { |
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
268 | errno = EOVERFLOW; |
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
269 | return 1; |
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
270 | } |
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
271 | |
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
272 | // check if resize is required |
627
cc8cbabd27cd
fix cx_array_copy() unintentionally shrinking the array
Mike Becker <universe@uap-core.de>
parents:
626
diff
changeset
|
273 | size_t minsize = index + elem_count; |
998
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
274 | size_t newsize = oldsize < minsize ? minsize : oldsize; |
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
275 | |
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
276 | // reallocate if possible |
998
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
277 | size_t newcap = oldcap; |
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
278 | if (newsize > oldcap) { |
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
279 | // check, if we need to repair the src pointer |
611
77efa5163ae5
#219 array list: implement insert
Mike Becker <universe@uap-core.de>
parents:
610
diff
changeset
|
280 | uintptr_t targetaddr = (uintptr_t) *target; |
77efa5163ae5
#219 array list: implement insert
Mike Becker <universe@uap-core.de>
parents:
610
diff
changeset
|
281 | uintptr_t srcaddr = (uintptr_t) src; |
77efa5163ae5
#219 array list: implement insert
Mike Becker <universe@uap-core.de>
parents:
610
diff
changeset
|
282 | bool repairsrc = targetaddr <= srcaddr |
998
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
283 | && srcaddr < targetaddr + oldcap * elem_size; |
611
77efa5163ae5
#219 array list: implement insert
Mike Becker <universe@uap-core.de>
parents:
610
diff
changeset
|
284 | |
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
285 | // calculate new capacity (next number divisible by 16) |
1040
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
286 | newcap = cx_array_align_capacity(newsize, 16, max_size); |
998
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
287 | assert(newcap > newsize); |
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
288 | |
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
289 | // perform reallocation |
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
290 | void *newmem = reallocator->realloc( |
1322
7be10b57f658
fix critical memory overflow in the stack-based array reallocator
Mike Becker <universe@uap-core.de>
parents:
1319
diff
changeset
|
291 | *target, oldcap, newcap, elem_size, reallocator |
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
292 | ); |
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
293 | if (newmem == NULL) { |
986
38fa7e41194c
simplify cx_array_copy() - fixes #474
Mike Becker <universe@uap-core.de>
parents:
985
diff
changeset
|
294 | return 1; |
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
295 | } |
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
296 | |
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
297 | // repair src pointer, if necessary |
611
77efa5163ae5
#219 array list: implement insert
Mike Becker <universe@uap-core.de>
parents:
610
diff
changeset
|
298 | if (repairsrc) { |
77efa5163ae5
#219 array list: implement insert
Mike Becker <universe@uap-core.de>
parents:
610
diff
changeset
|
299 | src = ((char *) newmem) + (srcaddr - targetaddr); |
77efa5163ae5
#219 array list: implement insert
Mike Becker <universe@uap-core.de>
parents:
610
diff
changeset
|
300 | } |
77efa5163ae5
#219 array list: implement insert
Mike Becker <universe@uap-core.de>
parents:
610
diff
changeset
|
301 | |
998
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
302 | // store new pointer |
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
303 | *target = newmem; |
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
304 | } |
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
305 | |
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
306 | // determine target pointer |
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
307 | char *start = *target; |
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
308 | start += index * elem_size; |
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
309 | |
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
310 | // copy elements and set new size |
1040
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
311 | // note: no overflow check here, b/c we cannot get here w/o allocation |
611
77efa5163ae5
#219 array list: implement insert
Mike Becker <universe@uap-core.de>
parents:
610
diff
changeset
|
312 | memmove(start, src, elem_count * elem_size); |
998
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
313 | |
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
314 | // if any of size or capacity changed, store them back |
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
315 | if (newsize != oldsize || newcap != oldcap) { |
1084
0bcd71d2615a
change cx_array_reserve() and cx_array_copy() to accept width in bytes instead of bits
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
316 | if (width == 0 || width == sizeof(size_t)) { |
998
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
317 | *(size_t*) capacity = newcap; |
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
318 | *(size_t*) size = newsize; |
1084
0bcd71d2615a
change cx_array_reserve() and cx_array_copy() to accept width in bytes instead of bits
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
319 | } else if (width == sizeof(uint16_t)) { |
1019
09c6fe8fe3b9
add explicit casts to silence warnings
Mike Becker <universe@uap-core.de>
parents:
1018
diff
changeset
|
320 | *(uint16_t*) capacity = (uint16_t) newcap; |
09c6fe8fe3b9
add explicit casts to silence warnings
Mike Becker <universe@uap-core.de>
parents:
1018
diff
changeset
|
321 | *(uint16_t*) size = (uint16_t) newsize; |
1084
0bcd71d2615a
change cx_array_reserve() and cx_array_copy() to accept width in bytes instead of bits
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
322 | } else if (width == sizeof(uint8_t)) { |
1019
09c6fe8fe3b9
add explicit casts to silence warnings
Mike Becker <universe@uap-core.de>
parents:
1018
diff
changeset
|
323 | *(uint8_t*) capacity = (uint8_t) newcap; |
09c6fe8fe3b9
add explicit casts to silence warnings
Mike Becker <universe@uap-core.de>
parents:
1018
diff
changeset
|
324 | *(uint8_t*) size = (uint8_t) newsize; |
998
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
325 | } |
1018
c773da859bad
fix compilation for compilers which don't set __WORDSIZE
Mike Becker <universe@uap-core.de>
parents:
999
diff
changeset
|
326 | #if CX_WORDSIZE == 64 |
1084
0bcd71d2615a
change cx_array_reserve() and cx_array_copy() to accept width in bytes instead of bits
Mike Becker <universe@uap-core.de>
parents:
1065
diff
changeset
|
327 | else if (width == sizeof(uint32_t)) { |
1019
09c6fe8fe3b9
add explicit casts to silence warnings
Mike Becker <universe@uap-core.de>
parents:
1018
diff
changeset
|
328 | *(uint32_t*) capacity = (uint32_t) newcap; |
09c6fe8fe3b9
add explicit casts to silence warnings
Mike Becker <universe@uap-core.de>
parents:
1018
diff
changeset
|
329 | *(uint32_t*) size = (uint32_t) newsize; |
998
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
330 | } |
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
331 | #endif |
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
332 | } |
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
333 | |
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
334 | // return successfully |
986
38fa7e41194c
simplify cx_array_copy() - fixes #474
Mike Becker <universe@uap-core.de>
parents:
985
diff
changeset
|
335 | return 0; |
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
336 | } |
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
337 | |
986
38fa7e41194c
simplify cx_array_copy() - fixes #474
Mike Becker <universe@uap-core.de>
parents:
985
diff
changeset
|
338 | int cx_array_insert_sorted( |
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
339 | void **target, |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
340 | size_t *size, |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
341 | size_t *capacity, |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
342 | cx_compare_func cmp_func, |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
343 | const void *sorted_data, |
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
344 | size_t elem_size, |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
345 | size_t elem_count, |
953
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
346 | CxArrayReallocator *reallocator |
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
347 | ) { |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
348 | // assert pointers |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
349 | assert(target != NULL); |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
350 | assert(size != NULL); |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
351 | assert(capacity != NULL); |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
352 | assert(cmp_func != NULL); |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
353 | assert(sorted_data != NULL); |
1089
865c84fef6b4
refine docs for array_list.h - issue #548
Mike Becker <universe@uap-core.de>
parents:
1084
diff
changeset
|
354 | |
865c84fef6b4
refine docs for array_list.h - issue #548
Mike Becker <universe@uap-core.de>
parents:
1084
diff
changeset
|
355 | // default reallocator |
865c84fef6b4
refine docs for array_list.h - issue #548
Mike Becker <universe@uap-core.de>
parents:
1084
diff
changeset
|
356 | if (reallocator == NULL) { |
865c84fef6b4
refine docs for array_list.h - issue #548
Mike Becker <universe@uap-core.de>
parents:
1084
diff
changeset
|
357 | reallocator = cx_array_default_reallocator; |
865c84fef6b4
refine docs for array_list.h - issue #548
Mike Becker <universe@uap-core.de>
parents:
1084
diff
changeset
|
358 | } |
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
359 | |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
360 | // corner case |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
361 | if (elem_count == 0) return 0; |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
362 | |
1040
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
363 | // overflow check |
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
364 | if (elem_count > SIZE_MAX - *size) { |
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
365 | errno = EOVERFLOW; |
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
366 | return 1; |
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
367 | } |
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
368 | |
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
369 | // store some counts |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
370 | size_t old_size = *size; |
1322
7be10b57f658
fix critical memory overflow in the stack-based array reallocator
Mike Becker <universe@uap-core.de>
parents:
1319
diff
changeset
|
371 | size_t old_capacity = *capacity; |
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
372 | size_t needed_capacity = old_size + elem_count; |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
373 | |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
374 | // if we need more than we have, try a reallocation |
1322
7be10b57f658
fix critical memory overflow in the stack-based array reallocator
Mike Becker <universe@uap-core.de>
parents:
1319
diff
changeset
|
375 | if (needed_capacity > old_capacity) { |
1040
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1022
diff
changeset
|
376 | size_t new_capacity = cx_array_align_capacity(needed_capacity, 16, SIZE_MAX); |
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
377 | void *new_mem = reallocator->realloc( |
1322
7be10b57f658
fix critical memory overflow in the stack-based array reallocator
Mike Becker <universe@uap-core.de>
parents:
1319
diff
changeset
|
378 | *target, old_capacity, new_capacity, elem_size, reallocator |
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
379 | ); |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
380 | if (new_mem == NULL) { |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
381 | // give it up right away, there is no contract |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
382 | // that requires us to insert as much as we can |
1065
6eb7b54975ee
improve coverage metrics
Mike Becker <universe@uap-core.de>
parents:
1047
diff
changeset
|
383 | return 1; // LCOV_EXCL_LINE |
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
384 | } |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
385 | *target = new_mem; |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
386 | *capacity = new_capacity; |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
387 | } |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
388 | |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
389 | // now we have guaranteed that we can insert everything |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
390 | size_t new_size = old_size + elem_count; |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
391 | *size = new_size; |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
392 | |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
393 | // declare the source and destination indices/pointers |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
394 | size_t si = 0, di = 0; |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
395 | const char *src = sorted_data; |
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
396 | char *dest = *target; |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
397 | |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
398 | // find the first insertion point |
889
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
399 | di = cx_array_binary_search_sup(dest, old_size, elem_size, src, cmp_func); |
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
400 | dest += di * elem_size; |
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
401 | |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
402 | // move the remaining elements in the array completely to the right |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
403 | // we will call it the "buffer" for parked elements |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
404 | size_t buf_size = old_size - di; |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
405 | size_t bi = new_size - buf_size; |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
406 | char *bptr = ((char *) *target) + bi * elem_size; |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
407 | memmove(bptr, dest, buf_size * elem_size); |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
408 | |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
409 | // while there are both source and buffered elements left, |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
410 | // copy them interleaving |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
411 | while (si < elem_count && bi < new_size) { |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
412 | // determine how many source elements can be inserted |
889
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
413 | size_t copy_len, bytes_copied; |
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
414 | copy_len = cx_array_binary_search_sup( |
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
415 | src, |
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
416 | elem_count - si, |
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
417 | elem_size, |
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
418 | bptr, |
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
419 | cmp_func |
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
420 | ); |
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
421 | |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
422 | // copy the source elements |
889
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
423 | bytes_copied = copy_len * elem_size; |
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
424 | memcpy(dest, src, bytes_copied); |
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
425 | dest += bytes_copied; |
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
426 | src += bytes_copied; |
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
427 | si += copy_len; |
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
428 | |
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
429 | // when all source elements are in place, we are done |
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
430 | if (si >= elem_count) break; |
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
431 | |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
432 | // determine how many buffered elements need to be restored |
889
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
433 | copy_len = cx_array_binary_search_sup( |
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
434 | bptr, |
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
435 | new_size - bi, |
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
436 | elem_size, |
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
437 | src, |
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
438 | cmp_func |
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
439 | ); |
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
440 | |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
441 | // restore the buffered elements |
889
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
442 | bytes_copied = copy_len * elem_size; |
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
443 | memmove(dest, bptr, bytes_copied); |
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
444 | dest += bytes_copied; |
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
445 | bptr += bytes_copied; |
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
446 | bi += copy_len; |
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
447 | } |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
448 | |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
449 | // still source elements left? simply append them |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
450 | if (si < elem_count) { |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
451 | memcpy(dest, src, elem_size * (elem_count - si)); |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
452 | } |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
453 | |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
454 | // still buffer elements left? |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
455 | // don't worry, we already moved them to the correct place |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
456 | |
986
38fa7e41194c
simplify cx_array_copy() - fixes #474
Mike Becker <universe@uap-core.de>
parents:
985
diff
changeset
|
457 | return 0; |
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
458 | } |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
459 | |
884
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
460 | size_t cx_array_binary_search_inf( |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
461 | const void *arr, |
884
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
462 | size_t size, |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
463 | size_t elem_size, |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
464 | const void *elem, |
884
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
465 | cx_compare_func cmp_func |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
466 | ) { |
888 | 467 | // special case: empty array |
468 | if (size == 0) return 0; | |
469 | ||
884
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
470 | // declare a variable that will contain the compare results |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
471 | int result; |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
472 | |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
473 | // cast the array pointer to something we can use offsets with |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
474 | const char *array = arr; |
884
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
475 | |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
476 | // check the first array element |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
477 | result = cmp_func(elem, array); |
885
878a450e79bd
fixes incorrect result from cx_array_binary_search() when searched element is smaller than the entire array
Mike Becker <universe@uap-core.de>
parents:
884
diff
changeset
|
478 | if (result < 0) { |
878a450e79bd
fixes incorrect result from cx_array_binary_search() when searched element is smaller than the entire array
Mike Becker <universe@uap-core.de>
parents:
884
diff
changeset
|
479 | return size; |
878a450e79bd
fixes incorrect result from cx_array_binary_search() when searched element is smaller than the entire array
Mike Becker <universe@uap-core.de>
parents:
884
diff
changeset
|
480 | } else if (result == 0) { |
884
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
481 | return 0; |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
482 | } |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
483 | |
1022
2911c1f4a570
add shortcut to binary search when array size is one
Mike Becker <universe@uap-core.de>
parents:
1019
diff
changeset
|
484 | // special case: there is only one element and that is smaller |
2911c1f4a570
add shortcut to binary search when array size is one
Mike Becker <universe@uap-core.de>
parents:
1019
diff
changeset
|
485 | if (size == 1) return 0; |
2911c1f4a570
add shortcut to binary search when array size is one
Mike Becker <universe@uap-core.de>
parents:
1019
diff
changeset
|
486 | |
884
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
487 | // check the last array element |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
488 | result = cmp_func(elem, array + elem_size * (size - 1)); |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
489 | if (result >= 0) { |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
490 | return size - 1; |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
491 | } |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
492 | |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
493 | // the element is now guaranteed to be somewhere in the list |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
494 | // so start the binary search |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
495 | size_t left_index = 1; |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
496 | size_t right_index = size - 1; |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
497 | size_t pivot_index; |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
498 | |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
499 | while (left_index <= right_index) { |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
500 | pivot_index = left_index + (right_index - left_index) / 2; |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
501 | const char *arr_elem = array + pivot_index * elem_size; |
884
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
502 | result = cmp_func(elem, arr_elem); |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
503 | if (result == 0) { |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
504 | // found it! |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
505 | return pivot_index; |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
506 | } else if (result < 0) { |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
507 | // element is smaller than pivot, continue search left |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
508 | right_index = pivot_index - 1; |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
509 | } else { |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
510 | // element is larger than pivot, continue search right |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
511 | left_index = pivot_index + 1; |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
512 | } |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
513 | } |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
514 | |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
515 | // report the largest upper bound |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
516 | return result < 0 ? (pivot_index - 1) : pivot_index; |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
517 | } |
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
518 | |
985
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
519 | size_t cx_array_binary_search( |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
520 | const void *arr, |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
521 | size_t size, |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
522 | size_t elem_size, |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
523 | const void *elem, |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
524 | cx_compare_func cmp_func |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
525 | ) { |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
526 | size_t index = cx_array_binary_search_inf( |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
527 | arr, size, elem_size, elem, cmp_func |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
528 | ); |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
529 | if (index < size && |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
530 | cmp_func(((const char *) arr) + index * elem_size, elem) == 0) { |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
531 | return index; |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
532 | } else { |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
533 | return size; |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
534 | } |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
535 | } |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
536 | |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
537 | size_t cx_array_binary_search_sup( |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
538 | const void *arr, |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
539 | size_t size, |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
540 | size_t elem_size, |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
541 | const void *elem, |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
542 | cx_compare_func cmp_func |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
543 | ) { |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
544 | size_t inf = cx_array_binary_search_inf( |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
545 | arr, size, elem_size, elem, cmp_func |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
546 | ); |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
547 | if (inf == size) { |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
548 | // no infimum means, first element is supremum |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
549 | return 0; |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
550 | } else if (cmp_func(((const char *) arr) + inf * elem_size, elem) == 0) { |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
551 | return inf; |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
552 | } else { |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
553 | return inf + 1; |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
554 | } |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
555 | } |
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
556 | |
643
5700ba9154ab
#228 make buffer sizes adjustable at compile time
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
557 | #ifndef CX_ARRAY_SWAP_SBO_SIZE |
735
b686d0c98c62
unify the list swap SBO sizes
Mike Becker <universe@uap-core.de>
parents:
708
diff
changeset
|
558 | #define CX_ARRAY_SWAP_SBO_SIZE 128 |
643
5700ba9154ab
#228 make buffer sizes adjustable at compile time
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
559 | #endif |
926
8fdd8d78c14b
fix several survivors of east-const and some missing consts
Mike Becker <universe@uap-core.de>
parents:
919
diff
changeset
|
560 | const unsigned cx_array_swap_sbo_size = CX_ARRAY_SWAP_SBO_SIZE; |
804
5136f2fc32ec
add CX_DISABLE_ARRAY_LIST_SWAP_SBO flag
Mike Becker <universe@uap-core.de>
parents:
764
diff
changeset
|
561 | |
623
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
562 | void cx_array_swap( |
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
563 | void *arr, |
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
564 | size_t elem_size, |
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
565 | size_t idx1, |
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
566 | size_t idx2 |
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
567 | ) { |
660 | 568 | assert(arr != NULL); |
569 | ||
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
570 | // short circuit |
623
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
571 | if (idx1 == idx2) return; |
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
572 | |
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
573 | char sbo_mem[CX_ARRAY_SWAP_SBO_SIZE]; |
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
574 | void *tmp; |
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
575 | |
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
576 | // decide if we can use the local buffer |
807
c8d692131b1e
remove flags to disable SBO in tests - fix #343 fix #358
Mike Becker <universe@uap-core.de>
parents:
804
diff
changeset
|
577 | if (elem_size > CX_ARRAY_SWAP_SBO_SIZE) { |
1319
aa1f580f8f59
add convenience macros for using the default allocator - relates to #669
Mike Becker <universe@uap-core.de>
parents:
1318
diff
changeset
|
578 | tmp = cxMallocDefault(elem_size); |
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
579 | // we don't want to enforce error handling |
623
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
580 | if (tmp == NULL) abort(); |
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
581 | } else { |
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
582 | tmp = sbo_mem; |
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
583 | } |
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
584 | |
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
585 | // calculate memory locations |
623
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
586 | char *left = arr, *right = arr; |
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
587 | left += idx1 * elem_size; |
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
588 | right += idx2 * elem_size; |
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
589 | |
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
590 | // three-way swap |
623
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
591 | memcpy(tmp, left, elem_size); |
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
592 | memcpy(left, right, elem_size); |
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
593 | memcpy(right, tmp, elem_size); |
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
594 | |
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
595 | // free dynamic memory, if it was needed |
623
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
596 | if (tmp != sbo_mem) { |
1319
aa1f580f8f59
add convenience macros for using the default allocator - relates to #669
Mike Becker <universe@uap-core.de>
parents:
1318
diff
changeset
|
597 | cxFreeDefault(tmp); |
623
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
598 | } |
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
599 | } |
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
600 | |
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
601 | // HIGH LEVEL ARRAY LIST FUNCTIONS |
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
602 | |
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
603 | typedef struct { |
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
604 | struct cx_list_s base; |
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
605 | void *data; |
677
b09aae58bba4
refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents:
676
diff
changeset
|
606 | size_t capacity; |
953
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
607 | CxArrayReallocator reallocator; |
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
608 | } cx_array_list; |
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
609 | |
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
610 | static void cx_arl_destructor(struct cx_list_s *list) { |
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
611 | cx_array_list *arl = (cx_array_list *) list; |
708
1caed6c9ba68
fix inconsistent destructor requirements for list and map classes
Mike Becker <universe@uap-core.de>
parents:
699
diff
changeset
|
612 | |
1caed6c9ba68
fix inconsistent destructor requirements for list and map classes
Mike Becker <universe@uap-core.de>
parents:
699
diff
changeset
|
613 | char *ptr = arl->data; |
1caed6c9ba68
fix inconsistent destructor requirements for list and map classes
Mike Becker <universe@uap-core.de>
parents:
699
diff
changeset
|
614 | |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
615 | if (list->collection.simple_destructor) { |
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
616 | for (size_t i = 0; i < list->collection.size; i++) { |
708
1caed6c9ba68
fix inconsistent destructor requirements for list and map classes
Mike Becker <universe@uap-core.de>
parents:
699
diff
changeset
|
617 | cx_invoke_simple_destructor(list, ptr); |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
618 | ptr += list->collection.elem_size; |
708
1caed6c9ba68
fix inconsistent destructor requirements for list and map classes
Mike Becker <universe@uap-core.de>
parents:
699
diff
changeset
|
619 | } |
1caed6c9ba68
fix inconsistent destructor requirements for list and map classes
Mike Becker <universe@uap-core.de>
parents:
699
diff
changeset
|
620 | } |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
621 | if (list->collection.advanced_destructor) { |
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
622 | for (size_t i = 0; i < list->collection.size; i++) { |
708
1caed6c9ba68
fix inconsistent destructor requirements for list and map classes
Mike Becker <universe@uap-core.de>
parents:
699
diff
changeset
|
623 | cx_invoke_advanced_destructor(list, ptr); |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
624 | ptr += list->collection.elem_size; |
708
1caed6c9ba68
fix inconsistent destructor requirements for list and map classes
Mike Becker <universe@uap-core.de>
parents:
699
diff
changeset
|
625 | } |
1caed6c9ba68
fix inconsistent destructor requirements for list and map classes
Mike Becker <universe@uap-core.de>
parents:
699
diff
changeset
|
626 | } |
1caed6c9ba68
fix inconsistent destructor requirements for list and map classes
Mike Becker <universe@uap-core.de>
parents:
699
diff
changeset
|
627 | |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
628 | cxFree(list->collection.allocator, arl->data); |
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
629 | cxFree(list->collection.allocator, list); |
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
630 | } |
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
631 | |
638
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
632 | static size_t cx_arl_insert_array( |
629
6c81ee4f11ad
#224 add cxListAddArray()
Mike Becker <universe@uap-core.de>
parents:
628
diff
changeset
|
633 | struct cx_list_s *list, |
638
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
634 | size_t index, |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
635 | const void *array, |
629
6c81ee4f11ad
#224 add cxListAddArray()
Mike Becker <universe@uap-core.de>
parents:
628
diff
changeset
|
636 | size_t n |
6c81ee4f11ad
#224 add cxListAddArray()
Mike Becker <universe@uap-core.de>
parents:
628
diff
changeset
|
637 | ) { |
638
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
638 | // out of bounds and special case check |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
639 | if (index > list->collection.size || n == 0) return 0; |
638
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
640 | |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
641 | // get a correctly typed pointer to the list |
629
6c81ee4f11ad
#224 add cxListAddArray()
Mike Becker <universe@uap-core.de>
parents:
628
diff
changeset
|
642 | cx_array_list *arl = (cx_array_list *) list; |
638
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
643 | |
1316
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
644 | // guarantee enough capacity |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
645 | if (arl->capacity < list->collection.size + n) { |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
646 | size_t new_capacity = list->collection.size + n; |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
647 | new_capacity = new_capacity - (new_capacity % 16) + 16; |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
648 | if (cxReallocateArray( |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
649 | list->collection.allocator, |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
650 | &arl->data, new_capacity, |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
651 | list->collection.elem_size) |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
652 | ) { |
638
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
653 | return 0; |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
654 | } |
1316
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
655 | arl->capacity = new_capacity; |
638
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
656 | } |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
657 | |
1316
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
658 | // determine insert position |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
659 | char *arl_data = arl->data; |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
660 | char *insert_pos = arl_data + index * list->collection.elem_size; |
638
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
661 | |
1316
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
662 | // do we need to move some elements? |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
663 | if (index < list->collection.size) { |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
664 | size_t elems_to_move = list->collection.size - index; |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
665 | char *target = insert_pos + n * list->collection.elem_size; |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
666 | memmove(target, insert_pos, elems_to_move * list->collection.elem_size); |
629
6c81ee4f11ad
#224 add cxListAddArray()
Mike Becker <universe@uap-core.de>
parents:
628
diff
changeset
|
667 | } |
1316
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
668 | |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
669 | // place the new elements, if any |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
670 | if (array != NULL) { |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
671 | memcpy(insert_pos, array, n * list->collection.elem_size); |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
672 | } |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
673 | list->collection.size += n; |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
674 | |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
675 | return n; |
629
6c81ee4f11ad
#224 add cxListAddArray()
Mike Becker <universe@uap-core.de>
parents:
628
diff
changeset
|
676 | } |
6c81ee4f11ad
#224 add cxListAddArray()
Mike Becker <universe@uap-core.de>
parents:
628
diff
changeset
|
677 | |
881
1dbbf8c1c42f
add optimized implementation of insert_sorted for array lists
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
678 | static size_t cx_arl_insert_sorted( |
1dbbf8c1c42f
add optimized implementation of insert_sorted for array lists
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
679 | struct cx_list_s *list, |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
680 | const void *sorted_data, |
881
1dbbf8c1c42f
add optimized implementation of insert_sorted for array lists
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
681 | size_t n |
1dbbf8c1c42f
add optimized implementation of insert_sorted for array lists
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
682 | ) { |
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
683 | // get a correctly typed pointer to the list |
881
1dbbf8c1c42f
add optimized implementation of insert_sorted for array lists
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
684 | cx_array_list *arl = (cx_array_list *) list; |
1dbbf8c1c42f
add optimized implementation of insert_sorted for array lists
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
685 | |
986
38fa7e41194c
simplify cx_array_copy() - fixes #474
Mike Becker <universe@uap-core.de>
parents:
985
diff
changeset
|
686 | if (cx_array_insert_sorted( |
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
687 | &arl->data, |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
688 | &list->collection.size, |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
689 | &arl->capacity, |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
690 | list->collection.cmpfunc, |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
691 | sorted_data, |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
692 | list->collection.elem_size, |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
693 | n, |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
694 | &arl->reallocator |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
695 | )) { |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
696 | // array list implementation is "all or nothing" |
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
697 | return 0; |
986
38fa7e41194c
simplify cx_array_copy() - fixes #474
Mike Becker <universe@uap-core.de>
parents:
985
diff
changeset
|
698 | } else { |
38fa7e41194c
simplify cx_array_copy() - fixes #474
Mike Becker <universe@uap-core.de>
parents:
985
diff
changeset
|
699 | return n; |
881
1dbbf8c1c42f
add optimized implementation of insert_sorted for array lists
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
700 | } |
1dbbf8c1c42f
add optimized implementation of insert_sorted for array lists
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
701 | } |
1dbbf8c1c42f
add optimized implementation of insert_sorted for array lists
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
702 | |
1316
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
703 | static void *cx_arl_insert_element( |
641
d402fead3386
add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents:
640
diff
changeset
|
704 | struct cx_list_s *list, |
d402fead3386
add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents:
640
diff
changeset
|
705 | size_t index, |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
706 | const void *element |
641
d402fead3386
add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents:
640
diff
changeset
|
707 | ) { |
1316
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
708 | if (cx_arl_insert_array(list, index, element, 1) == 1) { |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
709 | return ((char*)((cx_array_list *) list)->data) + index * list->collection.elem_size; |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
710 | } else { |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
711 | return NULL; |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
712 | } |
641
d402fead3386
add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents:
640
diff
changeset
|
713 | } |
d402fead3386
add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents:
640
diff
changeset
|
714 | |
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
715 | static int cx_arl_insert_iter( |
853
d4baf4dd55c3
simplify iterator structures
Mike Becker <universe@uap-core.de>
parents:
850
diff
changeset
|
716 | struct cx_iterator_s *iter, |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
717 | const void *elem, |
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
718 | int prepend |
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
719 | ) { |
853
d4baf4dd55c3
simplify iterator structures
Mike Becker <universe@uap-core.de>
parents:
850
diff
changeset
|
720 | struct cx_list_s *list = iter->src_handle.m; |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
721 | if (iter->index < list->collection.size) { |
1316
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
722 | if (cx_arl_insert_element(list, |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
723 | iter->index + 1 - prepend, elem) == NULL) { |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
724 | return 1; |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
725 | } |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
726 | iter->elem_count++; |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
727 | if (prepend != 0) { |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
728 | iter->index++; |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
729 | iter->elem_handle = ((char *) iter->elem_handle) + list->collection.elem_size; |
619
5e58187ac707
#219 array list: implement insert via iterator
Mike Becker <universe@uap-core.de>
parents:
616
diff
changeset
|
730 | } |
1316
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
731 | return 0; |
619
5e58187ac707
#219 array list: implement insert via iterator
Mike Becker <universe@uap-core.de>
parents:
616
diff
changeset
|
732 | } else { |
1316
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
733 | if (cx_arl_insert_element(list, list->collection.size, elem) == NULL) { |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
734 | return 1; |
874
cdce47f34d48
fix inserting via iterator correctly increases element count
Mike Becker <universe@uap-core.de>
parents:
856
diff
changeset
|
735 | } |
1316
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
736 | iter->elem_count++; |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
737 | iter->index = list->collection.size; |
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
738 | return 0; |
619
5e58187ac707
#219 array list: implement insert via iterator
Mike Becker <universe@uap-core.de>
parents:
616
diff
changeset
|
739 | } |
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
740 | } |
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
741 | |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
742 | static size_t cx_arl_remove( |
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
743 | struct cx_list_s *list, |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
744 | size_t index, |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
745 | size_t num, |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
746 | void *targetbuf |
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
747 | ) { |
664
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
748 | cx_array_list *arl = (cx_array_list *) list; |
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
749 | |
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
750 | // out-of-bounds check |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
751 | size_t remove; |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
752 | if (index >= list->collection.size) { |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
753 | remove = 0; |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
754 | } else if (index + num > list->collection.size) { |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
755 | remove = list->collection.size - index; |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
756 | } else { |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
757 | remove = num; |
613
85c08391a090
#219 array list: implement remove
Mike Becker <universe@uap-core.de>
parents:
612
diff
changeset
|
758 | } |
85c08391a090
#219 array list: implement remove
Mike Becker <universe@uap-core.de>
parents:
612
diff
changeset
|
759 | |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
760 | // easy exit |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
761 | if (remove == 0) return 0; |
664
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
762 | |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
763 | // destroy or copy contents |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
764 | if (targetbuf == NULL) { |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
765 | for (size_t idx = index; idx < index + remove; idx++) { |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
766 | cx_invoke_destructor( |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
767 | list, |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
768 | ((char *) arl->data) + idx * list->collection.elem_size |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
769 | ); |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
770 | } |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
771 | } else { |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
772 | memcpy( |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
773 | targetbuf, |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
774 | ((char *) arl->data) + index * list->collection.elem_size, |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
775 | remove * list->collection.elem_size |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
776 | ); |
624
b0bdff7d8203
#219: cx_arl_remove short-circuit for last element
Mike Becker <universe@uap-core.de>
parents:
623
diff
changeset
|
777 | } |
613
85c08391a090
#219 array list: implement remove
Mike Becker <universe@uap-core.de>
parents:
612
diff
changeset
|
778 | |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
779 | // short-circuit removal of last elements |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
780 | if (index + remove == list->collection.size) { |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
781 | list->collection.size -= remove; |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
782 | return remove; |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
783 | } |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
784 | |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
785 | // just move the elements to the left |
1065
6eb7b54975ee
improve coverage metrics
Mike Becker <universe@uap-core.de>
parents:
1047
diff
changeset
|
786 | cx_array_copy( |
613
85c08391a090
#219 array list: implement remove
Mike Becker <universe@uap-core.de>
parents:
612
diff
changeset
|
787 | &arl->data, |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
788 | &list->collection.size, |
677
b09aae58bba4
refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents:
676
diff
changeset
|
789 | &arl->capacity, |
998
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
790 | 0, |
613
85c08391a090
#219 array list: implement remove
Mike Becker <universe@uap-core.de>
parents:
612
diff
changeset
|
791 | index, |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
792 | ((char *) arl->data) + (index + remove) * list->collection.elem_size, |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
793 | list->collection.elem_size, |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
794 | list->collection.size - index - remove, |
613
85c08391a090
#219 array list: implement remove
Mike Becker <universe@uap-core.de>
parents:
612
diff
changeset
|
795 | &arl->reallocator |
85c08391a090
#219 array list: implement remove
Mike Becker <universe@uap-core.de>
parents:
612
diff
changeset
|
796 | ); |
820
8b86ee2e09bb
remove check that is always true in cx_arl_remove()
Mike Becker <universe@uap-core.de>
parents:
819
diff
changeset
|
797 | |
8b86ee2e09bb
remove check that is always true in cx_arl_remove()
Mike Becker <universe@uap-core.de>
parents:
819
diff
changeset
|
798 | // decrease the size |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
799 | list->collection.size -= remove; |
820
8b86ee2e09bb
remove check that is always true in cx_arl_remove()
Mike Becker <universe@uap-core.de>
parents:
819
diff
changeset
|
800 | |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
801 | return remove; |
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
802 | } |
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
803 | |
664
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
804 | static void cx_arl_clear(struct cx_list_s *list) { |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
805 | if (list->collection.size == 0) return; |
664
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
806 | |
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
807 | cx_array_list *arl = (cx_array_list *) list; |
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
808 | char *ptr = arl->data; |
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
809 | |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
810 | if (list->collection.simple_destructor) { |
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
811 | for (size_t i = 0; i < list->collection.size; i++) { |
677
b09aae58bba4
refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents:
676
diff
changeset
|
812 | cx_invoke_simple_destructor(list, ptr); |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
813 | ptr += list->collection.elem_size; |
664
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
814 | } |
677
b09aae58bba4
refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents:
676
diff
changeset
|
815 | } |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
816 | if (list->collection.advanced_destructor) { |
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
817 | for (size_t i = 0; i < list->collection.size; i++) { |
677
b09aae58bba4
refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents:
676
diff
changeset
|
818 | cx_invoke_advanced_destructor(list, ptr); |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
819 | ptr += list->collection.elem_size; |
664
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
820 | } |
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
821 | } |
666
b5dd654deb3b
add unit test for cxListClear + fix destructor functions not always invoked with the correct pointer
Mike Becker <universe@uap-core.de>
parents:
664
diff
changeset
|
822 | |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
823 | memset(arl->data, 0, list->collection.size * list->collection.elem_size); |
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
824 | list->collection.size = 0; |
664
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
825 | } |
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
826 | |
647
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
643
diff
changeset
|
827 | static int cx_arl_swap( |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
643
diff
changeset
|
828 | struct cx_list_s *list, |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
643
diff
changeset
|
829 | size_t i, |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
643
diff
changeset
|
830 | size_t j |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
643
diff
changeset
|
831 | ) { |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
832 | if (i >= list->collection.size || j >= list->collection.size) return 1; |
647
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
643
diff
changeset
|
833 | cx_array_list *arl = (cx_array_list *) list; |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
834 | cx_array_swap(arl->data, list->collection.elem_size, i, j); |
647
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
643
diff
changeset
|
835 | return 0; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
643
diff
changeset
|
836 | } |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
643
diff
changeset
|
837 | |
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
838 | static void *cx_arl_at( |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
839 | const struct cx_list_s *list, |
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
840 | size_t index |
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
841 | ) { |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
842 | if (index < list->collection.size) { |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
843 | const cx_array_list *arl = (const cx_array_list *) list; |
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
844 | char *space = arl->data; |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
845 | return space + index * list->collection.elem_size; |
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
846 | } else { |
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
847 | return NULL; |
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
848 | } |
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
849 | } |
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
850 | |
1162
e3bb67b72d33
remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents:
1111
diff
changeset
|
851 | static size_t cx_arl_find_remove( |
764
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
852 | struct cx_list_s *list, |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
853 | const void *elem, |
764
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
854 | bool remove |
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
855 | ) { |
1163
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
856 | assert(list != NULL); |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
857 | assert(list->collection.cmpfunc != NULL); |
1163
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
858 | if (list->collection.size == 0) return 0; |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
859 | char *cur = ((const cx_array_list *) list)->data; |
614
7aaec630cf15
#219 array list: implement find
Mike Becker <universe@uap-core.de>
parents:
613
diff
changeset
|
860 | |
1163
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
861 | // optimize with binary search, when sorted |
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
862 | if (list->collection.sorted) { |
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
863 | size_t i = cx_array_binary_search( |
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
864 | cur, |
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
865 | list->collection.size, |
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
866 | list->collection.elem_size, |
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
867 | elem, |
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
868 | list->collection.cmpfunc |
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
869 | ); |
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
870 | if (remove && i < list->collection.size) { |
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
871 | cx_arl_remove(list, i, 1, NULL); |
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
872 | } |
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
873 | return i; |
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
874 | } |
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
875 | |
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
876 | // fallback: linear search |
1162
e3bb67b72d33
remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents:
1111
diff
changeset
|
877 | for (size_t i = 0; i < list->collection.size; i++) { |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
878 | if (0 == list->collection.cmpfunc(elem, cur)) { |
764
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
879 | if (remove) { |
1163
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
880 | cx_arl_remove(list, i, 1, NULL); |
764
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
881 | } |
1163
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
882 | return i; |
614
7aaec630cf15
#219 array list: implement find
Mike Becker <universe@uap-core.de>
parents:
613
diff
changeset
|
883 | } |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
884 | cur += list->collection.elem_size; |
614
7aaec630cf15
#219 array list: implement find
Mike Becker <universe@uap-core.de>
parents:
613
diff
changeset
|
885 | } |
1162
e3bb67b72d33
remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents:
1111
diff
changeset
|
886 | return list->collection.size; |
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
887 | } |
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
888 | |
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
889 | static void cx_arl_sort(struct cx_list_s *list) { |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
890 | assert(list->collection.cmpfunc != NULL); |
615
b52b66dcd44b
#219 array list: implement sort
Mike Becker <universe@uap-core.de>
parents:
614
diff
changeset
|
891 | qsort(((cx_array_list *) list)->data, |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
892 | list->collection.size, |
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
893 | list->collection.elem_size, |
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
894 | list->collection.cmpfunc |
615
b52b66dcd44b
#219 array list: implement sort
Mike Becker <universe@uap-core.de>
parents:
614
diff
changeset
|
895 | ); |
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
896 | } |
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
897 | |
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
898 | static int cx_arl_compare( |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
899 | const struct cx_list_s *list, |
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
900 | const struct cx_list_s *other |
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
901 | ) { |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
902 | assert(list->collection.cmpfunc != NULL); |
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
903 | if (list->collection.size == other->collection.size) { |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
904 | const char *left = ((const cx_array_list *) list)->data; |
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
905 | const char *right = ((const cx_array_list *) other)->data; |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
906 | for (size_t i = 0; i < list->collection.size; i++) { |
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
907 | int d = list->collection.cmpfunc(left, right); |
622
3d93cd78aa20
#219 array list: implement compare member func
Mike Becker <universe@uap-core.de>
parents:
620
diff
changeset
|
908 | if (d != 0) { |
3d93cd78aa20
#219 array list: implement compare member func
Mike Becker <universe@uap-core.de>
parents:
620
diff
changeset
|
909 | return d; |
3d93cd78aa20
#219 array list: implement compare member func
Mike Becker <universe@uap-core.de>
parents:
620
diff
changeset
|
910 | } |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
911 | left += list->collection.elem_size; |
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
912 | right += other->collection.elem_size; |
622
3d93cd78aa20
#219 array list: implement compare member func
Mike Becker <universe@uap-core.de>
parents:
620
diff
changeset
|
913 | } |
3d93cd78aa20
#219 array list: implement compare member func
Mike Becker <universe@uap-core.de>
parents:
620
diff
changeset
|
914 | return 0; |
3d93cd78aa20
#219 array list: implement compare member func
Mike Becker <universe@uap-core.de>
parents:
620
diff
changeset
|
915 | } else { |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
916 | return list->collection.size < other->collection.size ? -1 : 1; |
622
3d93cd78aa20
#219 array list: implement compare member func
Mike Becker <universe@uap-core.de>
parents:
620
diff
changeset
|
917 | } |
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
918 | } |
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
919 | |
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
920 | static void cx_arl_reverse(struct cx_list_s *list) { |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
921 | if (list->collection.size < 2) return; |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
922 | void *data = ((const cx_array_list *) list)->data; |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
923 | size_t half = list->collection.size / 2; |
623
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
924 | for (size_t i = 0; i < half; i++) { |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
925 | cx_array_swap(data, list->collection.elem_size, i, list->collection.size - 1 - i); |
623
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
926 | } |
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
927 | } |
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
928 | |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
929 | static bool cx_arl_iter_valid(const void *it) { |
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
930 | const struct cx_iterator_s *iter = it; |
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
931 | const struct cx_list_s *list = iter->src_handle.c; |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
932 | return iter->index < list->collection.size; |
616
af7d8a29fbc5
#219 array list: add iterator
Mike Becker <universe@uap-core.de>
parents:
615
diff
changeset
|
933 | } |
af7d8a29fbc5
#219 array list: add iterator
Mike Becker <universe@uap-core.de>
parents:
615
diff
changeset
|
934 | |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
935 | static void *cx_arl_iter_current(const void *it) { |
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
936 | const struct cx_iterator_s *iter = it; |
616
af7d8a29fbc5
#219 array list: add iterator
Mike Becker <universe@uap-core.de>
parents:
615
diff
changeset
|
937 | return iter->elem_handle; |
af7d8a29fbc5
#219 array list: add iterator
Mike Becker <universe@uap-core.de>
parents:
615
diff
changeset
|
938 | } |
af7d8a29fbc5
#219 array list: add iterator
Mike Becker <universe@uap-core.de>
parents:
615
diff
changeset
|
939 | |
630
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
940 | static void cx_arl_iter_next(void *it) { |
853
d4baf4dd55c3
simplify iterator structures
Mike Becker <universe@uap-core.de>
parents:
850
diff
changeset
|
941 | 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
|
942 | 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
|
943 | iter->base.remove = false; |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
944 | cx_arl_remove(iter->src_handle.m, iter->index, 1, NULL); |
616
af7d8a29fbc5
#219 array list: add iterator
Mike Becker <universe@uap-core.de>
parents:
615
diff
changeset
|
945 | } else { |
af7d8a29fbc5
#219 array list: add iterator
Mike Becker <universe@uap-core.de>
parents:
615
diff
changeset
|
946 | iter->index++; |
620
f220695aded6
#219 improve cx_arl_iter_next
Mike Becker <universe@uap-core.de>
parents:
619
diff
changeset
|
947 | iter->elem_handle = |
f220695aded6
#219 improve cx_arl_iter_next
Mike Becker <universe@uap-core.de>
parents:
619
diff
changeset
|
948 | ((char *) iter->elem_handle) |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
949 | + ((const struct cx_list_s *) iter->src_handle.c)->collection.elem_size; |
616
af7d8a29fbc5
#219 array list: add iterator
Mike Becker <universe@uap-core.de>
parents:
615
diff
changeset
|
950 | } |
af7d8a29fbc5
#219 array list: add iterator
Mike Becker <universe@uap-core.de>
parents:
615
diff
changeset
|
951 | } |
af7d8a29fbc5
#219 array list: add iterator
Mike Becker <universe@uap-core.de>
parents:
615
diff
changeset
|
952 | |
655
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
953 | static void cx_arl_iter_prev(void *it) { |
853
d4baf4dd55c3
simplify iterator structures
Mike Becker <universe@uap-core.de>
parents:
850
diff
changeset
|
954 | struct cx_iterator_s *iter = it; |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
955 | const cx_array_list *list = iter->src_handle.c; |
854
fe0d69d72bcd
fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents:
853
diff
changeset
|
956 | 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
|
957 | iter->base.remove = false; |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
958 | cx_arl_remove(iter->src_handle.m, iter->index, 1, NULL); |
655
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
959 | } |
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
960 | iter->index--; |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
961 | if (iter->index < list->base.collection.size) { |
655
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
962 | iter->elem_handle = ((char *) list->data) |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
963 | + iter->index * list->base.collection.elem_size; |
655
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
964 | } |
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
965 | } |
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
966 | |
630
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
967 | |
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
968 | static struct cx_iterator_s cx_arl_iterator( |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
969 | const struct cx_list_s *list, |
655
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
970 | size_t index, |
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
971 | bool backwards |
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
972 | ) { |
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
973 | struct cx_iterator_s iter; |
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
974 | |
616
af7d8a29fbc5
#219 array list: add iterator
Mike Becker <universe@uap-core.de>
parents:
615
diff
changeset
|
975 | iter.index = index; |
853
d4baf4dd55c3
simplify iterator structures
Mike Becker <universe@uap-core.de>
parents:
850
diff
changeset
|
976 | iter.src_handle.c = list; |
616
af7d8a29fbc5
#219 array list: add iterator
Mike Becker <universe@uap-core.de>
parents:
615
diff
changeset
|
977 | iter.elem_handle = cx_arl_at(list, index); |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
978 | iter.elem_size = list->collection.elem_size; |
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
979 | iter.elem_count = list->collection.size; |
854
fe0d69d72bcd
fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents:
853
diff
changeset
|
980 | iter.base.valid = cx_arl_iter_valid; |
fe0d69d72bcd
fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents:
853
diff
changeset
|
981 | iter.base.current = cx_arl_iter_current; |
fe0d69d72bcd
fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents:
853
diff
changeset
|
982 | iter.base.next = backwards ? cx_arl_iter_prev : cx_arl_iter_next; |
fe0d69d72bcd
fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents:
853
diff
changeset
|
983 | 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
|
984 | iter.base.mutating = false; |
630
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
985 | |
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
986 | return iter; |
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
987 | } |
616
af7d8a29fbc5
#219 array list: add iterator
Mike Becker <universe@uap-core.de>
parents:
615
diff
changeset
|
988 | |
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
989 | static cx_list_class cx_array_list_class = { |
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
990 | cx_arl_destructor, |
641
d402fead3386
add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents:
640
diff
changeset
|
991 | cx_arl_insert_element, |
638
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
992 | cx_arl_insert_array, |
881
1dbbf8c1c42f
add optimized implementation of insert_sorted for array lists
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
993 | cx_arl_insert_sorted, |
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
994 | cx_arl_insert_iter, |
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
995 | cx_arl_remove, |
664
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
996 | cx_arl_clear, |
647
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
643
diff
changeset
|
997 | cx_arl_swap, |
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
998 | cx_arl_at, |
764
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
999 | cx_arl_find_remove, |
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1000 | cx_arl_sort, |
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1001 | cx_arl_compare, |
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1002 | cx_arl_reverse, |
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1003 | cx_arl_iterator, |
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1004 | }; |
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1005 | |
670
4ad8ea3aee49
allow NULL for allocator and comparator
Mike Becker <universe@uap-core.de>
parents:
667
diff
changeset
|
1006 | CxList *cxArrayListCreate( |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
1007 | const CxAllocator *allocator, |
677
b09aae58bba4
refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents:
676
diff
changeset
|
1008 | cx_compare_func comparator, |
855
35bcb3216c0d
fix inconsistent use of item_size and elem_size
Mike Becker <universe@uap-core.de>
parents:
854
diff
changeset
|
1009 | size_t elem_size, |
606 | 1010 | size_t initial_capacity |
1011 | ) { | |
670
4ad8ea3aee49
allow NULL for allocator and comparator
Mike Becker <universe@uap-core.de>
parents:
667
diff
changeset
|
1012 | if (allocator == NULL) { |
4ad8ea3aee49
allow NULL for allocator and comparator
Mike Becker <universe@uap-core.de>
parents:
667
diff
changeset
|
1013 | allocator = cxDefaultAllocator; |
4ad8ea3aee49
allow NULL for allocator and comparator
Mike Becker <universe@uap-core.de>
parents:
667
diff
changeset
|
1014 | } |
4ad8ea3aee49
allow NULL for allocator and comparator
Mike Becker <universe@uap-core.de>
parents:
667
diff
changeset
|
1015 | |
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1016 | cx_array_list *list = cxCalloc(allocator, 1, sizeof(cx_array_list)); |
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1017 | if (list == NULL) return NULL; |
1111
78eeeb950883
remove API for changing the store_pointer property after list creation
Mike Becker <universe@uap-core.de>
parents:
1089
diff
changeset
|
1018 | cx_list_init((CxList*)list, &cx_array_list_class, |
78eeeb950883
remove API for changing the store_pointer property after list creation
Mike Becker <universe@uap-core.de>
parents:
1089
diff
changeset
|
1019 | allocator, comparator, elem_size); |
677
b09aae58bba4
refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents:
676
diff
changeset
|
1020 | list->capacity = initial_capacity; |
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1021 | |
855
35bcb3216c0d
fix inconsistent use of item_size and elem_size
Mike Becker <universe@uap-core.de>
parents:
854
diff
changeset
|
1022 | // allocate the array after the real elem_size is known |
1111
78eeeb950883
remove API for changing the store_pointer property after list creation
Mike Becker <universe@uap-core.de>
parents:
1089
diff
changeset
|
1023 | list->data = cxCalloc(allocator, initial_capacity, |
78eeeb950883
remove API for changing the store_pointer property after list creation
Mike Becker <universe@uap-core.de>
parents:
1089
diff
changeset
|
1024 | list->base.collection.elem_size); |
1065
6eb7b54975ee
improve coverage metrics
Mike Becker <universe@uap-core.de>
parents:
1047
diff
changeset
|
1025 | if (list->data == NULL) { // LCOV_EXCL_START |
676
d0680a23d850
fix initial storage allocation for array lists created with CX_STORE_POINTERS
Mike Becker <universe@uap-core.de>
parents:
670
diff
changeset
|
1026 | cxFree(allocator, list); |
d0680a23d850
fix initial storage allocation for array lists created with CX_STORE_POINTERS
Mike Becker <universe@uap-core.de>
parents:
670
diff
changeset
|
1027 | return NULL; |
1065
6eb7b54975ee
improve coverage metrics
Mike Becker <universe@uap-core.de>
parents:
1047
diff
changeset
|
1028 | } // LCOV_EXCL_STOP |
676
d0680a23d850
fix initial storage allocation for array lists created with CX_STORE_POINTERS
Mike Becker <universe@uap-core.de>
parents:
670
diff
changeset
|
1029 | |
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
1030 | // configure the reallocator |
953
581ad4fd01e9
add function to create array reallocator that can move arrays from stack to heap
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
1031 | list->reallocator = cx_array_reallocator(allocator, NULL); |
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
1032 | |
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1033 | return (CxList *) list; |
606 | 1034 | } |