Sun, 14 Jan 2024 13:50:17 +0100
add constant for reading out strstr sbo size - relates to #343
also fixes the related test which was working with the old SBO size of 256 and was broken after increasing it to 512
398
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
1 | /* |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
3 | * |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
4 | * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved. |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
5 | * |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
6 | * Redistribution and use in source and binary forms, with or without |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
7 | * modification, are permitted provided that the following conditions are met: |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
8 | * |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
9 | * 1. Redistributions of source code must retain the above copyright |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
10 | * notice, this list of conditions and the following disclaimer. |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
11 | * |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
12 | * 2. Redistributions in binary form must reproduce the above copyright |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
13 | * notice, this list of conditions and the following disclaimer in the |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
14 | * documentation and/or other materials provided with the distribution. |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
15 | * |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
26 | * POSSIBILITY OF SUCH DAMAGE. |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
27 | */ |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
28 | |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
29 | #include "cx/linked_list.h" |
509
0d3c6075f82c
#129 - remove test code duplication
Mike Becker <universe@uap-core.de>
parents:
508
diff
changeset
|
30 | #include "cx/utils.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
|
31 | #include "cx/compare.h" |
401
e6a8f7fb0c45
copy list items when they are added to the list
Mike Becker <universe@uap-core.de>
parents:
400
diff
changeset
|
32 | #include <string.h> |
453
bb144d08cd44
add some documentation and changes some signatures
Mike Becker <universe@uap-core.de>
parents:
451
diff
changeset
|
33 | #include <assert.h> |
398
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
34 | |
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
592
diff
changeset
|
35 | // LOW LEVEL LINKED LIST FUNCTIONS |
398
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
36 | |
592
bb69ef3ad1f3
enclose macro arguments in parenthesis
Mike Becker <universe@uap-core.de>
parents:
552
diff
changeset
|
37 | #define CX_LL_PTR(cur, off) (*(void**)(((char*)(cur))+(off))) |
480
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
38 | #define ll_prev(node) CX_LL_PTR(node, loc_prev) |
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
39 | #define ll_next(node) CX_LL_PTR(node, loc_next) |
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
40 | #define ll_advance(node) CX_LL_PTR(node, loc_advance) |
639
309e8b08c60e
temporarily remove pointer lists - see #234
Mike Becker <universe@uap-core.de>
parents:
638
diff
changeset
|
41 | #define ll_data(node) (((char*)(node))+loc_data) |
398
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
42 | |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
43 | void *cx_linked_list_at( |
508
8aea65ae1eaf
#168 - add attributes and const
Mike Becker <universe@uap-core.de>
parents:
503
diff
changeset
|
44 | void const *start, |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
45 | size_t start_index, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
46 | ptrdiff_t loc_advance, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
47 | size_t index |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
48 | ) { |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
49 | assert(start != NULL); |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
50 | assert(loc_advance >= 0); |
438
cd3069757010
add function cx_linked_list_at()
Mike Becker <universe@uap-core.de>
parents:
437
diff
changeset
|
51 | size_t i = start_index; |
508
8aea65ae1eaf
#168 - add attributes and const
Mike Becker <universe@uap-core.de>
parents:
503
diff
changeset
|
52 | void const *cur = start; |
438
cd3069757010
add function cx_linked_list_at()
Mike Becker <universe@uap-core.de>
parents:
437
diff
changeset
|
53 | while (i != index && cur != NULL) { |
480
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
54 | cur = ll_advance(cur); |
438
cd3069757010
add function cx_linked_list_at()
Mike Becker <universe@uap-core.de>
parents:
437
diff
changeset
|
55 | i < index ? i++ : i--; |
cd3069757010
add function cx_linked_list_at()
Mike Becker <universe@uap-core.de>
parents:
437
diff
changeset
|
56 | } |
508
8aea65ae1eaf
#168 - add attributes and const
Mike Becker <universe@uap-core.de>
parents:
503
diff
changeset
|
57 | return (void *) cur; |
438
cd3069757010
add function cx_linked_list_at()
Mike Becker <universe@uap-core.de>
parents:
437
diff
changeset
|
58 | } |
cd3069757010
add function cx_linked_list_at()
Mike Becker <universe@uap-core.de>
parents:
437
diff
changeset
|
59 | |
699
35b2b99ee523
make list find return a negative value when elem not found
Mike Becker <universe@uap-core.de>
parents:
677
diff
changeset
|
60 | ssize_t cx_linked_list_find( |
489
af6be1e123aa
add some const qualifiers
Mike Becker <universe@uap-core.de>
parents:
488
diff
changeset
|
61 | void const *start, |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
62 | ptrdiff_t loc_advance, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
63 | ptrdiff_t loc_data, |
677
b09aae58bba4
refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents:
670
diff
changeset
|
64 | cx_compare_func cmp_func, |
489
af6be1e123aa
add some const qualifiers
Mike Becker <universe@uap-core.de>
parents:
488
diff
changeset
|
65 | void const *elem |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
66 | ) { |
764
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
67 | void *dummy; |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
68 | return cx_linked_list_find_node( |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
69 | &dummy, start, |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
70 | loc_advance, loc_data, |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
71 | cmp_func, elem |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
72 | ); |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
73 | } |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
74 | |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
75 | ssize_t cx_linked_list_find_node( |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
76 | void **result, |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
77 | void const *start, |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
78 | ptrdiff_t loc_advance, |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
79 | ptrdiff_t loc_data, |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
80 | cx_compare_func cmp_func, |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
81 | void const *elem |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
82 | ) { |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
83 | assert(result != NULL); |
480
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
84 | assert(start != NULL); |
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
85 | assert(loc_advance >= 0); |
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
86 | assert(loc_data >= 0); |
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
87 | assert(cmp_func); |
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
88 | |
489
af6be1e123aa
add some const qualifiers
Mike Becker <universe@uap-core.de>
parents:
488
diff
changeset
|
89 | void const *node = start; |
699
35b2b99ee523
make list find return a negative value when elem not found
Mike Becker <universe@uap-core.de>
parents:
677
diff
changeset
|
90 | ssize_t index = 0; |
480
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
91 | do { |
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
92 | void *current = ll_data(node); |
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
93 | if (cmp_func(current, elem) == 0) { |
764
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
94 | *result = (void*) node; |
480
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
95 | return index; |
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
96 | } |
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
97 | node = ll_advance(node); |
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
98 | index++; |
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
99 | } while (node != NULL); |
764
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
100 | *result = NULL; |
699
35b2b99ee523
make list find return a negative value when elem not found
Mike Becker <universe@uap-core.de>
parents:
677
diff
changeset
|
101 | return -1; |
480
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
102 | } |
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
103 | |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
104 | void *cx_linked_list_first( |
508
8aea65ae1eaf
#168 - add attributes and const
Mike Becker <universe@uap-core.de>
parents:
503
diff
changeset
|
105 | void const *node, |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
106 | ptrdiff_t loc_prev |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
107 | ) { |
475
31bf97fdbf71
add cx_linked_list_first() + cx_linked_list_prepend()
Mike Becker <universe@uap-core.de>
parents:
474
diff
changeset
|
108 | return cx_linked_list_last(node, loc_prev); |
31bf97fdbf71
add cx_linked_list_first() + cx_linked_list_prepend()
Mike Becker <universe@uap-core.de>
parents:
474
diff
changeset
|
109 | } |
31bf97fdbf71
add cx_linked_list_first() + cx_linked_list_prepend()
Mike Becker <universe@uap-core.de>
parents:
474
diff
changeset
|
110 | |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
111 | void *cx_linked_list_last( |
508
8aea65ae1eaf
#168 - add attributes and const
Mike Becker <universe@uap-core.de>
parents:
503
diff
changeset
|
112 | void const *node, |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
113 | ptrdiff_t loc_next |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
114 | ) { |
478
599770bb6314
add more nonnull attributes
Mike Becker <universe@uap-core.de>
parents:
477
diff
changeset
|
115 | assert(node != NULL); |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
116 | assert(loc_next >= 0); |
398
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
117 | |
508
8aea65ae1eaf
#168 - add attributes and const
Mike Becker <universe@uap-core.de>
parents:
503
diff
changeset
|
118 | void const *cur = node; |
8aea65ae1eaf
#168 - add attributes and const
Mike Becker <universe@uap-core.de>
parents:
503
diff
changeset
|
119 | void const *last; |
456
227c2eabbef8
change cx_linked_list_last() and add a test for it
Mike Becker <universe@uap-core.de>
parents:
453
diff
changeset
|
120 | do { |
227c2eabbef8
change cx_linked_list_last() and add a test for it
Mike Becker <universe@uap-core.de>
parents:
453
diff
changeset
|
121 | last = cur; |
480
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
122 | } while ((cur = ll_next(cur)) != NULL); |
398
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
123 | |
508
8aea65ae1eaf
#168 - add attributes and const
Mike Becker <universe@uap-core.de>
parents:
503
diff
changeset
|
124 | return (void *) last; |
398
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
125 | } |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
126 | |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
127 | void *cx_linked_list_prev( |
508
8aea65ae1eaf
#168 - add attributes and const
Mike Becker <universe@uap-core.de>
parents:
503
diff
changeset
|
128 | void const *begin, |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
129 | ptrdiff_t loc_next, |
508
8aea65ae1eaf
#168 - add attributes and const
Mike Becker <universe@uap-core.de>
parents:
503
diff
changeset
|
130 | void const *node |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
131 | ) { |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
132 | assert(begin != NULL); |
478
599770bb6314
add more nonnull attributes
Mike Becker <universe@uap-core.de>
parents:
477
diff
changeset
|
133 | assert(node != NULL); |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
134 | assert(loc_next >= 0); |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
135 | if (begin == node) return NULL; |
508
8aea65ae1eaf
#168 - add attributes and const
Mike Becker <universe@uap-core.de>
parents:
503
diff
changeset
|
136 | void const *cur = begin; |
8aea65ae1eaf
#168 - add attributes and const
Mike Becker <universe@uap-core.de>
parents:
503
diff
changeset
|
137 | void const *next; |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
138 | while (1) { |
480
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
139 | next = ll_next(cur); |
508
8aea65ae1eaf
#168 - add attributes and const
Mike Becker <universe@uap-core.de>
parents:
503
diff
changeset
|
140 | if (next == node) return (void *) cur; |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
141 | cur = next; |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
142 | } |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
143 | } |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
144 | |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
145 | void cx_linked_list_link( |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
146 | void *left, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
147 | void *right, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
148 | ptrdiff_t loc_prev, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
149 | ptrdiff_t loc_next |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
150 | ) { |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
151 | assert(loc_next >= 0); |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
152 | ll_next(left) = right; |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
153 | if (loc_prev >= 0) { |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
154 | ll_prev(right) = left; |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
155 | } |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
156 | } |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
157 | |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
158 | void cx_linked_list_unlink( |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
159 | void *left, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
160 | void *right, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
161 | ptrdiff_t loc_prev, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
162 | ptrdiff_t loc_next |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
163 | ) { |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
164 | assert (loc_next >= 0); |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
165 | assert(ll_next(left) == right); |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
166 | ll_next(left) = NULL; |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
167 | if (loc_prev >= 0) { |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
168 | assert(ll_prev(right) == left); |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
169 | ll_prev(right) = NULL; |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
170 | } |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
171 | } |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
172 | |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
173 | void cx_linked_list_add( |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
174 | void **begin, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
175 | void **end, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
176 | ptrdiff_t loc_prev, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
177 | ptrdiff_t loc_next, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
178 | void *new_node |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
179 | ) { |
456
227c2eabbef8
change cx_linked_list_last() and add a test for it
Mike Becker <universe@uap-core.de>
parents:
453
diff
changeset
|
180 | void *last; |
227c2eabbef8
change cx_linked_list_last() and add a test for it
Mike Becker <universe@uap-core.de>
parents:
453
diff
changeset
|
181 | if (end == NULL) { |
227c2eabbef8
change cx_linked_list_last() and add a test for it
Mike Becker <universe@uap-core.de>
parents:
453
diff
changeset
|
182 | assert(begin != NULL); |
478
599770bb6314
add more nonnull attributes
Mike Becker <universe@uap-core.de>
parents:
477
diff
changeset
|
183 | last = *begin == NULL ? NULL : cx_linked_list_last(*begin, loc_next); |
456
227c2eabbef8
change cx_linked_list_last() and add a test for it
Mike Becker <universe@uap-core.de>
parents:
453
diff
changeset
|
184 | } else { |
227c2eabbef8
change cx_linked_list_last() and add a test for it
Mike Becker <universe@uap-core.de>
parents:
453
diff
changeset
|
185 | last = *end; |
227c2eabbef8
change cx_linked_list_last() and add a test for it
Mike Becker <universe@uap-core.de>
parents:
453
diff
changeset
|
186 | } |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
187 | cx_linked_list_insert_chain(begin, end, loc_prev, loc_next, last, new_node, new_node); |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
188 | } |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
189 | |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
190 | void cx_linked_list_prepend( |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
191 | void **begin, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
192 | void **end, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
193 | ptrdiff_t loc_prev, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
194 | ptrdiff_t loc_next, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
195 | void *new_node |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
196 | ) { |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
197 | cx_linked_list_insert_chain(begin, end, loc_prev, loc_next, NULL, new_node, new_node); |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
198 | } |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
199 | |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
200 | void cx_linked_list_insert( |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
201 | void **begin, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
202 | void **end, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
203 | ptrdiff_t loc_prev, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
204 | ptrdiff_t loc_next, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
205 | void *node, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
206 | void *new_node |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
207 | ) { |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
208 | cx_linked_list_insert_chain(begin, end, loc_prev, loc_next, node, new_node, new_node); |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
209 | } |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
210 | |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
211 | void cx_linked_list_insert_chain( |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
212 | void **begin, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
213 | void **end, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
214 | ptrdiff_t loc_prev, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
215 | ptrdiff_t loc_next, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
216 | void *node, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
217 | void *insert_begin, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
218 | void *insert_end |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
219 | ) { |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
220 | // find the end of the chain, if not specified |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
221 | if (insert_end == NULL) { |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
222 | insert_end = cx_linked_list_last(insert_begin, loc_next); |
398
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
223 | } |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
224 | |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
225 | // determine the successor |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
226 | void *successor; |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
227 | if (node == NULL) { |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
228 | assert(begin != NULL || (end != NULL && loc_prev >= 0)); |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
229 | if (begin != NULL) { |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
230 | successor = *begin; |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
231 | *begin = insert_begin; |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
232 | } else { |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
233 | successor = *end == NULL ? NULL : cx_linked_list_first(*end, loc_prev); |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
234 | } |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
235 | } else { |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
236 | successor = ll_next(node); |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
237 | cx_linked_list_link(node, insert_begin, loc_prev, loc_next); |
408
dfdd571550f8
fixes cx_linked_list_add not recalculating end
Mike Becker <universe@uap-core.de>
parents:
407
diff
changeset
|
238 | } |
428
da66264af8ad
fix special cases for linked_list_add
Mike Becker <universe@uap-core.de>
parents:
423
diff
changeset
|
239 | |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
240 | if (successor == NULL) { |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
241 | // the list ends with the new chain |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
242 | if (end != NULL) { |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
243 | *end = insert_end; |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
244 | } |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
245 | } else { |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
246 | cx_linked_list_link(insert_end, successor, loc_prev, loc_next); |
398
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
247 | } |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
248 | } |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
249 | |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
250 | void cx_linked_list_remove( |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
251 | void **begin, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
252 | void **end, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
253 | ptrdiff_t loc_prev, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
254 | ptrdiff_t loc_next, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
255 | void *node |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
256 | ) { |
477
73a93c7a56ae
add more explicit documentation to cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents:
476
diff
changeset
|
257 | assert(node != NULL); |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
258 | assert(loc_next >= 0); |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
259 | assert(loc_prev >= 0 || begin != NULL); |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
260 | |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
261 | // find adjacent nodes |
480
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
262 | void *next = ll_next(node); |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
263 | void *prev; |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
264 | if (loc_prev >= 0) { |
480
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
265 | prev = ll_prev(node); |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
266 | } else { |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
267 | prev = cx_linked_list_prev(*begin, loc_next, node); |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
268 | } |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
269 | |
476
60ff4561dc04
change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents:
475
diff
changeset
|
270 | // update next pointer of prev node, or set begin |
60ff4561dc04
change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents:
475
diff
changeset
|
271 | if (prev == NULL) { |
60ff4561dc04
change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents:
475
diff
changeset
|
272 | if (begin != NULL) { |
60ff4561dc04
change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents:
475
diff
changeset
|
273 | *begin = next; |
60ff4561dc04
change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents:
475
diff
changeset
|
274 | } |
60ff4561dc04
change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents:
475
diff
changeset
|
275 | } else { |
480
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
276 | ll_next(prev) = next; |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
277 | } |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
278 | |
476
60ff4561dc04
change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents:
475
diff
changeset
|
279 | // update prev pointer of next node, or set end |
60ff4561dc04
change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents:
475
diff
changeset
|
280 | if (next == NULL) { |
60ff4561dc04
change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents:
475
diff
changeset
|
281 | if (end != NULL) { |
60ff4561dc04
change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents:
475
diff
changeset
|
282 | *end = prev; |
60ff4561dc04
change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents:
475
diff
changeset
|
283 | } |
60ff4561dc04
change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents:
475
diff
changeset
|
284 | } else if (loc_prev >= 0) { |
480
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
285 | ll_prev(next) = prev; |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
286 | } |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
287 | } |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
288 | |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
289 | size_t cx_linked_list_size( |
489
af6be1e123aa
add some const qualifiers
Mike Becker <universe@uap-core.de>
parents:
488
diff
changeset
|
290 | void const *node, |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
291 | ptrdiff_t loc_next |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
292 | ) { |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
293 | assert(loc_next >= 0); |
468
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
294 | size_t size = 0; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
295 | while (node != NULL) { |
480
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
296 | node = ll_next(node); |
468
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
297 | size++; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
298 | } |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
299 | return size; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
300 | } |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
301 | |
661
0a71ac9547fd
add CX_LINKED_LIST_SORT_SBO_SIZE macro
Mike Becker <universe@uap-core.de>
parents:
655
diff
changeset
|
302 | #ifndef CX_LINKED_LIST_SORT_SBO_SIZE |
0a71ac9547fd
add CX_LINKED_LIST_SORT_SBO_SIZE macro
Mike Becker <universe@uap-core.de>
parents:
655
diff
changeset
|
303 | #define CX_LINKED_LIST_SORT_SBO_SIZE 1024 |
0a71ac9547fd
add CX_LINKED_LIST_SORT_SBO_SIZE macro
Mike Becker <universe@uap-core.de>
parents:
655
diff
changeset
|
304 | #endif |
0a71ac9547fd
add CX_LINKED_LIST_SORT_SBO_SIZE macro
Mike Becker <universe@uap-core.de>
parents:
655
diff
changeset
|
305 | |
703
425d4279856f
improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents:
702
diff
changeset
|
306 | static void cx_linked_list_sort_merge( |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
307 | ptrdiff_t loc_prev, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
308 | ptrdiff_t loc_next, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
309 | ptrdiff_t loc_data, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
310 | size_t length, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
311 | void *ls, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
312 | void *le, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
313 | void *re, |
703
425d4279856f
improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents:
702
diff
changeset
|
314 | cx_compare_func cmp_func, |
425d4279856f
improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents:
702
diff
changeset
|
315 | void **begin, |
425d4279856f
improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents:
702
diff
changeset
|
316 | void **end |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
317 | ) { |
661
0a71ac9547fd
add CX_LINKED_LIST_SORT_SBO_SIZE macro
Mike Becker <universe@uap-core.de>
parents:
655
diff
changeset
|
318 | void *sbo[CX_LINKED_LIST_SORT_SBO_SIZE]; |
0a71ac9547fd
add CX_LINKED_LIST_SORT_SBO_SIZE macro
Mike Becker <universe@uap-core.de>
parents:
655
diff
changeset
|
319 | void **sorted = length >= CX_LINKED_LIST_SORT_SBO_SIZE ? |
662
d0d95740071b
add simple functions for creating lists
Mike Becker <universe@uap-core.de>
parents:
661
diff
changeset
|
320 | malloc(sizeof(void *) * length) : sbo; |
508
8aea65ae1eaf
#168 - add attributes and const
Mike Becker <universe@uap-core.de>
parents:
503
diff
changeset
|
321 | if (sorted == NULL) abort(); |
468
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
322 | void *rc, *lc; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
323 | |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
324 | lc = ls; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
325 | rc = le; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
326 | size_t n = 0; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
327 | while (lc && lc != le && rc != re) { |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
328 | if (cmp_func(ll_data(lc), ll_data(rc)) <= 0) { |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
329 | sorted[n] = lc; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
330 | lc = ll_next(lc); |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
331 | } else { |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
332 | sorted[n] = rc; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
333 | rc = ll_next(rc); |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
334 | } |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
335 | n++; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
336 | } |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
337 | while (lc && lc != le) { |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
338 | sorted[n] = lc; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
339 | lc = ll_next(lc); |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
340 | n++; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
341 | } |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
342 | while (rc && rc != re) { |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
343 | sorted[n] = rc; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
344 | rc = ll_next(rc); |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
345 | n++; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
346 | } |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
347 | |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
348 | // Update pointer |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
349 | if (loc_prev >= 0) ll_prev(sorted[0]) = NULL; |
509
0d3c6075f82c
#129 - remove test code duplication
Mike Becker <universe@uap-core.de>
parents:
508
diff
changeset
|
350 | cx_for_n (i, length - 1) { |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
351 | cx_linked_list_link(sorted[i], sorted[i + 1], loc_prev, loc_next); |
468
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
352 | } |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
353 | ll_next(sorted[length - 1]) = NULL; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
354 | |
703
425d4279856f
improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents:
702
diff
changeset
|
355 | *begin = sorted[0]; |
425d4279856f
improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents:
702
diff
changeset
|
356 | *end = sorted[length-1]; |
468
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
357 | if (sorted != sbo) { |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
358 | free(sorted); |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
359 | } |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
360 | } |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
361 | |
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
592
diff
changeset
|
362 | void cx_linked_list_sort( // NOLINT(misc-no-recursion) - purposely recursive function |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
363 | void **begin, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
364 | void **end, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
365 | ptrdiff_t loc_prev, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
366 | ptrdiff_t loc_next, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
367 | ptrdiff_t loc_data, |
677
b09aae58bba4
refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents:
670
diff
changeset
|
368 | cx_compare_func cmp_func |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
369 | ) { |
468
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
370 | assert(begin != NULL); |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
371 | assert(loc_next >= 0); |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
372 | assert(loc_data >= 0); |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
373 | assert(cmp_func); |
468
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
374 | |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
375 | void *lc, *ls, *le, *re; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
376 | |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
377 | // set start node |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
378 | ls = *begin; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
379 | |
702
3390b58ad15a
fix cx_linked_list_sort() not working for empty lists
Mike Becker <universe@uap-core.de>
parents:
699
diff
changeset
|
380 | // early exit when this list is empty |
3390b58ad15a
fix cx_linked_list_sort() not working for empty lists
Mike Becker <universe@uap-core.de>
parents:
699
diff
changeset
|
381 | if (ls == NULL) return; |
3390b58ad15a
fix cx_linked_list_sort() not working for empty lists
Mike Becker <universe@uap-core.de>
parents:
699
diff
changeset
|
382 | |
468
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
383 | // check how many elements are already sorted |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
384 | lc = ls; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
385 | size_t ln = 1; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
386 | while (ll_next(lc) != NULL && cmp_func(ll_data(ll_next(lc)), ll_data(lc)) > 0) { |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
387 | lc = ll_next(lc); |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
388 | ln++; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
389 | } |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
390 | le = ll_next(lc); |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
391 | |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
392 | // if first unsorted node is NULL, the list is already completely sorted |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
393 | if (le != NULL) { |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
394 | void *rc; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
395 | size_t rn = 1; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
396 | rc = le; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
397 | // skip already sorted elements |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
398 | while (ll_next(rc) != NULL && cmp_func(ll_data(ll_next(rc)), ll_data(rc)) > 0) { |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
399 | rc = ll_next(rc); |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
400 | rn++; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
401 | } |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
402 | re = ll_next(rc); |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
403 | |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
404 | // {ls,...,le->prev} and {rs,...,re->prev} are sorted - merge them |
703
425d4279856f
improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents:
702
diff
changeset
|
405 | void *sorted_begin, *sorted_end; |
425d4279856f
improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents:
702
diff
changeset
|
406 | cx_linked_list_sort_merge(loc_prev, loc_next, loc_data, |
425d4279856f
improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents:
702
diff
changeset
|
407 | ln + rn, ls, le, re, cmp_func, |
425d4279856f
improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents:
702
diff
changeset
|
408 | &sorted_begin, &sorted_end); |
468
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
409 | |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
410 | // Something left? Sort it! |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
411 | size_t remainder_length = cx_linked_list_size(re, loc_next); |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
412 | if (remainder_length > 0) { |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
413 | void *remainder = re; |
639
309e8b08c60e
temporarily remove pointer lists - see #234
Mike Becker <universe@uap-core.de>
parents:
638
diff
changeset
|
414 | cx_linked_list_sort(&remainder, NULL, loc_prev, loc_next, loc_data, cmp_func); |
468
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
415 | |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
416 | // merge sorted list with (also sorted) remainder |
703
425d4279856f
improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents:
702
diff
changeset
|
417 | cx_linked_list_sort_merge(loc_prev, loc_next, loc_data, |
425d4279856f
improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents:
702
diff
changeset
|
418 | ln + rn + remainder_length, |
425d4279856f
improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents:
702
diff
changeset
|
419 | sorted_begin, remainder, NULL, cmp_func, |
425d4279856f
improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents:
702
diff
changeset
|
420 | &sorted_begin, &sorted_end); |
468
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
421 | } |
703
425d4279856f
improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents:
702
diff
changeset
|
422 | *begin = sorted_begin; |
425d4279856f
improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents:
702
diff
changeset
|
423 | if (end) *end = sorted_end; |
468
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
424 | } |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
425 | } |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
426 | |
486
d7ca126eab7f
add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents:
481
diff
changeset
|
427 | int cx_linked_list_compare( |
489
af6be1e123aa
add some const qualifiers
Mike Becker <universe@uap-core.de>
parents:
488
diff
changeset
|
428 | void const *begin_left, |
af6be1e123aa
add some const qualifiers
Mike Becker <universe@uap-core.de>
parents:
488
diff
changeset
|
429 | void const *begin_right, |
486
d7ca126eab7f
add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents:
481
diff
changeset
|
430 | ptrdiff_t loc_advance, |
d7ca126eab7f
add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents:
481
diff
changeset
|
431 | ptrdiff_t loc_data, |
677
b09aae58bba4
refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents:
670
diff
changeset
|
432 | cx_compare_func cmp_func |
486
d7ca126eab7f
add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents:
481
diff
changeset
|
433 | ) { |
489
af6be1e123aa
add some const qualifiers
Mike Becker <universe@uap-core.de>
parents:
488
diff
changeset
|
434 | void const *left = begin_left, *right = begin_right; |
486
d7ca126eab7f
add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents:
481
diff
changeset
|
435 | |
d7ca126eab7f
add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents:
481
diff
changeset
|
436 | while (left != NULL && right != NULL) { |
639
309e8b08c60e
temporarily remove pointer lists - see #234
Mike Becker <universe@uap-core.de>
parents:
638
diff
changeset
|
437 | void const *left_data = ll_data(left); |
309e8b08c60e
temporarily remove pointer lists - see #234
Mike Becker <universe@uap-core.de>
parents:
638
diff
changeset
|
438 | void const *right_data = ll_data(right); |
552
4373c2a90066
#178 fix that lists of different kind cannot be compared
Mike Becker <universe@uap-core.de>
parents:
528
diff
changeset
|
439 | int result = cmp_func(left_data, right_data); |
486
d7ca126eab7f
add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents:
481
diff
changeset
|
440 | if (result != 0) return result; |
d7ca126eab7f
add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents:
481
diff
changeset
|
441 | left = ll_advance(left); |
d7ca126eab7f
add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents:
481
diff
changeset
|
442 | right = ll_advance(right); |
d7ca126eab7f
add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents:
481
diff
changeset
|
443 | } |
d7ca126eab7f
add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents:
481
diff
changeset
|
444 | |
d7ca126eab7f
add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents:
481
diff
changeset
|
445 | if (left != NULL) { return 1; } |
d7ca126eab7f
add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents:
481
diff
changeset
|
446 | else if (right != NULL) { return -1; } |
d7ca126eab7f
add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents:
481
diff
changeset
|
447 | else { return 0; } |
d7ca126eab7f
add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents:
481
diff
changeset
|
448 | } |
d7ca126eab7f
add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents:
481
diff
changeset
|
449 | |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
450 | void cx_linked_list_reverse( |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
451 | void **begin, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
452 | void **end, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
453 | ptrdiff_t loc_prev, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
454 | ptrdiff_t loc_next |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
455 | ) { |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
456 | assert(begin != NULL); |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
457 | assert(loc_next >= 0); |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
458 | |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
459 | // swap all links |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
460 | void *prev = NULL; |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
461 | void *cur = *begin; |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
462 | while (cur != NULL) { |
480
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
463 | void *next = ll_next(cur); |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
464 | |
480
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
465 | ll_next(cur) = prev; |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
466 | if (loc_prev >= 0) { |
480
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
467 | ll_prev(cur) = next; |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
468 | } |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
469 | |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
470 | prev = cur; |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
471 | cur = next; |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
472 | } |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
473 | |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
474 | // update begin and end |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
475 | if (end != NULL) { |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
476 | *end = *begin; |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
477 | } |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
478 | *begin = prev; |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
479 | } |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
480 | |
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
592
diff
changeset
|
481 | // HIGH LEVEL LINKED LIST IMPLEMENTATION |
398
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
482 | |
647
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
483 | bool CX_DISABLE_LINKED_LIST_SWAP_SBO = false; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
484 | |
447
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
485 | typedef struct cx_linked_list_node cx_linked_list_node; |
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
486 | struct cx_linked_list_node { |
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
487 | cx_linked_list_node *prev; |
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
488 | cx_linked_list_node *next; |
403
8fa43b732980
use C99 flexible array to mark the node's payload
Mike Becker <universe@uap-core.de>
parents:
402
diff
changeset
|
489 | char payload[]; |
447
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
490 | }; |
402
a34b93911956
use named fields to access node memory
Mike Becker <universe@uap-core.de>
parents:
401
diff
changeset
|
491 | |
446
668757098b73
remove unnecessary fields from linked list node and simplifies cx_ll_add()
Mike Becker <universe@uap-core.de>
parents:
441
diff
changeset
|
492 | #define CX_LL_LOC_PREV offsetof(cx_linked_list_node, prev) |
668757098b73
remove unnecessary fields from linked list node and simplifies cx_ll_add()
Mike Becker <universe@uap-core.de>
parents:
441
diff
changeset
|
493 | #define CX_LL_LOC_NEXT offsetof(cx_linked_list_node, next) |
469
0458bff0b1cd
add high level list sort and inlines method invocation functions
Mike Becker <universe@uap-core.de>
parents:
468
diff
changeset
|
494 | #define CX_LL_LOC_DATA offsetof(cx_linked_list_node, payload) |
439
9a5adedd6de6
add high-level function cxListAt()
Mike Becker <universe@uap-core.de>
parents:
438
diff
changeset
|
495 | |
398
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
496 | typedef struct { |
500
eb9e7bd40a8e
do not hide pointers behind typedefs
Mike Becker <universe@uap-core.de>
parents:
499
diff
changeset
|
497 | struct cx_list_s base; |
446
668757098b73
remove unnecessary fields from linked list node and simplifies cx_ll_add()
Mike Becker <universe@uap-core.de>
parents:
441
diff
changeset
|
498 | cx_linked_list_node *begin; |
668757098b73
remove unnecessary fields from linked list node and simplifies cx_ll_add()
Mike Becker <universe@uap-core.de>
parents:
441
diff
changeset
|
499 | cx_linked_list_node *end; |
398
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
500 | } cx_linked_list; |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
501 | |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
502 | static cx_linked_list_node *cx_ll_node_at( |
489
af6be1e123aa
add some const qualifiers
Mike Becker <universe@uap-core.de>
parents:
488
diff
changeset
|
503 | cx_linked_list const *list, |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
504 | size_t index |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
505 | ) { |
447
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
506 | if (index >= list->base.size) { |
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
507 | return NULL; |
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
508 | } else if (index > list->base.size / 2) { |
468
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
509 | return cx_linked_list_at(list->end, list->base.size - 1, CX_LL_LOC_PREV, index); |
447
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
510 | } else { |
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
511 | return cx_linked_list_at(list->begin, 0, CX_LL_LOC_NEXT, index); |
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
512 | } |
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
513 | } |
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
514 | |
499
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
515 | static int cx_ll_insert_at( |
500
eb9e7bd40a8e
do not hide pointers behind typedefs
Mike Becker <universe@uap-core.de>
parents:
499
diff
changeset
|
516 | struct cx_list_s *list, |
499
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
517 | cx_linked_list_node *node, |
489
af6be1e123aa
add some const qualifiers
Mike Becker <universe@uap-core.de>
parents:
488
diff
changeset
|
518 | void const *elem |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
519 | ) { |
448
37c5d2fdb36b
implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents:
447
diff
changeset
|
520 | |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
521 | // create the new new_node |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
522 | cx_linked_list_node *new_node = cxMalloc(list->allocator, |
677
b09aae58bba4
refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents:
670
diff
changeset
|
523 | sizeof(cx_linked_list_node) + list->item_size); |
448
37c5d2fdb36b
implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents:
447
diff
changeset
|
524 | |
37c5d2fdb36b
implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents:
447
diff
changeset
|
525 | // sortir if failed |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
526 | if (new_node == NULL) return 1; |
448
37c5d2fdb36b
implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents:
447
diff
changeset
|
527 | |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
528 | // initialize new new_node |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
529 | new_node->prev = new_node->next = NULL; |
677
b09aae58bba4
refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents:
670
diff
changeset
|
530 | memcpy(new_node->payload, elem, list->item_size); |
448
37c5d2fdb36b
implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents:
447
diff
changeset
|
531 | |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
532 | // insert |
499
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
533 | cx_linked_list *ll = (cx_linked_list *) list; |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
534 | cx_linked_list_insert_chain( |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
535 | (void **) &ll->begin, (void **) &ll->end, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
536 | CX_LL_LOC_PREV, CX_LL_LOC_NEXT, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
537 | node, new_node, new_node |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
538 | ); |
448
37c5d2fdb36b
implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents:
447
diff
changeset
|
539 | |
37c5d2fdb36b
implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents:
447
diff
changeset
|
540 | // increase the size and return |
37c5d2fdb36b
implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents:
447
diff
changeset
|
541 | list->size++; |
37c5d2fdb36b
implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents:
447
diff
changeset
|
542 | return 0; |
37c5d2fdb36b
implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents:
447
diff
changeset
|
543 | } |
37c5d2fdb36b
implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents:
447
diff
changeset
|
544 | |
638
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
545 | static size_t cx_ll_insert_array( |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
546 | struct cx_list_s *list, |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
547 | size_t index, |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
548 | void const *array, |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
549 | size_t n |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
550 | ) { |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
551 | // out-of bounds and corner case check |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
552 | if (index > list->size || n == 0) return 0; |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
553 | |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
554 | // find position efficiently |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
555 | cx_linked_list_node *node = index == 0 ? NULL : cx_ll_node_at((cx_linked_list *) list, index - 1); |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
556 | |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
557 | // perform first insert |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
558 | if (0 != cx_ll_insert_at(list, node, array)) { |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
559 | return 1; |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
560 | } |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
561 | |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
562 | // is there more? |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
563 | if (n == 1) return 1; |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
564 | |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
565 | // we now know exactly where we are |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
566 | node = node == NULL ? ((cx_linked_list *) list)->begin : node->next; |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
567 | |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
568 | // we can add the remaining nodes and immedately advance to the inserted node |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
569 | char const *source = array; |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
570 | for (size_t i = 1; i < n; i++) { |
677
b09aae58bba4
refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents:
670
diff
changeset
|
571 | source += list->item_size; |
638
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
572 | if (0 != cx_ll_insert_at(list, node, source)) { |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
573 | return i; |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
574 | } |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
575 | node = node->next; |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
576 | } |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
577 | return n; |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
578 | } |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
579 | |
641
d402fead3386
add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents:
640
diff
changeset
|
580 | static int cx_ll_insert_element( |
d402fead3386
add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents:
640
diff
changeset
|
581 | struct cx_list_s *list, |
d402fead3386
add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents:
640
diff
changeset
|
582 | size_t index, |
d402fead3386
add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents:
640
diff
changeset
|
583 | void const *element |
d402fead3386
add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents:
640
diff
changeset
|
584 | ) { |
d402fead3386
add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents:
640
diff
changeset
|
585 | return 1 != cx_ll_insert_array(list, index, element, 1); |
d402fead3386
add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents:
640
diff
changeset
|
586 | } |
d402fead3386
add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents:
640
diff
changeset
|
587 | |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
588 | static int cx_ll_remove( |
500
eb9e7bd40a8e
do not hide pointers behind typedefs
Mike Becker <universe@uap-core.de>
parents:
499
diff
changeset
|
589 | struct cx_list_s *list, |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
590 | size_t index |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
591 | ) { |
447
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
592 | cx_linked_list *ll = (cx_linked_list *) list; |
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
593 | cx_linked_list_node *node = cx_ll_node_at(ll, index); |
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
594 | |
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
595 | // out-of-bounds check |
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
596 | if (node == NULL) return 1; |
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
597 | |
664
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
598 | // element destruction |
677
b09aae58bba4
refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents:
670
diff
changeset
|
599 | cx_invoke_destructor(list, node->payload); |
664
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
600 | |
476
60ff4561dc04
change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents:
475
diff
changeset
|
601 | // remove |
60ff4561dc04
change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents:
475
diff
changeset
|
602 | cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end, |
60ff4561dc04
change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents:
475
diff
changeset
|
603 | CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node); |
447
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
604 | |
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
605 | // adjust size |
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
606 | list->size--; |
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
607 | |
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
608 | // free and return |
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
609 | cxFree(list->allocator, node); |
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
610 | |
438
cd3069757010
add function cx_linked_list_at()
Mike Becker <universe@uap-core.de>
parents:
437
diff
changeset
|
611 | return 0; |
398
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
612 | } |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
613 | |
664
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
614 | static void cx_ll_clear(struct cx_list_s *list) { |
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
615 | if (list->size == 0) return; |
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
616 | |
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
617 | cx_linked_list *ll = (cx_linked_list *) list; |
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
618 | cx_linked_list_node *node = ll->begin; |
677
b09aae58bba4
refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents:
670
diff
changeset
|
619 | while (node != NULL) { |
b09aae58bba4
refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents:
670
diff
changeset
|
620 | cx_invoke_destructor(list, node->payload); |
b09aae58bba4
refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents:
670
diff
changeset
|
621 | cx_linked_list_node *next = node->next; |
b09aae58bba4
refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents:
670
diff
changeset
|
622 | cxFree(list->allocator, node); |
b09aae58bba4
refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents:
670
diff
changeset
|
623 | node = next; |
664
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
624 | } |
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
625 | ll->begin = ll->end = NULL; |
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
626 | list->size = 0; |
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
627 | } |
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
628 | |
647
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
629 | #ifndef CX_LINKED_LIST_SWAP_SBO_SIZE |
735
b686d0c98c62
unify the list swap SBO sizes
Mike Becker <universe@uap-core.de>
parents:
708
diff
changeset
|
630 | #define CX_LINKED_LIST_SWAP_SBO_SIZE 128 |
647
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
631 | #endif |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
632 | |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
633 | static int cx_ll_swap( |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
634 | struct cx_list_s *list, |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
635 | size_t i, |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
636 | size_t j |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
637 | ) { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
638 | if (i >= list->size || j >= list->size) return 1; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
639 | if (i == j) return 0; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
640 | |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
641 | // perform an optimized search that finds both elements in one run |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
642 | cx_linked_list *ll = (cx_linked_list *) list; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
643 | size_t mid = list->size / 2; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
644 | size_t left, right; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
645 | if (i < j) { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
646 | left = i; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
647 | right = j; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
648 | } else { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
649 | left = j; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
650 | right = i; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
651 | } |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
652 | cx_linked_list_node *nleft, *nright; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
653 | if (left < mid && right < mid) { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
654 | // case 1: both items left from mid |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
655 | nleft = cx_ll_node_at(ll, left); |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
656 | nright = nleft; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
657 | for (size_t c = left; c < right; c++) { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
658 | nright = nright->next; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
659 | } |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
660 | } else if (left >= mid && right >= mid) { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
661 | // case 2: both items right from mid |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
662 | nright = cx_ll_node_at(ll, right); |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
663 | nleft = nright; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
664 | for (size_t c = right; c > left; c--) { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
665 | nleft = nleft->prev; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
666 | } |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
667 | } else { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
668 | // case 3: one item left, one item right |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
669 | |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
670 | // chose the closest to begin / end |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
671 | size_t closest; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
672 | size_t other; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
673 | size_t diff2boundary = list->size - right - 1; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
674 | if (left <= diff2boundary) { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
675 | closest = left; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
676 | other = right; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
677 | nleft = cx_ll_node_at(ll, left); |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
678 | } else { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
679 | closest = right; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
680 | other = left; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
681 | diff2boundary = left; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
682 | nright = cx_ll_node_at(ll, right); |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
683 | } |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
684 | |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
685 | // is other element closer to us or closer to boundary? |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
686 | if (right - left <= diff2boundary) { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
687 | // search other element starting from already found element |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
688 | if (closest == left) { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
689 | nright = nleft; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
690 | for (size_t c = left; c < right; c++) { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
691 | nright = nright->next; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
692 | } |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
693 | } else { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
694 | nleft = nright; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
695 | for (size_t c = right; c > left; c--) { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
696 | nleft = nleft->prev; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
697 | } |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
698 | } |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
699 | } else { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
700 | // search other element starting at the boundary |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
701 | if (closest == left) { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
702 | nright = cx_ll_node_at(ll, other); |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
703 | } else { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
704 | nleft = cx_ll_node_at(ll, other); |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
705 | } |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
706 | } |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
707 | } |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
708 | |
677
b09aae58bba4
refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents:
670
diff
changeset
|
709 | if (list->item_size > CX_LINKED_LIST_SWAP_SBO_SIZE || CX_DISABLE_LINKED_LIST_SWAP_SBO) { |
647
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
710 | cx_linked_list_node *prev = nleft->prev; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
711 | cx_linked_list_node *next = nright->next; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
712 | cx_linked_list_node *midstart = nleft->next; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
713 | cx_linked_list_node *midend = nright->prev; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
714 | |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
715 | if (prev == NULL) { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
716 | ll->begin = nright; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
717 | } else { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
718 | prev->next = nright; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
719 | } |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
720 | nright->prev = prev; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
721 | if (midstart == nright) { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
722 | // special case: both nodes are adjacent |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
723 | nright->next = nleft; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
724 | nleft->prev = nright; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
725 | } else { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
726 | // likely case: a chain is between the two nodes |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
727 | nright->next = midstart; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
728 | midstart->prev = nright; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
729 | midend->next = nleft; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
730 | nleft->prev = midend; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
731 | } |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
732 | nleft->next = next; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
733 | if (next == NULL) { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
734 | ll->end = nleft; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
735 | } else { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
736 | next->prev = nleft; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
737 | } |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
738 | } else { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
739 | // swap payloads to avoid relinking |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
740 | char buf[CX_LINKED_LIST_SWAP_SBO_SIZE]; |
677
b09aae58bba4
refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents:
670
diff
changeset
|
741 | memcpy(buf, nleft->payload, list->item_size); |
b09aae58bba4
refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents:
670
diff
changeset
|
742 | memcpy(nleft->payload, nright->payload, list->item_size); |
b09aae58bba4
refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents:
670
diff
changeset
|
743 | memcpy(nright->payload, buf, list->item_size); |
647
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
744 | } |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
745 | |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
746 | return 0; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
747 | } |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
748 | |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
749 | static void *cx_ll_at( |
500
eb9e7bd40a8e
do not hide pointers behind typedefs
Mike Becker <universe@uap-core.de>
parents:
499
diff
changeset
|
750 | struct cx_list_s const *list, |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
751 | size_t index |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
752 | ) { |
439
9a5adedd6de6
add high-level function cxListAt()
Mike Becker <universe@uap-core.de>
parents:
438
diff
changeset
|
753 | cx_linked_list *ll = (cx_linked_list *) list; |
447
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
754 | cx_linked_list_node *node = cx_ll_node_at(ll, index); |
466
28bc3e10ac28
add special linked list implementation for storing pointers
Mike Becker <universe@uap-core.de>
parents:
457
diff
changeset
|
755 | return node == NULL ? NULL : node->payload; |
28bc3e10ac28
add special linked list implementation for storing pointers
Mike Becker <universe@uap-core.de>
parents:
457
diff
changeset
|
756 | } |
28bc3e10ac28
add special linked list implementation for storing pointers
Mike Becker <universe@uap-core.de>
parents:
457
diff
changeset
|
757 | |
764
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
758 | static ssize_t cx_ll_find_remove( |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
759 | struct cx_list_s *list, |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
760 | void const *elem, |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
761 | bool remove |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
762 | ) { |
764
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
763 | if (remove) { |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
764 | cx_linked_list *ll = ((cx_linked_list *) list); |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
765 | cx_linked_list_node *node; |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
766 | ssize_t index = cx_linked_list_find_node( |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
767 | (void **) &node, |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
768 | ll->begin, |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
769 | CX_LL_LOC_NEXT, CX_LL_LOC_DATA, |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
770 | list->cmpfunc, elem |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
771 | ); |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
772 | if (node != NULL) { |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
773 | cx_invoke_destructor(list, node->payload); |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
774 | cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end, |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
775 | CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node); |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
776 | list->size--; |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
777 | cxFree(list->allocator, node); |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
778 | } |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
779 | return index; |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
780 | } else { |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
781 | return cx_linked_list_find( |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
782 | ((cx_linked_list *) list)->begin, |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
783 | CX_LL_LOC_NEXT, CX_LL_LOC_DATA, |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
784 | list->cmpfunc, elem |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
785 | ); |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
786 | } |
466
28bc3e10ac28
add special linked list implementation for storing pointers
Mike Becker <universe@uap-core.de>
parents:
457
diff
changeset
|
787 | } |
28bc3e10ac28
add special linked list implementation for storing pointers
Mike Becker <universe@uap-core.de>
parents:
457
diff
changeset
|
788 | |
500
eb9e7bd40a8e
do not hide pointers behind typedefs
Mike Becker <universe@uap-core.de>
parents:
499
diff
changeset
|
789 | static void cx_ll_sort(struct cx_list_s *list) { |
469
0458bff0b1cd
add high level list sort and inlines method invocation functions
Mike Becker <universe@uap-core.de>
parents:
468
diff
changeset
|
790 | cx_linked_list *ll = (cx_linked_list *) list; |
0458bff0b1cd
add high level list sort and inlines method invocation functions
Mike Becker <universe@uap-core.de>
parents:
468
diff
changeset
|
791 | cx_linked_list_sort((void **) &ll->begin, (void **) &ll->end, |
0458bff0b1cd
add high level list sort and inlines method invocation functions
Mike Becker <universe@uap-core.de>
parents:
468
diff
changeset
|
792 | CX_LL_LOC_PREV, CX_LL_LOC_NEXT, CX_LL_LOC_DATA, |
639
309e8b08c60e
temporarily remove pointer lists - see #234
Mike Becker <universe@uap-core.de>
parents:
638
diff
changeset
|
793 | list->cmpfunc); |
469
0458bff0b1cd
add high level list sort and inlines method invocation functions
Mike Becker <universe@uap-core.de>
parents:
468
diff
changeset
|
794 | } |
0458bff0b1cd
add high level list sort and inlines method invocation functions
Mike Becker <universe@uap-core.de>
parents:
468
diff
changeset
|
795 | |
500
eb9e7bd40a8e
do not hide pointers behind typedefs
Mike Becker <universe@uap-core.de>
parents:
499
diff
changeset
|
796 | static void cx_ll_reverse(struct cx_list_s *list) { |
490 | 797 | cx_linked_list *ll = (cx_linked_list *) list; |
521
e5dc54131d55
add test for cxListCompare
Mike Becker <universe@uap-core.de>
parents:
509
diff
changeset
|
798 | cx_linked_list_reverse((void **) &ll->begin, (void **) &ll->end, CX_LL_LOC_PREV, CX_LL_LOC_NEXT); |
490 | 799 | } |
800 | ||
488
9138acaa494b
add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents:
487
diff
changeset
|
801 | static int cx_ll_compare( |
500
eb9e7bd40a8e
do not hide pointers behind typedefs
Mike Becker <universe@uap-core.de>
parents:
499
diff
changeset
|
802 | struct cx_list_s const *list, |
eb9e7bd40a8e
do not hide pointers behind typedefs
Mike Becker <universe@uap-core.de>
parents:
499
diff
changeset
|
803 | struct cx_list_s const *other |
488
9138acaa494b
add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents:
487
diff
changeset
|
804 | ) { |
9138acaa494b
add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents:
487
diff
changeset
|
805 | cx_linked_list *left = (cx_linked_list *) list; |
9138acaa494b
add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents:
487
diff
changeset
|
806 | cx_linked_list *right = (cx_linked_list *) other; |
9138acaa494b
add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents:
487
diff
changeset
|
807 | return cx_linked_list_compare(left->begin, right->begin, |
9138acaa494b
add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents:
487
diff
changeset
|
808 | CX_LL_LOC_NEXT, CX_LL_LOC_DATA, |
639
309e8b08c60e
temporarily remove pointer lists - see #234
Mike Becker <universe@uap-core.de>
parents:
638
diff
changeset
|
809 | list->cmpfunc); |
488
9138acaa494b
add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents:
487
diff
changeset
|
810 | } |
9138acaa494b
add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents:
487
diff
changeset
|
811 | |
630
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
812 | static bool cx_ll_iter_valid(void const *it) { |
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
813 | struct cx_iterator_s const *iter = it; |
495
2856c74e18ba
add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents:
494
diff
changeset
|
814 | return iter->elem_handle != NULL; |
494
6ce8cfa10a96
add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents:
490
diff
changeset
|
815 | } |
6ce8cfa10a96
add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents:
490
diff
changeset
|
816 | |
630
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
817 | static void cx_ll_iter_next(void *it) { |
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
818 | struct cx_iterator_base_s *itbase = it; |
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
819 | if (itbase->remove) { |
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
820 | itbase->remove = false; |
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
821 | struct cx_mut_iterator_s *iter = it; |
664
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
822 | struct cx_list_s *list = iter->src_handle; |
495
2856c74e18ba
add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents:
494
diff
changeset
|
823 | cx_linked_list *ll = iter->src_handle; |
2856c74e18ba
add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents:
494
diff
changeset
|
824 | cx_linked_list_node *node = iter->elem_handle; |
2856c74e18ba
add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents:
494
diff
changeset
|
825 | iter->elem_handle = node->next; |
677
b09aae58bba4
refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents:
670
diff
changeset
|
826 | cx_invoke_destructor(list, node->payload); |
495
2856c74e18ba
add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents:
494
diff
changeset
|
827 | cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end, |
2856c74e18ba
add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents:
494
diff
changeset
|
828 | CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node); |
664
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
829 | list->size--; |
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
830 | cxFree(list->allocator, node); |
495
2856c74e18ba
add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents:
494
diff
changeset
|
831 | } else { |
630
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
832 | struct cx_iterator_s *iter = it; |
495
2856c74e18ba
add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents:
494
diff
changeset
|
833 | iter->index++; |
2856c74e18ba
add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents:
494
diff
changeset
|
834 | cx_linked_list_node *node = iter->elem_handle; |
2856c74e18ba
add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents:
494
diff
changeset
|
835 | iter->elem_handle = node->next; |
2856c74e18ba
add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents:
494
diff
changeset
|
836 | } |
494
6ce8cfa10a96
add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents:
490
diff
changeset
|
837 | } |
6ce8cfa10a96
add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents:
490
diff
changeset
|
838 | |
655
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
839 | static void cx_ll_iter_prev(void *it) { |
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
840 | struct cx_iterator_base_s *itbase = it; |
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
841 | if (itbase->remove) { |
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
842 | itbase->remove = false; |
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
843 | struct cx_mut_iterator_s *iter = it; |
664
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
844 | struct cx_list_s *list = iter->src_handle; |
655
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
845 | cx_linked_list *ll = iter->src_handle; |
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
846 | cx_linked_list_node *node = iter->elem_handle; |
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
847 | iter->elem_handle = node->prev; |
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
848 | iter->index--; |
677
b09aae58bba4
refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents:
670
diff
changeset
|
849 | cx_invoke_destructor(list, node->payload); |
655
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
850 | cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end, |
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
851 | CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node); |
664
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
852 | list->size--; |
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
853 | cxFree(list->allocator, node); |
655
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
854 | } else { |
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
855 | struct cx_iterator_s *iter = it; |
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
856 | iter->index--; |
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
857 | cx_linked_list_node *node = iter->elem_handle; |
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
858 | iter->elem_handle = node->prev; |
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
859 | } |
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
860 | } |
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
861 | |
630
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
862 | static void *cx_ll_iter_current(void const *it) { |
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
863 | struct cx_iterator_s const *iter = it; |
495
2856c74e18ba
add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents:
494
diff
changeset
|
864 | cx_linked_list_node *node = iter->elem_handle; |
494
6ce8cfa10a96
add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents:
490
diff
changeset
|
865 | return node->payload; |
6ce8cfa10a96
add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents:
490
diff
changeset
|
866 | } |
6ce8cfa10a96
add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents:
490
diff
changeset
|
867 | |
630
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
868 | static bool cx_ll_iter_flag_rm(void *it) { |
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
869 | struct cx_iterator_base_s *iter = it; |
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
870 | if (iter->mutating) { |
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
871 | iter->remove = true; |
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
872 | return true; |
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
873 | } else { |
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
874 | return false; |
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
875 | } |
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
876 | } |
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
877 | |
494
6ce8cfa10a96
add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents:
490
diff
changeset
|
878 | static CxIterator cx_ll_iterator( |
630
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
879 | struct cx_list_s const *list, |
655
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
880 | size_t index, |
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
881 | bool backwards |
494
6ce8cfa10a96
add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents:
490
diff
changeset
|
882 | ) { |
6ce8cfa10a96
add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents:
490
diff
changeset
|
883 | CxIterator iter; |
6ce8cfa10a96
add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents:
490
diff
changeset
|
884 | iter.index = index; |
495
2856c74e18ba
add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents:
494
diff
changeset
|
885 | iter.src_handle = list; |
2856c74e18ba
add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents:
494
diff
changeset
|
886 | iter.elem_handle = cx_ll_node_at((cx_linked_list const *) list, index); |
630
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
887 | iter.base.valid = cx_ll_iter_valid; |
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
888 | iter.base.current = cx_ll_iter_current; |
655
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
889 | iter.base.next = backwards ? cx_ll_iter_prev : cx_ll_iter_next; |
630
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
890 | iter.base.flag_removal = cx_ll_iter_flag_rm; |
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
891 | iter.base.mutating = false; |
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
892 | iter.base.remove = false; |
494
6ce8cfa10a96
add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents:
490
diff
changeset
|
893 | return iter; |
6ce8cfa10a96
add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents:
490
diff
changeset
|
894 | } |
6ce8cfa10a96
add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents:
490
diff
changeset
|
895 | |
499
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
896 | static int cx_ll_insert_iter( |
630
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
897 | CxMutIterator *iter, |
499
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
898 | void const *elem, |
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
899 | int prepend |
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
900 | ) { |
500
eb9e7bd40a8e
do not hide pointers behind typedefs
Mike Becker <universe@uap-core.de>
parents:
499
diff
changeset
|
901 | struct cx_list_s *list = iter->src_handle; |
499
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
902 | cx_linked_list_node *node = iter->elem_handle; |
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
903 | if (node != NULL) { |
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
904 | assert(prepend >= 0 && prepend <= 1); |
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
905 | cx_linked_list_node *choice[2] = {node, node->prev}; |
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
906 | int result = cx_ll_insert_at(list, choice[prepend], elem); |
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
907 | iter->index += prepend * (0 == result); |
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
908 | return result; |
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
909 | } else { |
641
d402fead3386
add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents:
640
diff
changeset
|
910 | int result = cx_ll_insert_element(list, list->size, elem); |
499
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
911 | iter->index = list->size; |
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
912 | return result; |
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
913 | } |
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
914 | } |
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
915 | |
524 | 916 | static void cx_ll_destructor(CxList *list) { |
917 | cx_linked_list *ll = (cx_linked_list *) list; | |
918 | ||
919 | cx_linked_list_node *node = ll->begin; | |
920 | while (node) { | |
708
1caed6c9ba68
fix inconsistent destructor requirements for list and map classes
Mike Becker <universe@uap-core.de>
parents:
703
diff
changeset
|
921 | cx_invoke_destructor(list, node->payload); |
524 | 922 | void *next = node->next; |
923 | cxFree(list->allocator, node); | |
924 | node = next; | |
925 | } | |
708
1caed6c9ba68
fix inconsistent destructor requirements for list and map classes
Mike Becker <universe@uap-core.de>
parents:
703
diff
changeset
|
926 | |
1caed6c9ba68
fix inconsistent destructor requirements for list and map classes
Mike Becker <universe@uap-core.de>
parents:
703
diff
changeset
|
927 | cxFree(list->allocator, list); |
524 | 928 | } |
929 | ||
451
db06dda7ac4d
make cx_linked_list_class static
Mike Becker <universe@uap-core.de>
parents:
448
diff
changeset
|
930 | static cx_list_class cx_linked_list_class = { |
524 | 931 | cx_ll_destructor, |
641
d402fead3386
add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents:
640
diff
changeset
|
932 | cx_ll_insert_element, |
638
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
933 | cx_ll_insert_array, |
499
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
934 | cx_ll_insert_iter, |
398
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
935 | cx_ll_remove, |
664
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
936 | cx_ll_clear, |
647
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
937 | cx_ll_swap, |
439
9a5adedd6de6
add high-level function cxListAt()
Mike Becker <universe@uap-core.de>
parents:
438
diff
changeset
|
938 | cx_ll_at, |
764
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
939 | cx_ll_find_remove, |
488
9138acaa494b
add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents:
487
diff
changeset
|
940 | cx_ll_sort, |
490 | 941 | cx_ll_compare, |
494
6ce8cfa10a96
add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents:
490
diff
changeset
|
942 | cx_ll_reverse, |
630
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
943 | cx_ll_iterator, |
398
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
944 | }; |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
945 | |
670
4ad8ea3aee49
allow NULL for allocator and comparator
Mike Becker <universe@uap-core.de>
parents:
667
diff
changeset
|
946 | CxList *cxLinkedListCreate( |
508
8aea65ae1eaf
#168 - add attributes and const
Mike Becker <universe@uap-core.de>
parents:
503
diff
changeset
|
947 | CxAllocator const *allocator, |
677
b09aae58bba4
refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents:
670
diff
changeset
|
948 | cx_compare_func comparator, |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
949 | size_t item_size |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
950 | ) { |
670
4ad8ea3aee49
allow NULL for allocator and comparator
Mike Becker <universe@uap-core.de>
parents:
667
diff
changeset
|
951 | if (allocator == NULL) { |
4ad8ea3aee49
allow NULL for allocator and comparator
Mike Becker <universe@uap-core.de>
parents:
667
diff
changeset
|
952 | allocator = cxDefaultAllocator; |
4ad8ea3aee49
allow NULL for allocator and comparator
Mike Becker <universe@uap-core.de>
parents:
667
diff
changeset
|
953 | } |
4ad8ea3aee49
allow NULL for allocator and comparator
Mike Becker <universe@uap-core.de>
parents:
667
diff
changeset
|
954 | |
503
a89857072ace
add new destructor API and apply it to CxList
Mike Becker <universe@uap-core.de>
parents:
500
diff
changeset
|
955 | cx_linked_list *list = cxCalloc(allocator, 1, sizeof(cx_linked_list)); |
528
4fbfac557df8
#179 improve API for list content destruction
Mike Becker <universe@uap-core.de>
parents:
524
diff
changeset
|
956 | if (list == NULL) return NULL; |
398
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
957 | |
435
0fe204d50f54
change inheritance model for lists
Mike Becker <universe@uap-core.de>
parents:
428
diff
changeset
|
958 | list->base.cl = &cx_linked_list_class; |
0fe204d50f54
change inheritance model for lists
Mike Becker <universe@uap-core.de>
parents:
428
diff
changeset
|
959 | list->base.allocator = allocator; |
406
9cbea761fbf7
adds cxLinkedListWrap and cxLinkedListRecalculateSize
Mike Becker <universe@uap-core.de>
parents:
404
diff
changeset
|
960 | |
667
2f88a7c13a28
add CX_STORE_POINTERS special "item size" for lists
Mike Becker <universe@uap-core.de>
parents:
666
diff
changeset
|
961 | if (item_size > 0) { |
677
b09aae58bba4
refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents:
670
diff
changeset
|
962 | list->base.item_size = item_size; |
763
741a2040fa33
make cx_cmp_ptr default comparator for pointer lists - relates to #340
Mike Becker <universe@uap-core.de>
parents:
735
diff
changeset
|
963 | list->base.cmpfunc = comparator; |
667
2f88a7c13a28
add CX_STORE_POINTERS special "item size" for lists
Mike Becker <universe@uap-core.de>
parents:
666
diff
changeset
|
964 | } else { |
763
741a2040fa33
make cx_cmp_ptr default comparator for pointer lists - relates to #340
Mike Becker <universe@uap-core.de>
parents:
735
diff
changeset
|
965 | list->base.cmpfunc = comparator == NULL ? cx_cmp_ptr : comparator; |
667
2f88a7c13a28
add CX_STORE_POINTERS special "item size" for lists
Mike Becker <universe@uap-core.de>
parents:
666
diff
changeset
|
966 | cxListStorePointers((CxList *) list); |
2f88a7c13a28
add CX_STORE_POINTERS special "item size" for lists
Mike Becker <universe@uap-core.de>
parents:
666
diff
changeset
|
967 | } |
2f88a7c13a28
add CX_STORE_POINTERS special "item size" for lists
Mike Becker <universe@uap-core.de>
parents:
666
diff
changeset
|
968 | |
500
eb9e7bd40a8e
do not hide pointers behind typedefs
Mike Becker <universe@uap-core.de>
parents:
499
diff
changeset
|
969 | return (CxList *) list; |
406
9cbea761fbf7
adds cxLinkedListWrap and cxLinkedListRecalculateSize
Mike Becker <universe@uap-core.de>
parents:
404
diff
changeset
|
970 | } |