Sun, 23 Nov 2025 13:15:19 +0100
optimize sorted insertion by using the infimum instead of the supremum
The reason is that the supremum returns the equal element with the smallest index, and we want the largest.
Therefore, we use the infimum, which already gives us the largest index when there are equal elements, and increase the index by one. The infimum is also guaranteed to exist in that case.
| 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:
1024
diff
changeset
|
44 | size_t n; |
|
1494
f027a95d93f2
add missing test coverage for cx_array_reserve()
Mike Becker <universe@uap-core.de>
parents:
1482
diff
changeset
|
45 | // LCOV_EXCL_START |
|
1322
7be10b57f658
fix critical memory overflow in the stack-based array reallocator
Mike Becker <universe@uap-core.de>
parents:
1319
diff
changeset
|
46 | 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:
1024
diff
changeset
|
47 | errno = EOVERFLOW; |
|
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1024
diff
changeset
|
48 | return NULL; |
|
1494
f027a95d93f2
add missing test coverage for cx_array_reserve()
Mike Becker <universe@uap-core.de>
parents:
1482
diff
changeset
|
49 | } // LCOV_EXCL_STOP |
|
1319
aa1f580f8f59
add convenience macros for using the default allocator - relates to #669
Mike Becker <universe@uap-core.de>
parents:
1318
diff
changeset
|
50 | return cxReallocDefault(array, n); |
|
817
949908c97474
add cx_array_default_reallocator
Mike Becker <universe@uap-core.de>
parents:
807
diff
changeset
|
51 | } |
|
949908c97474
add cx_array_default_reallocator
Mike Becker <universe@uap-core.de>
parents:
807
diff
changeset
|
52 | |
|
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
|
53 | CxArrayReallocator cx_array_default_reallocator_impl = { |
|
1425
83284b289430
remove unnecessary members from the array reallocator struct - fixes #621
Mike Becker <universe@uap-core.de>
parents:
1423
diff
changeset
|
54 | cx_array_default_realloc, NULL, NULL |
|
817
949908c97474
add cx_array_default_reallocator
Mike Becker <universe@uap-core.de>
parents:
807
diff
changeset
|
55 | }; |
|
949908c97474
add cx_array_default_reallocator
Mike Becker <universe@uap-core.de>
parents:
807
diff
changeset
|
56 | |
|
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
|
57 | 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
|
58 | |
|
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 | // 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
|
60 | |
|
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 | 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
|
62 | void *array, |
|
1322
7be10b57f658
fix critical memory overflow in the stack-based array reallocator
Mike Becker <universe@uap-core.de>
parents:
1319
diff
changeset
|
63 | 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
|
64 | 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
|
65 | size_t elem_size, |
|
985
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
66 | 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
|
67 | ) { |
|
1040
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1024
diff
changeset
|
68 | // check for overflow |
|
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1024
diff
changeset
|
69 | size_t n; |
|
1494
f027a95d93f2
add missing test coverage for cx_array_reserve()
Mike Becker <universe@uap-core.de>
parents:
1482
diff
changeset
|
70 | // LCOV_EXCL_START |
|
1322
7be10b57f658
fix critical memory overflow in the stack-based array reallocator
Mike Becker <universe@uap-core.de>
parents:
1319
diff
changeset
|
71 | 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:
1024
diff
changeset
|
72 | errno = EOVERFLOW; |
|
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1024
diff
changeset
|
73 | return NULL; |
|
1494
f027a95d93f2
add missing test coverage for cx_array_reserve()
Mike Becker <universe@uap-core.de>
parents:
1482
diff
changeset
|
74 | } // LCOV_EXCL_STOP |
|
1040
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1024
diff
changeset
|
75 | |
|
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
|
76 | // retrieve the pointer to the actual allocator |
|
1425
83284b289430
remove unnecessary members from the array reallocator struct - fixes #621
Mike Becker <universe@uap-core.de>
parents:
1423
diff
changeset
|
77 | const CxAllocator *al = alloc->allocator; |
|
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
|
78 | |
|
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 | // 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
|
80 | void *newmem; |
|
1425
83284b289430
remove unnecessary members from the array reallocator struct - fixes #621
Mike Becker <universe@uap-core.de>
parents:
1423
diff
changeset
|
81 | if (array == alloc->stack_ptr) { |
|
1040
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1024
diff
changeset
|
82 | 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
|
83 | 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
|
84 | 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
|
85 | } |
|
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 | } else { |
|
1040
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1024
diff
changeset
|
87 | 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
|
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 | 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
|
90 | } |
|
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 | |
|
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 | 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
|
93 | const struct cx_allocator_s *allocator, |
|
1425
83284b289430
remove unnecessary members from the array reallocator struct - fixes #621
Mike Becker <universe@uap-core.de>
parents:
1423
diff
changeset
|
94 | const void *stack_ptr |
|
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
|
95 | ) { |
|
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 | 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
|
97 | 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
|
98 | } |
|
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 | 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
|
100 | cx_array_advanced_realloc, |
|
1425
83284b289430
remove unnecessary members from the array reallocator struct - fixes #621
Mike Becker <universe@uap-core.de>
parents:
1423
diff
changeset
|
101 | allocator, stack_ptr, |
|
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
|
102 | }; |
|
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
|
103 | } |
|
818
2be8fe3d5a2d
add cx_array_add() + fix type of cx_array_default_reallocator
Mike Becker <universe@uap-core.de>
parents:
817
diff
changeset
|
104 | |
|
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
105 | // LOW LEVEL ARRAY LIST FUNCTIONS |
|
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
106 | |
|
1476
79d4c281a63b
add documentation for cx_array_align_capacity() and use it in cx_arl_insert_array()
Mike Becker <universe@uap-core.de>
parents:
1429
diff
changeset
|
107 | /** |
|
1482
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
108 | * Intelligently calculates a new capacity, reserving some more |
|
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
109 | * elements than required to prevent too many allocations. |
|
1476
79d4c281a63b
add documentation for cx_array_align_capacity() and use it in cx_arl_insert_array()
Mike Becker <universe@uap-core.de>
parents:
1429
diff
changeset
|
110 | * |
|
1482
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
111 | * @param current_capacity the current capacity of the array |
|
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
112 | * @param needed_capacity the required capacity of the array |
|
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
113 | * @return the new capacity |
|
1476
79d4c281a63b
add documentation for cx_array_align_capacity() and use it in cx_arl_insert_array()
Mike Becker <universe@uap-core.de>
parents:
1429
diff
changeset
|
114 | */ |
|
1482
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
115 | static size_t cx_array_grow_capacity( |
|
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
116 | size_t current_capacity, |
|
1494
f027a95d93f2
add missing test coverage for cx_array_reserve()
Mike Becker <universe@uap-core.de>
parents:
1482
diff
changeset
|
117 | size_t needed_capacity |
|
1040
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1024
diff
changeset
|
118 | ) { |
|
1482
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
119 | if (current_capacity >= needed_capacity) { |
|
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
120 | return current_capacity; |
|
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
121 | } |
|
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
122 | size_t cap = needed_capacity; |
|
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
123 | size_t alignment; |
|
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
124 | if (cap < 128) alignment = 16; |
|
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
125 | else if (cap < 1024) alignment = 64; |
|
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
126 | else if (cap < 8192) alignment = 512; |
|
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
127 | else alignment = 1024; |
|
1494
f027a95d93f2
add missing test coverage for cx_array_reserve()
Mike Becker <universe@uap-core.de>
parents:
1482
diff
changeset
|
128 | return cap - (cap % alignment) + alignment; |
|
1040
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1024
diff
changeset
|
129 | } |
|
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1024
diff
changeset
|
130 | |
|
999
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
131 | 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
|
132 | void **array, |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
133 | void *size, |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
134 | void *capacity, |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
135 | unsigned width, |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
136 | 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
|
137 | 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
|
138 | CxArrayReallocator *reallocator |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
139 | ) { |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
140 | // assert pointers |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
141 | assert(array != NULL); |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
142 | assert(size != NULL); |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
143 | assert(capacity != NULL); |
|
1089
865c84fef6b4
refine docs for array_list.h - issue #548
Mike Becker <universe@uap-core.de>
parents:
1084
diff
changeset
|
144 | |
|
865c84fef6b4
refine docs for array_list.h - issue #548
Mike Becker <universe@uap-core.de>
parents:
1084
diff
changeset
|
145 | // default reallocator |
|
865c84fef6b4
refine docs for array_list.h - issue #548
Mike Becker <universe@uap-core.de>
parents:
1084
diff
changeset
|
146 | if (reallocator == NULL) { |
|
865c84fef6b4
refine docs for array_list.h - issue #548
Mike Becker <universe@uap-core.de>
parents:
1084
diff
changeset
|
147 | reallocator = cx_array_default_reallocator; |
|
865c84fef6b4
refine docs for array_list.h - issue #548
Mike Becker <universe@uap-core.de>
parents:
1084
diff
changeset
|
148 | } |
|
999
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
149 | |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
150 | // 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
|
151 | size_t oldcap; |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
152 | size_t oldsize; |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
153 | 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
|
154 | 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
|
155 | 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
|
156 | 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
|
157 | 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
|
158 | } 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
|
159 | 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
|
160 | 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
|
161 | 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
|
162 | } 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
|
163 | 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
|
164 | 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
|
165 | 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
|
166 | } |
|
1020
c773da859bad
fix compilation for compilers which don't set __WORDSIZE
Mike Becker <universe@uap-core.de>
parents:
999
diff
changeset
|
167 | #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
|
168 | 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
|
169 | 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
|
170 | 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
|
171 | 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
|
172 | } |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
173 | #endif |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
174 | else { |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
175 | errno = EINVAL; |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
176 | return 1; |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
177 | } |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
178 | |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
179 | // 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
|
180 | 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
|
181 | |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
182 | // check for overflow |
|
1040
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1024
diff
changeset
|
183 | 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
|
184 | errno = EOVERFLOW; |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
185 | return 1; |
|
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 | |
|
1040
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1024
diff
changeset
|
188 | // determine new capacity |
|
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1024
diff
changeset
|
189 | 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:
1024
diff
changeset
|
190 | |
|
999
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
191 | // reallocate if possible |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
192 | if (newcap > oldcap) { |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
193 | 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
|
194 | *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
|
195 | ); |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
196 | if (newmem == NULL) { |
|
1065
6eb7b54975ee
improve coverage metrics
Mike Becker <universe@uap-core.de>
parents:
1047
diff
changeset
|
197 | 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
|
198 | } |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
199 | |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
200 | // store new pointer |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
201 | *array = newmem; |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
202 | |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
203 | // 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
|
204 | 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
|
205 | *(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
|
206 | } else if (width == sizeof(uint16_t)) { |
|
1021
09c6fe8fe3b9
add explicit casts to silence warnings
Mike Becker <universe@uap-core.de>
parents:
1020
diff
changeset
|
207 | *(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
|
208 | } else if (width == sizeof(uint8_t)) { |
|
1021
09c6fe8fe3b9
add explicit casts to silence warnings
Mike Becker <universe@uap-core.de>
parents:
1020
diff
changeset
|
209 | *(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
|
210 | } |
|
1020
c773da859bad
fix compilation for compilers which don't set __WORDSIZE
Mike Becker <universe@uap-core.de>
parents:
999
diff
changeset
|
211 | #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
|
212 | else if (width == sizeof(uint32_t)) { |
|
1021
09c6fe8fe3b9
add explicit casts to silence warnings
Mike Becker <universe@uap-core.de>
parents:
1020
diff
changeset
|
213 | *(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
|
214 | } |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
215 | #endif |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
216 | } |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
217 | |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
218 | return 0; |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
219 | } |
|
84fc42b04d3b
add cx_array_reserve() and several more array convenience functions
Mike Becker <universe@uap-core.de>
parents:
998
diff
changeset
|
220 | |
|
986
38fa7e41194c
simplify cx_array_copy() - fixes #474
Mike Becker <universe@uap-core.de>
parents:
985
diff
changeset
|
221 | int cx_array_copy( |
|
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
222 | 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
|
223 | 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
|
224 | 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
|
225 | unsigned width, |
|
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
226 | size_t index, |
|
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
227 | const void *src, |
|
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
228 | size_t elem_size, |
|
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
229 | 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
|
230 | CxArrayReallocator *reallocator |
|
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
231 | ) { |
|
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
232 | // assert pointers |
|
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
233 | assert(target != NULL); |
|
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
234 | assert(size != NULL); |
|
986
38fa7e41194c
simplify cx_array_copy() - fixes #474
Mike Becker <universe@uap-core.de>
parents:
985
diff
changeset
|
235 | assert(capacity != NULL); |
|
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
236 | assert(src != NULL); |
|
1089
865c84fef6b4
refine docs for array_list.h - issue #548
Mike Becker <universe@uap-core.de>
parents:
1084
diff
changeset
|
237 | |
|
865c84fef6b4
refine docs for array_list.h - issue #548
Mike Becker <universe@uap-core.de>
parents:
1084
diff
changeset
|
238 | // default reallocator |
|
865c84fef6b4
refine docs for array_list.h - issue #548
Mike Becker <universe@uap-core.de>
parents:
1084
diff
changeset
|
239 | if (reallocator == NULL) { |
|
865c84fef6b4
refine docs for array_list.h - issue #548
Mike Becker <universe@uap-core.de>
parents:
1084
diff
changeset
|
240 | reallocator = cx_array_default_reallocator; |
|
865c84fef6b4
refine docs for array_list.h - issue #548
Mike Becker <universe@uap-core.de>
parents:
1084
diff
changeset
|
241 | } |
|
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
242 | |
|
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 | // 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
|
244 | 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
|
245 | 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
|
246 | 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
|
247 | 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
|
248 | 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
|
249 | 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
|
250 | 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
|
251 | } 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
|
252 | 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
|
253 | 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
|
254 | 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
|
255 | } 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
|
256 | 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
|
257 | 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
|
258 | 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
|
259 | } |
|
1020
c773da859bad
fix compilation for compilers which don't set __WORDSIZE
Mike Becker <universe@uap-core.de>
parents:
999
diff
changeset
|
260 | #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
|
261 | 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
|
262 | 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
|
263 | 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
|
264 | 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
|
265 | } |
|
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
266 | #endif |
|
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
267 | else { |
|
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
268 | 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
|
269 | 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
|
270 | } |
|
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
271 | |
|
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
272 | // 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
|
273 | assert(*target != NULL || oldcap == 0); |
|
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
274 | |
|
1040
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1024
diff
changeset
|
275 | // check for overflow |
|
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1024
diff
changeset
|
276 | 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:
1024
diff
changeset
|
277 | errno = EOVERFLOW; |
|
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1024
diff
changeset
|
278 | return 1; |
|
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1024
diff
changeset
|
279 | } |
|
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1024
diff
changeset
|
280 | |
|
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
281 | // check if resize is required |
|
1482
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
282 | const size_t minsize = index + elem_count; |
|
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
283 | const size_t newsize = oldsize < minsize ? minsize : oldsize; |
|
998
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
284 | |
|
1482
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
285 | // reallocate if necessary |
|
1494
f027a95d93f2
add missing test coverage for cx_array_reserve()
Mike Becker <universe@uap-core.de>
parents:
1482
diff
changeset
|
286 | const size_t newcap = cx_array_grow_capacity(oldcap, newsize); |
|
1482
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
287 | if (newcap > oldcap) { |
|
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
288 | // 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
|
289 | uintptr_t targetaddr = (uintptr_t) *target; |
|
77efa5163ae5
#219 array list: implement insert
Mike Becker <universe@uap-core.de>
parents:
610
diff
changeset
|
290 | uintptr_t srcaddr = (uintptr_t) src; |
|
77efa5163ae5
#219 array list: implement insert
Mike Becker <universe@uap-core.de>
parents:
610
diff
changeset
|
291 | 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
|
292 | && srcaddr < targetaddr + oldcap * elem_size; |
|
611
77efa5163ae5
#219 array list: implement insert
Mike Becker <universe@uap-core.de>
parents:
610
diff
changeset
|
293 | |
|
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
294 | // perform reallocation |
|
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
295 | 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
|
296 | *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
|
297 | ); |
|
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
298 | if (newmem == NULL) { |
|
1423
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
299 | return 1; // LCOV_EXCL_LINE |
|
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
300 | } |
|
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
301 | |
|
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
302 | // repair src pointer, if necessary |
|
611
77efa5163ae5
#219 array list: implement insert
Mike Becker <universe@uap-core.de>
parents:
610
diff
changeset
|
303 | if (repairsrc) { |
|
77efa5163ae5
#219 array list: implement insert
Mike Becker <universe@uap-core.de>
parents:
610
diff
changeset
|
304 | src = ((char *) newmem) + (srcaddr - targetaddr); |
|
77efa5163ae5
#219 array list: implement insert
Mike Becker <universe@uap-core.de>
parents:
610
diff
changeset
|
305 | } |
|
77efa5163ae5
#219 array list: implement insert
Mike Becker <universe@uap-core.de>
parents:
610
diff
changeset
|
306 | |
|
998
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
307 | // store new pointer |
|
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
308 | *target = newmem; |
|
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
309 | } |
|
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
310 | |
|
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
311 | // determine target pointer |
|
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
312 | char *start = *target; |
|
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
313 | start += index * elem_size; |
|
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
314 | |
|
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
315 | // 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:
1024
diff
changeset
|
316 | // 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
|
317 | 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
|
318 | |
|
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
319 | // 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
|
320 | 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
|
321 | 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
|
322 | *(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
|
323 | *(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
|
324 | } else if (width == sizeof(uint16_t)) { |
|
1021
09c6fe8fe3b9
add explicit casts to silence warnings
Mike Becker <universe@uap-core.de>
parents:
1020
diff
changeset
|
325 | *(uint16_t*) capacity = (uint16_t) newcap; |
|
09c6fe8fe3b9
add explicit casts to silence warnings
Mike Becker <universe@uap-core.de>
parents:
1020
diff
changeset
|
326 | *(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
|
327 | } else if (width == sizeof(uint8_t)) { |
|
1021
09c6fe8fe3b9
add explicit casts to silence warnings
Mike Becker <universe@uap-core.de>
parents:
1020
diff
changeset
|
328 | *(uint8_t*) capacity = (uint8_t) newcap; |
|
09c6fe8fe3b9
add explicit casts to silence warnings
Mike Becker <universe@uap-core.de>
parents:
1020
diff
changeset
|
329 | *(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
|
330 | } |
|
1020
c773da859bad
fix compilation for compilers which don't set __WORDSIZE
Mike Becker <universe@uap-core.de>
parents:
999
diff
changeset
|
331 | #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
|
332 | else if (width == sizeof(uint32_t)) { |
|
1021
09c6fe8fe3b9
add explicit casts to silence warnings
Mike Becker <universe@uap-core.de>
parents:
1020
diff
changeset
|
333 | *(uint32_t*) capacity = (uint32_t) newcap; |
|
09c6fe8fe3b9
add explicit casts to silence warnings
Mike Becker <universe@uap-core.de>
parents:
1020
diff
changeset
|
334 | *(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
|
335 | } |
|
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
336 | #endif |
|
bb196054f3fd
make cx_array_copy() support different types for size/capacity - fixes #492
Mike Becker <universe@uap-core.de>
parents:
995
diff
changeset
|
337 | } |
|
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
338 | |
|
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
339 | // return successfully |
|
986
38fa7e41194c
simplify cx_array_copy() - fixes #474
Mike Becker <universe@uap-core.de>
parents:
985
diff
changeset
|
340 | return 0; |
|
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
341 | } |
|
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
342 | |
|
1419
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
343 | static int cx_array_insert_sorted_impl( |
|
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
344 | void **target, |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
345 | size_t *size, |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
346 | size_t *capacity, |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
347 | 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
|
348 | 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
|
349 | 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
|
350 | size_t elem_count, |
|
1419
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
351 | CxArrayReallocator *reallocator, |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
352 | bool allow_duplicates |
|
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
353 | ) { |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
354 | // assert pointers |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
355 | assert(target != NULL); |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
356 | assert(size != NULL); |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
357 | assert(capacity != NULL); |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
358 | 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
|
359 | assert(sorted_data != NULL); |
|
1089
865c84fef6b4
refine docs for array_list.h - issue #548
Mike Becker <universe@uap-core.de>
parents:
1084
diff
changeset
|
360 | |
|
865c84fef6b4
refine docs for array_list.h - issue #548
Mike Becker <universe@uap-core.de>
parents:
1084
diff
changeset
|
361 | // default reallocator |
|
865c84fef6b4
refine docs for array_list.h - issue #548
Mike Becker <universe@uap-core.de>
parents:
1084
diff
changeset
|
362 | if (reallocator == NULL) { |
|
865c84fef6b4
refine docs for array_list.h - issue #548
Mike Becker <universe@uap-core.de>
parents:
1084
diff
changeset
|
363 | reallocator = cx_array_default_reallocator; |
|
865c84fef6b4
refine docs for array_list.h - issue #548
Mike Becker <universe@uap-core.de>
parents:
1084
diff
changeset
|
364 | } |
|
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
365 | |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
366 | // corner case |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
367 | 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
|
368 | |
|
1040
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1024
diff
changeset
|
369 | // overflow check |
|
1496
1a982f6f2407
add missing exclusions for some allocation error handling (all remaining uncovered lines must be covered eventually)
Mike Becker <universe@uap-core.de>
parents:
1494
diff
changeset
|
370 | // LCOV_EXCL_START |
|
1040
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1024
diff
changeset
|
371 | 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:
1024
diff
changeset
|
372 | errno = EOVERFLOW; |
|
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1024
diff
changeset
|
373 | return 1; |
|
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1024
diff
changeset
|
374 | } |
|
1496
1a982f6f2407
add missing exclusions for some allocation error handling (all remaining uncovered lines must be covered eventually)
Mike Becker <universe@uap-core.de>
parents:
1494
diff
changeset
|
375 | // LCOV_EXCL_STOP |
|
1040
1ecf4dbbc60c
add some more overflow treatment and make sure to set errno properly
Mike Becker <universe@uap-core.de>
parents:
1024
diff
changeset
|
376 | |
|
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
377 | // store some counts |
|
1482
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
378 | const size_t old_size = *size; |
|
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
379 | const size_t old_capacity = *capacity; |
|
1419
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
380 | // the necessary capacity is the worst case assumption, including duplicates |
|
1494
f027a95d93f2
add missing test coverage for cx_array_reserve()
Mike Becker <universe@uap-core.de>
parents:
1482
diff
changeset
|
381 | const size_t needed_capacity = cx_array_grow_capacity(old_capacity, old_size + elem_count); |
|
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
382 | |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
383 | // 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
|
384 | if (needed_capacity > old_capacity) { |
|
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
385 | void *new_mem = reallocator->realloc( |
|
1482
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
386 | *target, old_capacity, needed_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
|
387 | ); |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
388 | 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
|
389 | // 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
|
390 | // 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
|
391 | 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
|
392 | } |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
393 | *target = new_mem; |
|
1482
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
394 | *capacity = needed_capacity; |
|
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
395 | } |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
396 | |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
397 | // 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
|
398 | 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
|
399 | *size = new_size; |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
400 | |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
401 | // 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
|
402 | 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
|
403 | 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
|
404 | char *dest = *target; |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
405 | |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
406 | // 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
|
407 | 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
|
408 | 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
|
409 | |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
410 | // 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
|
411 | // 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
|
412 | 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
|
413 | 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
|
414 | 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
|
415 | 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
|
416 | |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
417 | // 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
|
418 | // copy them interleaving |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
419 | while (si < elem_count && bi < new_size) { |
|
1508
dfc0ddd9571e
optimize sorted insertion by using the infimum instead of the supremum
Mike Becker <universe@uap-core.de>
parents:
1507
diff
changeset
|
420 | // determine how many source elements can be inserted. |
|
dfc0ddd9571e
optimize sorted insertion by using the infimum instead of the supremum
Mike Becker <universe@uap-core.de>
parents:
1507
diff
changeset
|
421 | // the first element that shall not be inserted is the smallest element |
|
dfc0ddd9571e
optimize sorted insertion by using the infimum instead of the supremum
Mike Becker <universe@uap-core.de>
parents:
1507
diff
changeset
|
422 | // that is strictly larger than the first buffered element |
|
dfc0ddd9571e
optimize sorted insertion by using the infimum instead of the supremum
Mike Becker <universe@uap-core.de>
parents:
1507
diff
changeset
|
423 | // (located at the index of the infimum plus one). |
|
dfc0ddd9571e
optimize sorted insertion by using the infimum instead of the supremum
Mike Becker <universe@uap-core.de>
parents:
1507
diff
changeset
|
424 | // the infimum is guaranteed to exist: |
|
dfc0ddd9571e
optimize sorted insertion by using the infimum instead of the supremum
Mike Becker <universe@uap-core.de>
parents:
1507
diff
changeset
|
425 | // - if all src elements are larger, |
|
dfc0ddd9571e
optimize sorted insertion by using the infimum instead of the supremum
Mike Becker <universe@uap-core.de>
parents:
1507
diff
changeset
|
426 | // there is no buffer, and this loop is skipped |
|
dfc0ddd9571e
optimize sorted insertion by using the infimum instead of the supremum
Mike Becker <universe@uap-core.de>
parents:
1507
diff
changeset
|
427 | // - if any src element is smaller or equal, the infimum exists |
|
dfc0ddd9571e
optimize sorted insertion by using the infimum instead of the supremum
Mike Becker <universe@uap-core.de>
parents:
1507
diff
changeset
|
428 | // - when all src elements that are smaller are copied, the second part |
|
dfc0ddd9571e
optimize sorted insertion by using the infimum instead of the supremum
Mike Becker <universe@uap-core.de>
parents:
1507
diff
changeset
|
429 | // of this loop body will copy the remaining buffer (emptying it) |
|
dfc0ddd9571e
optimize sorted insertion by using the infimum instead of the supremum
Mike Becker <universe@uap-core.de>
parents:
1507
diff
changeset
|
430 | // Therefore, the buffer can never contain an element that is smaller |
|
dfc0ddd9571e
optimize sorted insertion by using the infimum instead of the supremum
Mike Becker <universe@uap-core.de>
parents:
1507
diff
changeset
|
431 | // than any element in the source and the infimum exists. |
|
889
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
432 | size_t copy_len, bytes_copied; |
|
1508
dfc0ddd9571e
optimize sorted insertion by using the infimum instead of the supremum
Mike Becker <universe@uap-core.de>
parents:
1507
diff
changeset
|
433 | copy_len = cx_array_binary_search_inf( |
|
dfc0ddd9571e
optimize sorted insertion by using the infimum instead of the supremum
Mike Becker <universe@uap-core.de>
parents:
1507
diff
changeset
|
434 | src, elem_count - si, elem_size, bptr, cmp_func |
|
889
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
435 | ); |
|
1508
dfc0ddd9571e
optimize sorted insertion by using the infimum instead of the supremum
Mike Becker <universe@uap-core.de>
parents:
1507
diff
changeset
|
436 | copy_len++; |
|
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
437 | |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
438 | // copy the source elements |
|
1423
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
439 | if (copy_len > 0) { |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
440 | if (allow_duplicates) { |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
441 | // we can copy the entire chunk |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
442 | bytes_copied = copy_len * elem_size; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
443 | memcpy(dest, src, bytes_copied); |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
444 | dest += bytes_copied; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
445 | src += bytes_copied; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
446 | si += copy_len; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
447 | di += copy_len; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
448 | } else { |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
449 | // first, check the end of the source chunk |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
450 | // for being a duplicate of the bptr |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
451 | const char *end_of_src = src + (copy_len - 1) * elem_size; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
452 | size_t skip_len = 0; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
453 | while (copy_len > 0 && cmp_func(bptr, end_of_src) == 0) { |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
454 | end_of_src -= elem_size; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
455 | skip_len++; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
456 | copy_len--; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
457 | } |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
458 | char *last = dest == *target ? NULL : dest - elem_size; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
459 | // then iterate through the source chunk |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
460 | // and skip all duplicates with the last element in the array |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
461 | size_t more_skipped = 0; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
462 | for (unsigned j = 0; j < copy_len; j++) { |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
463 | if (last != NULL && cmp_func(last, src) == 0) { |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
464 | // duplicate - skip |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
465 | src += elem_size; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
466 | si++; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
467 | more_skipped++; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
468 | } else { |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
469 | memcpy(dest, src, elem_size); |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
470 | src += elem_size; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
471 | last = dest; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
472 | dest += elem_size; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
473 | si++; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
474 | di++; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
475 | } |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
476 | } |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
477 | // skip the previously identified elements as well |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
478 | src += skip_len * elem_size; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
479 | si += skip_len; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
480 | skip_len += more_skipped; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
481 | // reduce the actual size by the number of skipped elements |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
482 | *size -= skip_len; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
483 | } |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
484 | } |
|
889
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
485 | |
|
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
486 | // 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
|
487 | 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
|
488 | |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
489 | // 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
|
490 | 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
|
491 | bptr, |
|
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
492 | new_size - bi, |
|
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
493 | elem_size, |
|
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
494 | src, |
|
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
495 | cmp_func |
|
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
496 | ); |
|
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
497 | |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
498 | // restore the buffered elements |
|
889
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
499 | 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
|
500 | memmove(dest, bptr, bytes_copied); |
|
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
501 | dest += bytes_copied; |
|
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
502 | bptr += bytes_copied; |
|
1419
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
503 | di += copy_len; |
|
889
f549fd9fbd8f
apply binary search in cx_array_insert_sorted()
Mike Becker <universe@uap-core.de>
parents:
888
diff
changeset
|
504 | bi += copy_len; |
|
1423
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
505 | } |
|
1419
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
506 | |
|
1423
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
507 | // still source elements left? |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
508 | if (si < elem_count) { |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
509 | if (allow_duplicates) { |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
510 | // duplicates allowed or nothing inserted yet: simply copy everything |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
511 | memcpy(dest, src, elem_size * (elem_count - si)); |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
512 | } else { |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
513 | if (dest != *target) { |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
514 | // skip all source elements that equal the last element |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
515 | char *last = dest - elem_size; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
516 | while (si < elem_count) { |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
517 | if (last != NULL && cmp_func(last, src) == 0) { |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
518 | src += elem_size; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
519 | si++; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
520 | (*size)--; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
521 | } else { |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
522 | break; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
523 | } |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
524 | } |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
525 | } |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
526 | // we must check the elements in the chunk one by one |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
527 | while (si < elem_count) { |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
528 | // find a chain of elements that can be copied |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
529 | size_t copy_len = 1, skip_len = 0; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
530 | { |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
531 | const char *left_src = src; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
532 | while (si + copy_len < elem_count) { |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
533 | const char *right_src = left_src + elem_size; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
534 | int d = cmp_func(left_src, right_src); |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
535 | if (d < 0) { |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
536 | if (skip_len > 0) { |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
537 | // new larger element found; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
538 | // handle it in the next cycle |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
539 | break; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
540 | } |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
541 | left_src += elem_size; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
542 | copy_len++; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
543 | } else if (d == 0) { |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
544 | left_src += elem_size; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
545 | skip_len++; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
546 | } else { |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
547 | break; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
548 | } |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
549 | } |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
550 | } |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
551 | size_t bytes_copied = copy_len * elem_size; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
552 | memcpy(dest, src, bytes_copied); |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
553 | dest += bytes_copied; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
554 | src += bytes_copied + skip_len * elem_size; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
555 | si += copy_len + skip_len; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
556 | di += copy_len; |
|
9a72258446cd
fixes various bugs related to skipping duplicates in insert_unique - relates to #557
Mike Becker <universe@uap-core.de>
parents:
1419
diff
changeset
|
557 | *size -= skip_len; |
|
1419
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
558 | } |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
559 | } |
|
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
560 | } |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
561 | |
|
1419
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
562 | // buffered elements need to be moved when we skipped duplicates |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
563 | size_t total_skipped = new_size - *size; |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
564 | if (bi < new_size && total_skipped > 0) { |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
565 | // move the remaining buffer to the end of the array |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
566 | memmove(dest, bptr, elem_size * (new_size - bi)); |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
567 | } |
|
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
568 | |
|
986
38fa7e41194c
simplify cx_array_copy() - fixes #474
Mike Becker <universe@uap-core.de>
parents:
985
diff
changeset
|
569 | return 0; |
|
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
570 | } |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
571 | |
|
1419
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
572 | int cx_array_insert_sorted( |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
573 | void **target, |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
574 | size_t *size, |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
575 | size_t *capacity, |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
576 | cx_compare_func cmp_func, |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
577 | const void *sorted_data, |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
578 | size_t elem_size, |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
579 | size_t elem_count, |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
580 | CxArrayReallocator *reallocator |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
581 | ) { |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
582 | return cx_array_insert_sorted_impl(target, size, capacity, |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
583 | cmp_func, sorted_data, elem_size, elem_count, reallocator, true); |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
584 | } |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
585 | |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
586 | int cx_array_insert_unique( |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
587 | void **target, |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
588 | size_t *size, |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
589 | size_t *capacity, |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
590 | cx_compare_func cmp_func, |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
591 | const void *sorted_data, |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
592 | size_t elem_size, |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
593 | size_t elem_count, |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
594 | CxArrayReallocator *reallocator |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
595 | ) { |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
596 | return cx_array_insert_sorted_impl(target, size, capacity, |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
597 | cmp_func, sorted_data, elem_size, elem_count, reallocator, false); |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
598 | } |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
599 | |
|
1507
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
600 | // implementation that finds ANY index |
|
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
601 | static size_t cx_array_binary_search_inf_impl( |
|
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
602 | const void *arr, |
|
884
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
603 | size_t size, |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
604 | 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
|
605 | const void *elem, |
|
884
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
606 | cx_compare_func cmp_func |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
607 | ) { |
| 888 | 608 | // special case: empty array |
| 609 | if (size == 0) return 0; | |
| 610 | ||
|
884
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
611 | // 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
|
612 | int result; |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
613 | |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
614 | // 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
|
615 | const char *array = arr; |
|
884
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
616 | |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
617 | // check the first array element |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
618 | 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
|
619 | 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
|
620 | 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
|
621 | } else if (result == 0) { |
|
884
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
622 | return 0; |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
623 | } |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
624 | |
|
1024
2911c1f4a570
add shortcut to binary search when array size is one
Mike Becker <universe@uap-core.de>
parents:
1021
diff
changeset
|
625 | // 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:
1021
diff
changeset
|
626 | if (size == 1) return 0; |
|
2911c1f4a570
add shortcut to binary search when array size is one
Mike Becker <universe@uap-core.de>
parents:
1021
diff
changeset
|
627 | |
|
884
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
628 | // check the last array element |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
629 | 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
|
630 | if (result >= 0) { |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
631 | return size - 1; |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
632 | } |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
633 | |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
634 | // 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
|
635 | // so start the binary search |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
636 | size_t left_index = 1; |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
637 | size_t right_index = size - 1; |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
638 | size_t pivot_index; |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
639 | |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
640 | while (left_index <= right_index) { |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
641 | 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
|
642 | 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
|
643 | result = cmp_func(elem, arr_elem); |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
644 | if (result == 0) { |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
645 | // found it! |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
646 | return pivot_index; |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
647 | } else if (result < 0) { |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
648 | // 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
|
649 | right_index = pivot_index - 1; |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
650 | } else { |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
651 | // 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
|
652 | left_index = pivot_index + 1; |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
653 | } |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
654 | } |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
655 | |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
656 | // report the largest upper bound |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
657 | 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
|
658 | } |
|
d375d8056262
add cx_array_binary_search() - fixes #424
Mike Becker <universe@uap-core.de>
parents:
883
diff
changeset
|
659 | |
|
1507
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
660 | size_t cx_array_binary_search_inf( |
|
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
661 | const void *arr, |
|
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
662 | size_t size, |
|
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
663 | size_t elem_size, |
|
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
664 | const void *elem, |
|
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
665 | cx_compare_func cmp_func |
|
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
666 | ) { |
|
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
667 | size_t index = cx_array_binary_search_inf_impl( |
|
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
668 | arr, size, elem_size, elem, cmp_func); |
|
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
669 | // in case of equality, report the largest index |
|
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
670 | const char *e = ((const char *) arr) + (index + 1) * elem_size; |
|
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
671 | while (index + 1 < size && cmp_func(e, elem) == 0) { |
|
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
672 | e += elem_size; |
|
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
673 | index++; |
|
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
674 | } |
|
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
675 | return index; |
|
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
676 | } |
|
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
677 | |
|
985
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
678 | size_t cx_array_binary_search( |
|
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
679 | const void *arr, |
|
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
680 | size_t size, |
|
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
681 | size_t elem_size, |
|
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
682 | const void *elem, |
|
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
683 | cx_compare_func cmp_func |
|
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
684 | ) { |
|
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
685 | size_t index = cx_array_binary_search_inf( |
|
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
686 | arr, size, elem_size, elem, cmp_func |
|
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
687 | ); |
|
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
688 | if (index < size && |
|
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
689 | 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
|
690 | return index; |
|
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
691 | } else { |
|
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
692 | return size; |
|
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
693 | } |
|
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
694 | } |
|
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
695 | |
|
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
696 | size_t cx_array_binary_search_sup( |
|
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
697 | const void *arr, |
|
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
698 | size_t size, |
|
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
699 | size_t elem_size, |
|
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
700 | const void *elem, |
|
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
701 | cx_compare_func cmp_func |
|
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
702 | ) { |
|
1507
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
703 | size_t index = cx_array_binary_search_inf_impl( |
|
985
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
704 | arr, size, elem_size, elem, cmp_func |
|
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
705 | ); |
|
1507
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
706 | const char *e = ((const char *) arr) + index * elem_size; |
|
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
707 | if (index == size) { |
|
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
708 | // no infimum means the first element is supremum |
|
985
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
709 | return 0; |
|
1507
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
710 | } else if (cmp_func(e, elem) == 0) { |
|
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
711 | // found an equal element, search the smallest index |
|
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
712 | e -= elem_size; // e now contains the element at index-1 |
|
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
713 | while (index > 0 && cmp_func(e, elem) == 0) { |
|
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
714 | e -= elem_size; |
|
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
715 | index--; |
|
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
716 | } |
|
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
717 | return index; |
|
985
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
718 | } else { |
|
1507
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
719 | // we already have the largest index of the infimum (by design) |
|
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
720 | // the next element is the supremum (or there is no supremum) |
|
f4010cda9a2a
stable return value for binary search when there are duplicates in the array
Mike Becker <universe@uap-core.de>
parents:
1496
diff
changeset
|
721 | return index + 1; |
|
985
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
722 | } |
|
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
723 | } |
|
68754c7de906
major refactoring of attributes
Mike Becker <universe@uap-core.de>
parents:
968
diff
changeset
|
724 | |
|
643
5700ba9154ab
#228 make buffer sizes adjustable at compile time
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
725 | #ifndef CX_ARRAY_SWAP_SBO_SIZE |
|
735
b686d0c98c62
unify the list swap SBO sizes
Mike Becker <universe@uap-core.de>
parents:
708
diff
changeset
|
726 | #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
|
727 | #endif |
|
926
8fdd8d78c14b
fix several survivors of east-const and some missing consts
Mike Becker <universe@uap-core.de>
parents:
919
diff
changeset
|
728 | 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
|
729 | |
|
623
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
730 | void cx_array_swap( |
|
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
731 | void *arr, |
|
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
732 | size_t elem_size, |
|
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
733 | size_t idx1, |
|
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
734 | size_t idx2 |
|
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
735 | ) { |
| 660 | 736 | assert(arr != NULL); |
| 737 | ||
|
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
738 | // short circuit |
|
623
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
739 | if (idx1 == idx2) return; |
|
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
740 | |
|
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
741 | char sbo_mem[CX_ARRAY_SWAP_SBO_SIZE]; |
|
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
742 | void *tmp; |
|
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
743 | |
|
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
744 | // 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
|
745 | 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
|
746 | tmp = cxMallocDefault(elem_size); |
|
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
747 | // 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
|
748 | if (tmp == NULL) abort(); |
|
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
749 | } else { |
|
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
750 | tmp = sbo_mem; |
|
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
751 | } |
|
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
752 | |
|
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
753 | // calculate memory locations |
|
623
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
754 | char *left = arr, *right = arr; |
|
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
755 | left += idx1 * elem_size; |
|
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
756 | right += idx2 * elem_size; |
|
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
757 | |
|
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
758 | // three-way swap |
|
623
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
759 | memcpy(tmp, left, elem_size); |
|
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
760 | memcpy(left, right, elem_size); |
|
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
761 | memcpy(right, tmp, elem_size); |
|
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
762 | |
|
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
763 | // free dynamic memory, if it was needed |
|
623
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
764 | 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
|
765 | cxFreeDefault(tmp); |
|
623
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
766 | } |
|
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
767 | } |
|
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
768 | |
|
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
769 | // HIGH LEVEL ARRAY LIST FUNCTIONS |
|
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
770 | |
|
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
771 | typedef struct { |
|
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
772 | struct cx_list_s base; |
|
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
773 | 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
|
774 | 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
|
775 | CxArrayReallocator reallocator; |
|
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
776 | } cx_array_list; |
|
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
777 | |
|
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
778 | 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
|
779 | 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
|
780 | |
|
1caed6c9ba68
fix inconsistent destructor requirements for list and map classes
Mike Becker <universe@uap-core.de>
parents:
699
diff
changeset
|
781 | char *ptr = arl->data; |
|
1caed6c9ba68
fix inconsistent destructor requirements for list and map classes
Mike Becker <universe@uap-core.de>
parents:
699
diff
changeset
|
782 | |
|
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
783 | 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
|
784 | 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
|
785 | 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
|
786 | 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
|
787 | } |
|
1caed6c9ba68
fix inconsistent destructor requirements for list and map classes
Mike Becker <universe@uap-core.de>
parents:
699
diff
changeset
|
788 | } |
|
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
789 | 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
|
790 | 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
|
791 | 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
|
792 | 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
|
793 | } |
|
1caed6c9ba68
fix inconsistent destructor requirements for list and map classes
Mike Becker <universe@uap-core.de>
parents:
699
diff
changeset
|
794 | } |
|
1caed6c9ba68
fix inconsistent destructor requirements for list and map classes
Mike Becker <universe@uap-core.de>
parents:
699
diff
changeset
|
795 | |
|
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
796 | 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
|
797 | cxFree(list->collection.allocator, list); |
|
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
798 | } |
|
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
799 | |
|
638
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
800 | static size_t cx_arl_insert_array( |
|
629
6c81ee4f11ad
#224 add cxListAddArray()
Mike Becker <universe@uap-core.de>
parents:
628
diff
changeset
|
801 | struct cx_list_s *list, |
|
638
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
802 | size_t index, |
|
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
803 | const void *array, |
|
629
6c81ee4f11ad
#224 add cxListAddArray()
Mike Becker <universe@uap-core.de>
parents:
628
diff
changeset
|
804 | size_t n |
|
6c81ee4f11ad
#224 add cxListAddArray()
Mike Becker <universe@uap-core.de>
parents:
628
diff
changeset
|
805 | ) { |
|
638
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
806 | // 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
|
807 | 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
|
808 | |
|
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
809 | // get a correctly typed pointer to the list |
|
629
6c81ee4f11ad
#224 add cxListAddArray()
Mike Becker <universe@uap-core.de>
parents:
628
diff
changeset
|
810 | cx_array_list *arl = (cx_array_list *) list; |
|
638
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
811 | |
|
1316
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
812 | // 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
|
813 | if (arl->capacity < list->collection.size + n) { |
|
1494
f027a95d93f2
add missing test coverage for cx_array_reserve()
Mike Becker <universe@uap-core.de>
parents:
1482
diff
changeset
|
814 | const size_t new_capacity = cx_array_grow_capacity(arl->capacity,list->collection.size + n); |
|
1316
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
815 | 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
|
816 | 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
|
817 | &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
|
818 | 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
|
819 | ) { |
|
1496
1a982f6f2407
add missing exclusions for some allocation error handling (all remaining uncovered lines must be covered eventually)
Mike Becker <universe@uap-core.de>
parents:
1494
diff
changeset
|
820 | return 0; // LCOV_EXCL_LINE |
|
638
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
821 | } |
|
1316
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
822 | arl->capacity = new_capacity; |
|
638
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
823 | } |
|
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
824 | |
|
1316
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
825 | // 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
|
826 | 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
|
827 | 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
|
828 | |
|
1316
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
829 | // 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
|
830 | 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
|
831 | 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
|
832 | 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
|
833 | 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
|
834 | } |
|
1316
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
835 | |
|
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
836 | // 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
|
837 | 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
|
838 | 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
|
839 | } |
|
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
840 | 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
|
841 | |
|
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
842 | return n; |
|
629
6c81ee4f11ad
#224 add cxListAddArray()
Mike Becker <universe@uap-core.de>
parents:
628
diff
changeset
|
843 | } |
|
6c81ee4f11ad
#224 add cxListAddArray()
Mike Becker <universe@uap-core.de>
parents:
628
diff
changeset
|
844 | |
|
881
1dbbf8c1c42f
add optimized implementation of insert_sorted for array lists
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
845 | 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
|
846 | 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
|
847 | 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
|
848 | size_t n |
|
1dbbf8c1c42f
add optimized implementation of insert_sorted for array lists
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
849 | ) { |
|
883
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
850 | // 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
|
851 | 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
|
852 | |
|
986
38fa7e41194c
simplify cx_array_copy() - fixes #474
Mike Becker <universe@uap-core.de>
parents:
985
diff
changeset
|
853 | 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
|
854 | &arl->data, |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
855 | &list->collection.size, |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
856 | &arl->capacity, |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
857 | list->collection.cmpfunc, |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
858 | sorted_data, |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
859 | 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
|
860 | n, |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
861 | &arl->reallocator |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
862 | )) { |
|
3012e9b4214e
add low level cx_array_insert_sorted() and convenience macros
Mike Becker <universe@uap-core.de>
parents:
881
diff
changeset
|
863 | // array list implementation is "all or nothing" |
|
1496
1a982f6f2407
add missing exclusions for some allocation error handling (all remaining uncovered lines must be covered eventually)
Mike Becker <universe@uap-core.de>
parents:
1494
diff
changeset
|
864 | return 0; // LCOV_EXCL_LINE |
|
986
38fa7e41194c
simplify cx_array_copy() - fixes #474
Mike Becker <universe@uap-core.de>
parents:
985
diff
changeset
|
865 | } else { |
|
38fa7e41194c
simplify cx_array_copy() - fixes #474
Mike Becker <universe@uap-core.de>
parents:
985
diff
changeset
|
866 | return n; |
|
881
1dbbf8c1c42f
add optimized implementation of insert_sorted for array lists
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
867 | } |
|
1dbbf8c1c42f
add optimized implementation of insert_sorted for array lists
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
868 | } |
|
1dbbf8c1c42f
add optimized implementation of insert_sorted for array lists
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
869 | |
|
1419
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
870 | static size_t cx_arl_insert_unique( |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
871 | struct cx_list_s *list, |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
872 | const void *sorted_data, |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
873 | size_t n |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
874 | ) { |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
875 | // get a correctly typed pointer to the list |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
876 | cx_array_list *arl = (cx_array_list *) list; |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
877 | |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
878 | if (cx_array_insert_unique( |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
879 | &arl->data, |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
880 | &list->collection.size, |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
881 | &arl->capacity, |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
882 | list->collection.cmpfunc, |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
883 | sorted_data, |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
884 | list->collection.elem_size, |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
885 | n, |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
886 | &arl->reallocator |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
887 | )) { |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
888 | // array list implementation is "all or nothing" |
|
1496
1a982f6f2407
add missing exclusions for some allocation error handling (all remaining uncovered lines must be covered eventually)
Mike Becker <universe@uap-core.de>
parents:
1494
diff
changeset
|
889 | return 0; // LCOV_EXCL_LINE |
|
1419
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
890 | } else { |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
891 | return n; |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
892 | } |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
893 | } |
|
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
894 | |
|
1316
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
895 | 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
|
896 | struct cx_list_s *list, |
|
d402fead3386
add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents:
640
diff
changeset
|
897 | size_t index, |
|
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
898 | const void *element |
|
641
d402fead3386
add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents:
640
diff
changeset
|
899 | ) { |
|
1316
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
900 | 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
|
901 | 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
|
902 | } else { |
|
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
903 | 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
|
904 | } |
|
641
d402fead3386
add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents:
640
diff
changeset
|
905 | } |
|
d402fead3386
add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents:
640
diff
changeset
|
906 | |
|
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
907 | static int cx_arl_insert_iter( |
|
853
d4baf4dd55c3
simplify iterator structures
Mike Becker <universe@uap-core.de>
parents:
850
diff
changeset
|
908 | 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
|
909 | const void *elem, |
|
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
910 | int prepend |
|
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
911 | ) { |
|
1429
6e0c3a8a914a
remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents:
1425
diff
changeset
|
912 | struct cx_list_s *list = iter->src_handle; |
|
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
913 | 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
|
914 | 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
|
915 | iter->index + 1 - prepend, elem) == NULL) { |
|
1496
1a982f6f2407
add missing exclusions for some allocation error handling (all remaining uncovered lines must be covered eventually)
Mike Becker <universe@uap-core.de>
parents:
1494
diff
changeset
|
916 | return 1; // LCOV_EXCL_LINE |
|
1316
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
917 | } |
|
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
918 | 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
|
919 | 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
|
920 | 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
|
921 | 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
|
922 | } |
|
1316
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
923 | return 0; |
|
619
5e58187ac707
#219 array list: implement insert via iterator
Mike Becker <universe@uap-core.de>
parents:
616
diff
changeset
|
924 | } 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
|
925 | if (cx_arl_insert_element(list, list->collection.size, elem) == NULL) { |
|
1496
1a982f6f2407
add missing exclusions for some allocation error handling (all remaining uncovered lines must be covered eventually)
Mike Becker <universe@uap-core.de>
parents:
1494
diff
changeset
|
926 | return 1; // LCOV_EXCL_LINE |
|
874
cdce47f34d48
fix inserting via iterator correctly increases element count
Mike Becker <universe@uap-core.de>
parents:
856
diff
changeset
|
927 | } |
|
1316
c41538edfcef
add cxListEmplace() and cxListEmplaceAt() plus some improvements to the array list implementation
Mike Becker <universe@uap-core.de>
parents:
1163
diff
changeset
|
928 | 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
|
929 | 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
|
930 | return 0; |
|
619
5e58187ac707
#219 array list: implement insert via iterator
Mike Becker <universe@uap-core.de>
parents:
616
diff
changeset
|
931 | } |
|
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
932 | } |
|
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
933 | |
|
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
934 | static size_t cx_arl_remove( |
|
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
935 | 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
|
936 | 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
|
937 | 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
|
938 | void *targetbuf |
|
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
939 | ) { |
|
664
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
940 | 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
|
941 | |
|
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
942 | // 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
|
943 | 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
|
944 | 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
|
945 | remove = 0; |
|
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
946 | } 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
|
947 | 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
|
948 | } else { |
|
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
949 | remove = num; |
|
613
85c08391a090
#219 array list: implement remove
Mike Becker <universe@uap-core.de>
parents:
612
diff
changeset
|
950 | } |
|
85c08391a090
#219 array list: implement remove
Mike Becker <universe@uap-core.de>
parents:
612
diff
changeset
|
951 | |
|
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
952 | // easy exit |
|
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
953 | 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
|
954 | |
|
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
955 | // 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
|
956 | 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
|
957 | 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
|
958 | 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
|
959 | list, |
|
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
960 | ((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
|
961 | ); |
|
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
962 | } |
|
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
963 | } else { |
|
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
964 | memcpy( |
|
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
965 | targetbuf, |
|
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
966 | ((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
|
967 | 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
|
968 | ); |
|
624
b0bdff7d8203
#219: cx_arl_remove short-circuit for last element
Mike Becker <universe@uap-core.de>
parents:
623
diff
changeset
|
969 | } |
|
613
85c08391a090
#219 array list: implement remove
Mike Becker <universe@uap-core.de>
parents:
612
diff
changeset
|
970 | |
|
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
971 | // 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
|
972 | 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
|
973 | 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
|
974 | return remove; |
|
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
975 | } |
|
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
976 | |
|
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
977 | // just move the elements to the left |
|
1065
6eb7b54975ee
improve coverage metrics
Mike Becker <universe@uap-core.de>
parents:
1047
diff
changeset
|
978 | cx_array_copy( |
|
613
85c08391a090
#219 array list: implement remove
Mike Becker <universe@uap-core.de>
parents:
612
diff
changeset
|
979 | &arl->data, |
|
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
980 | &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
|
981 | &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
|
982 | 0, |
|
613
85c08391a090
#219 array list: implement remove
Mike Becker <universe@uap-core.de>
parents:
612
diff
changeset
|
983 | index, |
|
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
984 | ((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
|
985 | 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
|
986 | list->collection.size - index - remove, |
|
613
85c08391a090
#219 array list: implement remove
Mike Becker <universe@uap-core.de>
parents:
612
diff
changeset
|
987 | &arl->reallocator |
|
85c08391a090
#219 array list: implement remove
Mike Becker <universe@uap-core.de>
parents:
612
diff
changeset
|
988 | ); |
|
820
8b86ee2e09bb
remove check that is always true in cx_arl_remove()
Mike Becker <universe@uap-core.de>
parents:
819
diff
changeset
|
989 | |
|
8b86ee2e09bb
remove check that is always true in cx_arl_remove()
Mike Becker <universe@uap-core.de>
parents:
819
diff
changeset
|
990 | // 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
|
991 | 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
|
992 | |
|
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
993 | return remove; |
|
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
994 | } |
|
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
995 | |
|
664
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
996 | 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
|
997 | 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
|
998 | |
|
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
999 | 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
|
1000 | char *ptr = arl->data; |
|
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
1001 | |
|
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
1002 | 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
|
1003 | 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
|
1004 | 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
|
1005 | 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
|
1006 | } |
|
677
b09aae58bba4
refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents:
676
diff
changeset
|
1007 | } |
|
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
1008 | 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
|
1009 | 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
|
1010 | 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
|
1011 | 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
|
1012 | } |
|
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
1013 | } |
|
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
|
1014 | |
|
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
1015 | 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
|
1016 | 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
|
1017 | } |
|
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
1018 | |
|
653
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
643
diff
changeset
|
1019 | static int cx_arl_swap( |
|
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
643
diff
changeset
|
1020 | struct cx_list_s *list, |
|
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
643
diff
changeset
|
1021 | size_t i, |
|
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
643
diff
changeset
|
1022 | size_t j |
|
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
643
diff
changeset
|
1023 | ) { |
|
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
1024 | if (i >= list->collection.size || j >= list->collection.size) return 1; |
|
653
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
643
diff
changeset
|
1025 | 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
|
1026 | cx_array_swap(arl->data, list->collection.elem_size, i, j); |
|
653
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
643
diff
changeset
|
1027 | return 0; |
|
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
643
diff
changeset
|
1028 | } |
|
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
643
diff
changeset
|
1029 | |
|
610
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
1030 | 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
|
1031 | const struct cx_list_s *list, |
|
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1032 | size_t index |
|
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1033 | ) { |
|
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
1034 | 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
|
1035 | 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
|
1036 | 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
|
1037 | 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
|
1038 | } else { |
|
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
1039 | return NULL; |
|
de5d3ee6435f
#219 array list: implement add and at
Mike Becker <universe@uap-core.de>
parents:
607
diff
changeset
|
1040 | } |
|
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1041 | } |
|
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1042 | |
|
1162
e3bb67b72d33
remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents:
1111
diff
changeset
|
1043 | 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
|
1044 | 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
|
1045 | const void *elem, |
|
764
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
1046 | bool remove |
|
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1047 | ) { |
|
1163
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
1048 | 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
|
1049 | 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
|
1050 | 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
|
1051 | 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
|
1052 | |
|
1163
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
1053 | // 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
|
1054 | 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
|
1055 | 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
|
1056 | cur, |
|
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
1057 | list->collection.size, |
|
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
1058 | 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
|
1059 | elem, |
|
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
1060 | list->collection.cmpfunc |
|
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
1061 | ); |
|
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
1062 | 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
|
1063 | 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
|
1064 | } |
|
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
1065 | return i; |
|
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
1066 | } |
|
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
1067 | |
|
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
1068 | // fallback: linear search |
|
1162
e3bb67b72d33
remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents:
1111
diff
changeset
|
1069 | 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
|
1070 | 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
|
1071 | if (remove) { |
|
1163
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
1072 | 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
|
1073 | } |
|
1163
68ff0839bc6a
optimize cx_arl_find_remove for sorted arrays - fixes #547
Mike Becker <universe@uap-core.de>
parents:
1162
diff
changeset
|
1074 | return i; |
|
614
7aaec630cf15
#219 array list: implement find
Mike Becker <universe@uap-core.de>
parents:
613
diff
changeset
|
1075 | } |
|
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
1076 | cur += list->collection.elem_size; |
|
614
7aaec630cf15
#219 array list: implement find
Mike Becker <universe@uap-core.de>
parents:
613
diff
changeset
|
1077 | } |
|
1162
e3bb67b72d33
remove dependency to ssize_t - fixes #552
Mike Becker <universe@uap-core.de>
parents:
1111
diff
changeset
|
1078 | return list->collection.size; |
|
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1079 | } |
|
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1080 | |
|
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1081 | 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
|
1082 | assert(list->collection.cmpfunc != NULL); |
|
615
b52b66dcd44b
#219 array list: implement sort
Mike Becker <universe@uap-core.de>
parents:
614
diff
changeset
|
1083 | 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
|
1084 | list->collection.size, |
|
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
1085 | 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
|
1086 | list->collection.cmpfunc |
|
615
b52b66dcd44b
#219 array list: implement sort
Mike Becker <universe@uap-core.de>
parents:
614
diff
changeset
|
1087 | ); |
|
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1088 | } |
|
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1089 | |
|
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1090 | 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
|
1091 | 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
|
1092 | const struct cx_list_s *other |
|
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1093 | ) { |
|
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
1094 | 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
|
1095 | 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
|
1096 | 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
|
1097 | 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
|
1098 | 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
|
1099 | 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
|
1100 | if (d != 0) { |
|
3d93cd78aa20
#219 array list: implement compare member func
Mike Becker <universe@uap-core.de>
parents:
620
diff
changeset
|
1101 | return d; |
|
3d93cd78aa20
#219 array list: implement compare member func
Mike Becker <universe@uap-core.de>
parents:
620
diff
changeset
|
1102 | } |
|
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
1103 | 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
|
1104 | right += other->collection.elem_size; |
|
622
3d93cd78aa20
#219 array list: implement compare member func
Mike Becker <universe@uap-core.de>
parents:
620
diff
changeset
|
1105 | } |
|
3d93cd78aa20
#219 array list: implement compare member func
Mike Becker <universe@uap-core.de>
parents:
620
diff
changeset
|
1106 | return 0; |
|
3d93cd78aa20
#219 array list: implement compare member func
Mike Becker <universe@uap-core.de>
parents:
620
diff
changeset
|
1107 | } else { |
|
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
1108 | 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
|
1109 | } |
|
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1110 | } |
|
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1111 | |
|
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1112 | 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
|
1113 | 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
|
1114 | 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
|
1115 | size_t half = list->collection.size / 2; |
|
623
21082350a590
#219 array list: implement reverse
Mike Becker <universe@uap-core.de>
parents:
622
diff
changeset
|
1116 | 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
|
1117 | 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
|
1118 | } |
|
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1119 | } |
|
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1120 | |
|
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
1121 | 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
|
1122 | const struct cx_iterator_s *iter = it; |
|
1429
6e0c3a8a914a
remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents:
1425
diff
changeset
|
1123 | const struct cx_list_s *list = iter->src_handle; |
|
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
1124 | return iter->index < list->collection.size; |
|
616
af7d8a29fbc5
#219 array list: add iterator
Mike Becker <universe@uap-core.de>
parents:
615
diff
changeset
|
1125 | } |
|
af7d8a29fbc5
#219 array list: add iterator
Mike Becker <universe@uap-core.de>
parents:
615
diff
changeset
|
1126 | |
|
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
1127 | 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
|
1128 | const struct cx_iterator_s *iter = it; |
|
616
af7d8a29fbc5
#219 array list: add iterator
Mike Becker <universe@uap-core.de>
parents:
615
diff
changeset
|
1129 | return iter->elem_handle; |
|
af7d8a29fbc5
#219 array list: add iterator
Mike Becker <universe@uap-core.de>
parents:
615
diff
changeset
|
1130 | } |
|
af7d8a29fbc5
#219 array list: add iterator
Mike Becker <universe@uap-core.de>
parents:
615
diff
changeset
|
1131 | |
|
630
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
1132 | static void cx_arl_iter_next(void *it) { |
|
853
d4baf4dd55c3
simplify iterator structures
Mike Becker <universe@uap-core.de>
parents:
850
diff
changeset
|
1133 | 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
|
1134 | 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
|
1135 | iter->base.remove = false; |
|
1429
6e0c3a8a914a
remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents:
1425
diff
changeset
|
1136 | cx_arl_remove(iter->src_handle, iter->index, 1, NULL); |
|
1387
9bdd053820b7
the elem_count member of an iterator was not updated after removing an element flagged by cxIteratorFlagRemoval() - fixes #728
Mike Becker <universe@uap-core.de>
parents:
1322
diff
changeset
|
1137 | iter->elem_count--; |
|
616
af7d8a29fbc5
#219 array list: add iterator
Mike Becker <universe@uap-core.de>
parents:
615
diff
changeset
|
1138 | } else { |
|
af7d8a29fbc5
#219 array list: add iterator
Mike Becker <universe@uap-core.de>
parents:
615
diff
changeset
|
1139 | iter->index++; |
|
620
f220695aded6
#219 improve cx_arl_iter_next
Mike Becker <universe@uap-core.de>
parents:
619
diff
changeset
|
1140 | iter->elem_handle = |
|
f220695aded6
#219 improve cx_arl_iter_next
Mike Becker <universe@uap-core.de>
parents:
619
diff
changeset
|
1141 | ((char *) iter->elem_handle) |
|
1429
6e0c3a8a914a
remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents:
1425
diff
changeset
|
1142 | + ((const struct cx_list_s *) iter->src_handle)->collection.elem_size; |
|
616
af7d8a29fbc5
#219 array list: add iterator
Mike Becker <universe@uap-core.de>
parents:
615
diff
changeset
|
1143 | } |
|
af7d8a29fbc5
#219 array list: add iterator
Mike Becker <universe@uap-core.de>
parents:
615
diff
changeset
|
1144 | } |
|
af7d8a29fbc5
#219 array list: add iterator
Mike Becker <universe@uap-core.de>
parents:
615
diff
changeset
|
1145 | |
|
655
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
1146 | static void cx_arl_iter_prev(void *it) { |
|
853
d4baf4dd55c3
simplify iterator structures
Mike Becker <universe@uap-core.de>
parents:
850
diff
changeset
|
1147 | 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
|
1148 | 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
|
1149 | iter->base.remove = false; |
|
1429
6e0c3a8a914a
remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents:
1425
diff
changeset
|
1150 | cx_arl_remove(iter->src_handle, iter->index, 1, NULL); |
|
1387
9bdd053820b7
the elem_count member of an iterator was not updated after removing an element flagged by cxIteratorFlagRemoval() - fixes #728
Mike Becker <universe@uap-core.de>
parents:
1322
diff
changeset
|
1151 | iter->elem_count--; |
|
655
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
1152 | } |
|
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
1153 | iter->index--; |
|
1429
6e0c3a8a914a
remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents:
1425
diff
changeset
|
1154 | cx_array_list *list = iter->src_handle; |
|
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
1155 | if (iter->index < list->base.collection.size) { |
|
655
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
1156 | 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
|
1157 | + iter->index * list->base.collection.elem_size; |
|
655
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
1158 | } |
|
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
1159 | } |
|
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
1160 | |
|
1482
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
1161 | static int cx_arl_change_capacity( |
|
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
1162 | struct cx_list_s *list, |
|
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
1163 | size_t new_capacity |
|
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
1164 | ) { |
|
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
1165 | cx_array_list *arl = (cx_array_list *)list; |
|
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
1166 | return cxReallocateArray(list->collection.allocator, |
|
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
1167 | &arl->data, new_capacity, list->collection.elem_size); |
|
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
1168 | } |
|
630
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
1169 | |
|
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1170 | 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
|
1171 | const struct cx_list_s *list, |
|
655
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
1172 | size_t index, |
|
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
1173 | bool backwards |
|
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1174 | ) { |
|
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1175 | struct cx_iterator_s iter; |
|
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1176 | |
|
616
af7d8a29fbc5
#219 array list: add iterator
Mike Becker <universe@uap-core.de>
parents:
615
diff
changeset
|
1177 | iter.index = index; |
|
1429
6e0c3a8a914a
remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents:
1425
diff
changeset
|
1178 | iter.src_handle = (void*)list; |
|
616
af7d8a29fbc5
#219 array list: add iterator
Mike Becker <universe@uap-core.de>
parents:
615
diff
changeset
|
1179 | 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
|
1180 | 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
|
1181 | 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
|
1182 | 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
|
1183 | 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
|
1184 | 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
|
1185 | iter.base.remove = false; |
|
1429
6e0c3a8a914a
remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents:
1425
diff
changeset
|
1186 | iter.base.allow_remove = true; |
|
630
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
1187 | |
|
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
1188 | return iter; |
|
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
1189 | } |
|
616
af7d8a29fbc5
#219 array list: add iterator
Mike Becker <universe@uap-core.de>
parents:
615
diff
changeset
|
1190 | |
|
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1191 | 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
|
1192 | cx_arl_destructor, |
|
641
d402fead3386
add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents:
640
diff
changeset
|
1193 | cx_arl_insert_element, |
|
638
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
1194 | 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
|
1195 | cx_arl_insert_sorted, |
|
1419
e46406fd1b3c
add functions to insert elements into lists/arrays without duplicates - resolves #557
Mike Becker <universe@uap-core.de>
parents:
1387
diff
changeset
|
1196 | cx_arl_insert_unique, |
|
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1197 | cx_arl_insert_iter, |
|
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1198 | cx_arl_remove, |
|
664
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
1199 | cx_arl_clear, |
|
653
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
643
diff
changeset
|
1200 | cx_arl_swap, |
|
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1201 | cx_arl_at, |
|
764
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
1202 | cx_arl_find_remove, |
|
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1203 | cx_arl_sort, |
|
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1204 | cx_arl_compare, |
|
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1205 | cx_arl_reverse, |
|
1482
6769cb72521b
implement a new allocation strategy for array lists and add cxListReserve() and cxListShrink()
Mike Becker <universe@uap-core.de>
parents:
1476
diff
changeset
|
1206 | cx_arl_change_capacity, |
|
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1207 | cx_arl_iterator, |
|
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1208 | }; |
|
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1209 | |
|
670
4ad8ea3aee49
allow NULL for allocator and comparator
Mike Becker <universe@uap-core.de>
parents:
667
diff
changeset
|
1210 | CxList *cxArrayListCreate( |
|
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
889
diff
changeset
|
1211 | 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
|
1212 | 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
|
1213 | size_t elem_size, |
| 606 | 1214 | size_t initial_capacity |
| 1215 | ) { | |
|
670
4ad8ea3aee49
allow NULL for allocator and comparator
Mike Becker <universe@uap-core.de>
parents:
667
diff
changeset
|
1216 | if (allocator == NULL) { |
|
4ad8ea3aee49
allow NULL for allocator and comparator
Mike Becker <universe@uap-core.de>
parents:
667
diff
changeset
|
1217 | allocator = cxDefaultAllocator; |
|
4ad8ea3aee49
allow NULL for allocator and comparator
Mike Becker <universe@uap-core.de>
parents:
667
diff
changeset
|
1218 | } |
|
4ad8ea3aee49
allow NULL for allocator and comparator
Mike Becker <universe@uap-core.de>
parents:
667
diff
changeset
|
1219 | |
|
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1220 | 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
|
1221 | 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
|
1222 | 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
|
1223 | 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
|
1224 | list->capacity = initial_capacity; |
|
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1225 | |
|
855
35bcb3216c0d
fix inconsistent use of item_size and elem_size
Mike Becker <universe@uap-core.de>
parents:
854
diff
changeset
|
1226 | // 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
|
1227 | 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
|
1228 | list->base.collection.elem_size); |
|
1065
6eb7b54975ee
improve coverage metrics
Mike Becker <universe@uap-core.de>
parents:
1047
diff
changeset
|
1229 | 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
|
1230 | 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
|
1231 | return NULL; |
|
1065
6eb7b54975ee
improve coverage metrics
Mike Becker <universe@uap-core.de>
parents:
1047
diff
changeset
|
1232 | } // 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
|
1233 | |
|
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
627
diff
changeset
|
1234 | // 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
|
1235 | 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
|
1236 | |
|
607
2d99e978dc34
implement array list ctor and dtor
Mike Becker <universe@uap-core.de>
parents:
606
diff
changeset
|
1237 | return (CxList *) list; |
| 606 | 1238 | } |