Sun, 22 Dec 2024 22:10:04 +0100
don't trust that size_t always has word width
it should be the case on all platforms supported by UCX, but it's not strictly defined in POSIX that it must be the case
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" |
763
741a2040fa33
make cx_cmp_ptr default comparator for pointer lists - relates to #340
Mike Becker <universe@uap-core.de>
parents:
735
diff
changeset
|
30 | #include "cx/compare.h" |
401
e6a8f7fb0c45
copy list items when they are added to the list
Mike Becker <universe@uap-core.de>
parents:
400
diff
changeset
|
31 | #include <string.h> |
453
bb144d08cd44
add some documentation and changes some signatures
Mike Becker <universe@uap-core.de>
parents:
451
diff
changeset
|
32 | #include <assert.h> |
398
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
33 | |
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
592
diff
changeset
|
34 | // LOW LEVEL LINKED LIST FUNCTIONS |
398
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
35 | |
592
bb69ef3ad1f3
enclose macro arguments in parenthesis
Mike Becker <universe@uap-core.de>
parents:
552
diff
changeset
|
36 | #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
|
37 | #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
|
38 | #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
|
39 | #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
|
40 | #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
|
41 | |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
42 | void *cx_linked_list_at( |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
43 | const void *start, |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
44 | size_t start_index, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
45 | ptrdiff_t loc_advance, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
46 | size_t index |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
47 | ) { |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
48 | assert(start != NULL); |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
49 | assert(loc_advance >= 0); |
438
cd3069757010
add function cx_linked_list_at()
Mike Becker <universe@uap-core.de>
parents:
437
diff
changeset
|
50 | size_t i = start_index; |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
51 | const void *cur = start; |
438
cd3069757010
add function cx_linked_list_at()
Mike Becker <universe@uap-core.de>
parents:
437
diff
changeset
|
52 | while (i != index && cur != NULL) { |
480
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
53 | cur = ll_advance(cur); |
438
cd3069757010
add function cx_linked_list_at()
Mike Becker <universe@uap-core.de>
parents:
437
diff
changeset
|
54 | i < index ? i++ : i--; |
cd3069757010
add function cx_linked_list_at()
Mike Becker <universe@uap-core.de>
parents:
437
diff
changeset
|
55 | } |
508
8aea65ae1eaf
#168 - add attributes and const
Mike Becker <universe@uap-core.de>
parents:
503
diff
changeset
|
56 | return (void *) cur; |
438
cd3069757010
add function cx_linked_list_at()
Mike Becker <universe@uap-core.de>
parents:
437
diff
changeset
|
57 | } |
cd3069757010
add function cx_linked_list_at()
Mike Becker <universe@uap-core.de>
parents:
437
diff
changeset
|
58 | |
699
35b2b99ee523
make list find return a negative value when elem not found
Mike Becker <universe@uap-core.de>
parents:
677
diff
changeset
|
59 | ssize_t cx_linked_list_find( |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
60 | const void *start, |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
61 | ptrdiff_t loc_advance, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
62 | 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
|
63 | cx_compare_func cmp_func, |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
64 | const void *elem |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
65 | ) { |
764
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
66 | void *dummy; |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
67 | 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
|
68 | &dummy, start, |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
69 | loc_advance, loc_data, |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
70 | cmp_func, elem |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
71 | ); |
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 | 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
|
75 | void **result, |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
76 | const void *start, |
764
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
77 | ptrdiff_t loc_advance, |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
78 | ptrdiff_t loc_data, |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
79 | cx_compare_func cmp_func, |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
80 | const void *elem |
764
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
81 | ) { |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
82 | assert(result != NULL); |
480
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
83 | assert(start != NULL); |
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
84 | assert(loc_advance >= 0); |
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
85 | assert(loc_data >= 0); |
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
86 | assert(cmp_func); |
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
87 | |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
88 | const void *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
|
89 | ssize_t index = 0; |
480
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
90 | do { |
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
91 | void *current = ll_data(node); |
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
92 | if (cmp_func(current, elem) == 0) { |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
93 | *result = (void *) node; |
480
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
94 | return index; |
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
95 | } |
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
96 | node = ll_advance(node); |
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
97 | index++; |
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
98 | } while (node != NULL); |
764
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
99 | *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
|
100 | return -1; |
480
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
101 | } |
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
102 | |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
103 | void *cx_linked_list_first( |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
104 | const void *node, |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
105 | ptrdiff_t loc_prev |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
106 | ) { |
475
31bf97fdbf71
add cx_linked_list_first() + cx_linked_list_prepend()
Mike Becker <universe@uap-core.de>
parents:
474
diff
changeset
|
107 | 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
|
108 | } |
31bf97fdbf71
add cx_linked_list_first() + cx_linked_list_prepend()
Mike Becker <universe@uap-core.de>
parents:
474
diff
changeset
|
109 | |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
110 | void *cx_linked_list_last( |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
111 | const void *node, |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
112 | ptrdiff_t loc_next |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
113 | ) { |
478
599770bb6314
add more nonnull attributes
Mike Becker <universe@uap-core.de>
parents:
477
diff
changeset
|
114 | assert(node != NULL); |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
115 | assert(loc_next >= 0); |
398
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
116 | |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
117 | const void *cur = node; |
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
118 | const void *last; |
456
227c2eabbef8
change cx_linked_list_last() and add a test for it
Mike Becker <universe@uap-core.de>
parents:
453
diff
changeset
|
119 | do { |
227c2eabbef8
change cx_linked_list_last() and add a test for it
Mike Becker <universe@uap-core.de>
parents:
453
diff
changeset
|
120 | last = cur; |
480
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
121 | } while ((cur = ll_next(cur)) != NULL); |
398
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
122 | |
508
8aea65ae1eaf
#168 - add attributes and const
Mike Becker <universe@uap-core.de>
parents:
503
diff
changeset
|
123 | return (void *) last; |
398
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
124 | } |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
125 | |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
126 | void *cx_linked_list_prev( |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
127 | const void *begin, |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
128 | ptrdiff_t loc_next, |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
129 | const void *node |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
130 | ) { |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
131 | assert(begin != NULL); |
478
599770bb6314
add more nonnull attributes
Mike Becker <universe@uap-core.de>
parents:
477
diff
changeset
|
132 | assert(node != NULL); |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
133 | assert(loc_next >= 0); |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
134 | if (begin == node) return NULL; |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
135 | const void *cur = begin; |
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
136 | const void *next; |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
137 | while (1) { |
480
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
138 | next = ll_next(cur); |
508
8aea65ae1eaf
#168 - add attributes and const
Mike Becker <universe@uap-core.de>
parents:
503
diff
changeset
|
139 | 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
|
140 | cur = next; |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
141 | } |
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 | |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
144 | void cx_linked_list_link( |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
145 | void *left, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
146 | void *right, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
147 | ptrdiff_t loc_prev, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
148 | ptrdiff_t loc_next |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
149 | ) { |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
150 | assert(loc_next >= 0); |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
151 | ll_next(left) = right; |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
152 | if (loc_prev >= 0) { |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
153 | ll_prev(right) = left; |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
154 | } |
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 | void cx_linked_list_unlink( |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
158 | void *left, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
159 | void *right, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
160 | ptrdiff_t loc_prev, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
161 | ptrdiff_t loc_next |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
162 | ) { |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
163 | assert (loc_next >= 0); |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
164 | assert(ll_next(left) == right); |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
165 | ll_next(left) = NULL; |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
166 | if (loc_prev >= 0) { |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
167 | assert(ll_prev(right) == left); |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
168 | ll_prev(right) = NULL; |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
169 | } |
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 | void cx_linked_list_add( |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
173 | void **begin, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
174 | void **end, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
175 | ptrdiff_t loc_prev, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
176 | ptrdiff_t loc_next, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
177 | void *new_node |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
178 | ) { |
456
227c2eabbef8
change cx_linked_list_last() and add a test for it
Mike Becker <universe@uap-core.de>
parents:
453
diff
changeset
|
179 | void *last; |
227c2eabbef8
change cx_linked_list_last() and add a test for it
Mike Becker <universe@uap-core.de>
parents:
453
diff
changeset
|
180 | 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
|
181 | assert(begin != NULL); |
478
599770bb6314
add more nonnull attributes
Mike Becker <universe@uap-core.de>
parents:
477
diff
changeset
|
182 | 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
|
183 | } else { |
227c2eabbef8
change cx_linked_list_last() and add a test for it
Mike Becker <universe@uap-core.de>
parents:
453
diff
changeset
|
184 | last = *end; |
227c2eabbef8
change cx_linked_list_last() and add a test for it
Mike Becker <universe@uap-core.de>
parents:
453
diff
changeset
|
185 | } |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
186 | 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
|
187 | } |
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 | void cx_linked_list_prepend( |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
190 | void **begin, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
191 | void **end, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
192 | ptrdiff_t loc_prev, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
193 | ptrdiff_t loc_next, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
194 | void *new_node |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
195 | ) { |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
196 | 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
|
197 | } |
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 | void cx_linked_list_insert( |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
200 | void **begin, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
201 | void **end, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
202 | ptrdiff_t loc_prev, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
203 | ptrdiff_t loc_next, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
204 | void *node, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
205 | void *new_node |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
206 | ) { |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
207 | 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
|
208 | } |
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 | void cx_linked_list_insert_chain( |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
211 | void **begin, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
212 | void **end, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
213 | ptrdiff_t loc_prev, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
214 | ptrdiff_t loc_next, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
215 | void *node, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
216 | void *insert_begin, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
217 | void *insert_end |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
218 | ) { |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
219 | // 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
|
220 | if (insert_end == NULL) { |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
221 | 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
|
222 | } |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
223 | |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
224 | // determine the successor |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
225 | void *successor; |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
226 | if (node == NULL) { |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
227 | 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
|
228 | if (begin != NULL) { |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
229 | successor = *begin; |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
230 | *begin = insert_begin; |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
231 | } else { |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
232 | 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
|
233 | } |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
234 | } else { |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
235 | successor = ll_next(node); |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
236 | 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
|
237 | } |
428
da66264af8ad
fix special cases for linked_list_add
Mike Becker <universe@uap-core.de>
parents:
423
diff
changeset
|
238 | |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
239 | if (successor == NULL) { |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
240 | // the list ends with the new chain |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
241 | if (end != NULL) { |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
242 | *end = insert_end; |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
243 | } |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
244 | } else { |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
245 | 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
|
246 | } |
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 | |
879
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
249 | void cx_linked_list_insert_sorted( |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
250 | void **begin, |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
251 | void **end, |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
252 | ptrdiff_t loc_prev, |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
253 | ptrdiff_t loc_next, |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
254 | void *new_node, |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
255 | cx_compare_func cmp_func |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
256 | ) { |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
257 | assert(ll_next(new_node) == NULL); |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
258 | cx_linked_list_insert_sorted_chain( |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
259 | begin, end, loc_prev, loc_next, new_node, cmp_func); |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
260 | } |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
261 | |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
262 | void cx_linked_list_insert_sorted_chain( |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
263 | void **begin, |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
264 | void **end, |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
265 | ptrdiff_t loc_prev, |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
266 | ptrdiff_t loc_next, |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
267 | void *insert_begin, |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
268 | cx_compare_func cmp_func |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
269 | ) { |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
270 | assert(begin != NULL); |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
271 | assert(loc_next >= 0); |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
272 | assert(insert_begin != NULL); |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
273 | |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
274 | // track currently observed nodes |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
275 | void *dest_prev = NULL; |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
276 | void *dest = *begin; |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
277 | void *src = insert_begin; |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
278 | |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
279 | // special case: list is empty |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
280 | if (dest == NULL) { |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
281 | *begin = src; |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
282 | if (end != NULL) { |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
283 | *end = cx_linked_list_last(src, loc_next); |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
284 | } |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
285 | return; |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
286 | } |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
287 | |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
288 | // search the list for insertion points |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
289 | while (dest != NULL && src != NULL) { |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
290 | // compare current list node with source node |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
291 | // if less or equal, skip |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
292 | if (cmp_func(dest, src) <= 0) { |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
293 | dest_prev = dest; |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
294 | dest = ll_next(dest); |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
295 | continue; |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
296 | } |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
297 | |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
298 | // determine chain of elements that can be inserted |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
299 | void *end_of_chain = src; |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
300 | void *next_in_chain = ll_next(src); |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
301 | while (next_in_chain != NULL) { |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
302 | // once we become larger than the list elem, break |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
303 | if (cmp_func(dest, next_in_chain) <= 0) { |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
304 | break; |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
305 | } |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
306 | // otherwise, we can insert one more |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
307 | end_of_chain = next_in_chain; |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
308 | next_in_chain = ll_next(next_in_chain); |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
309 | } |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
310 | |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
311 | // insert the elements |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
312 | if (dest_prev == NULL) { |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
313 | // new begin |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
314 | *begin = src; |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
315 | } else { |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
316 | cx_linked_list_link(dest_prev, src, loc_prev, loc_next); |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
317 | } |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
318 | cx_linked_list_link(end_of_chain, dest, loc_prev, loc_next); |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
319 | |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
320 | // continue with next |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
321 | src = next_in_chain; |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
322 | dest_prev = dest; |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
323 | dest = ll_next(dest); |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
324 | } |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
325 | |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
326 | // insert remaining items |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
327 | if (src != NULL) { |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
328 | cx_linked_list_link(dest_prev, src, loc_prev, loc_next); |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
329 | } |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
330 | |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
331 | // determine new end of list, if requested |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
332 | if (end != NULL) { |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
333 | *end = cx_linked_list_last( |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
334 | dest != NULL ? dest : dest_prev, loc_next); |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
335 | } |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
336 | } |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
337 | |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
338 | size_t cx_linked_list_remove_chain( |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
339 | void **begin, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
340 | void **end, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
341 | ptrdiff_t loc_prev, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
342 | ptrdiff_t loc_next, |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
343 | void *node, |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
344 | size_t num |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
345 | ) { |
477
73a93c7a56ae
add more explicit documentation to cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents:
476
diff
changeset
|
346 | assert(node != NULL); |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
347 | assert(loc_next >= 0); |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
348 | assert(loc_prev >= 0 || begin != NULL); |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
349 | |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
350 | // easy exit |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
351 | if (num == 0) return 0; |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
352 | |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
353 | // find adjacent nodes |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
354 | void *prev; |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
355 | if (loc_prev >= 0) { |
480
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
356 | prev = ll_prev(node); |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
357 | } else { |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
358 | 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
|
359 | } |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
360 | |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
361 | void *next = ll_next(node); |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
362 | size_t removed = 1; |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
363 | for (; removed < num && next != NULL ; removed++) { |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
364 | next = ll_next(next); |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
365 | } |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
366 | |
476
60ff4561dc04
change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents:
475
diff
changeset
|
367 | // 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
|
368 | if (prev == NULL) { |
60ff4561dc04
change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents:
475
diff
changeset
|
369 | if (begin != NULL) { |
60ff4561dc04
change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents:
475
diff
changeset
|
370 | *begin = next; |
60ff4561dc04
change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents:
475
diff
changeset
|
371 | } |
60ff4561dc04
change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents:
475
diff
changeset
|
372 | } else { |
480
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
373 | ll_next(prev) = next; |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
374 | } |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
375 | |
476
60ff4561dc04
change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents:
475
diff
changeset
|
376 | // 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
|
377 | if (next == NULL) { |
60ff4561dc04
change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents:
475
diff
changeset
|
378 | if (end != NULL) { |
60ff4561dc04
change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents:
475
diff
changeset
|
379 | *end = prev; |
60ff4561dc04
change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents:
475
diff
changeset
|
380 | } |
60ff4561dc04
change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents:
475
diff
changeset
|
381 | } else if (loc_prev >= 0) { |
480
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
382 | ll_prev(next) = prev; |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
383 | } |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
384 | |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
385 | return removed; |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
386 | } |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
387 | |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
388 | size_t cx_linked_list_size( |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
389 | const void *node, |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
390 | ptrdiff_t loc_next |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
391 | ) { |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
392 | assert(loc_next >= 0); |
468
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
393 | size_t size = 0; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
394 | while (node != NULL) { |
480
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
395 | node = ll_next(node); |
468
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
396 | size++; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
397 | } |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
398 | return size; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
399 | } |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
400 | |
661
0a71ac9547fd
add CX_LINKED_LIST_SORT_SBO_SIZE macro
Mike Becker <universe@uap-core.de>
parents:
655
diff
changeset
|
401 | #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
|
402 | #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
|
403 | #endif |
0a71ac9547fd
add CX_LINKED_LIST_SORT_SBO_SIZE macro
Mike Becker <universe@uap-core.de>
parents:
655
diff
changeset
|
404 | |
703
425d4279856f
improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents:
702
diff
changeset
|
405 | 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
|
406 | ptrdiff_t loc_prev, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
407 | ptrdiff_t loc_next, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
408 | ptrdiff_t loc_data, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
409 | size_t length, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
410 | void *ls, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
411 | void *le, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
412 | void *re, |
703
425d4279856f
improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents:
702
diff
changeset
|
413 | cx_compare_func cmp_func, |
425d4279856f
improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents:
702
diff
changeset
|
414 | void **begin, |
425d4279856f
improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents:
702
diff
changeset
|
415 | void **end |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
416 | ) { |
661
0a71ac9547fd
add CX_LINKED_LIST_SORT_SBO_SIZE macro
Mike Becker <universe@uap-core.de>
parents:
655
diff
changeset
|
417 | 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
|
418 | 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
|
419 | malloc(sizeof(void *) * length) : sbo; |
508
8aea65ae1eaf
#168 - add attributes and const
Mike Becker <universe@uap-core.de>
parents:
503
diff
changeset
|
420 | if (sorted == NULL) abort(); |
468
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
421 | void *rc, *lc; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
422 | |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
423 | lc = ls; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
424 | rc = le; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
425 | size_t n = 0; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
426 | while (lc && lc != le && rc != re) { |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
427 | 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
|
428 | sorted[n] = lc; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
429 | lc = ll_next(lc); |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
430 | } else { |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
431 | sorted[n] = rc; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
432 | rc = ll_next(rc); |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
433 | } |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
434 | n++; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
435 | } |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
436 | while (lc && lc != le) { |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
437 | sorted[n] = lc; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
438 | lc = ll_next(lc); |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
439 | n++; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
440 | } |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
441 | while (rc && rc != re) { |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
442 | sorted[n] = rc; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
443 | rc = ll_next(rc); |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
444 | n++; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
445 | } |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
446 | |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
447 | // Update pointer |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
448 | if (loc_prev >= 0) ll_prev(sorted[0]) = NULL; |
962
cd418898af5c
remove cx_for_n() macro - fixes #467
Mike Becker <universe@uap-core.de>
parents:
950
diff
changeset
|
449 | for (size_t i = 0 ; i < length - 1; i++) { |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
450 | 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
|
451 | } |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
452 | ll_next(sorted[length - 1]) = NULL; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
453 | |
703
425d4279856f
improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents:
702
diff
changeset
|
454 | *begin = sorted[0]; |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
455 | *end = sorted[length - 1]; |
468
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
456 | if (sorted != sbo) { |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
457 | free(sorted); |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
458 | } |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
459 | } |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
460 | |
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
592
diff
changeset
|
461 | 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
|
462 | void **begin, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
463 | void **end, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
464 | ptrdiff_t loc_prev, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
465 | ptrdiff_t loc_next, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
466 | 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
|
467 | cx_compare_func cmp_func |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
468 | ) { |
468
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
469 | assert(begin != NULL); |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
470 | assert(loc_next >= 0); |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
471 | assert(loc_data >= 0); |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
472 | assert(cmp_func); |
468
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
473 | |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
474 | void *lc, *ls, *le, *re; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
475 | |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
476 | // set start node |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
477 | ls = *begin; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
478 | |
702
3390b58ad15a
fix cx_linked_list_sort() not working for empty lists
Mike Becker <universe@uap-core.de>
parents:
699
diff
changeset
|
479 | // 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
|
480 | 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
|
481 | |
468
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
482 | // check how many elements are already sorted |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
483 | lc = ls; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
484 | size_t ln = 1; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
485 | 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
|
486 | lc = ll_next(lc); |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
487 | ln++; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
488 | } |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
489 | le = ll_next(lc); |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
490 | |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
491 | // 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
|
492 | if (le != NULL) { |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
493 | void *rc; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
494 | size_t rn = 1; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
495 | rc = le; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
496 | // skip already sorted elements |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
497 | 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
|
498 | rc = ll_next(rc); |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
499 | rn++; |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
500 | } |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
501 | re = ll_next(rc); |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
502 | |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
503 | // {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
|
504 | void *sorted_begin, *sorted_end; |
425d4279856f
improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents:
702
diff
changeset
|
505 | 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
|
506 | 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
|
507 | &sorted_begin, &sorted_end); |
468
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
508 | |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
509 | // Something left? Sort it! |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
510 | 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
|
511 | if (remainder_length > 0) { |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
512 | void *remainder = re; |
639
309e8b08c60e
temporarily remove pointer lists - see #234
Mike Becker <universe@uap-core.de>
parents:
638
diff
changeset
|
513 | 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
|
514 | |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
515 | // 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
|
516 | 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
|
517 | ln + rn + remainder_length, |
425d4279856f
improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents:
702
diff
changeset
|
518 | sorted_begin, remainder, NULL, cmp_func, |
425d4279856f
improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents:
702
diff
changeset
|
519 | &sorted_begin, &sorted_end); |
468
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
520 | } |
703
425d4279856f
improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents:
702
diff
changeset
|
521 | *begin = sorted_begin; |
425d4279856f
improve cx_linked_list_sort() - fixes #257
Mike Becker <universe@uap-core.de>
parents:
702
diff
changeset
|
522 | if (end) *end = sorted_end; |
468
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
523 | } |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
524 | } |
75ae1dccd101
add cx_linked_list_sort()
Mike Becker <universe@uap-core.de>
parents:
467
diff
changeset
|
525 | |
486
d7ca126eab7f
add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents:
481
diff
changeset
|
526 | int cx_linked_list_compare( |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
527 | const void *begin_left, |
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
528 | const void *begin_right, |
486
d7ca126eab7f
add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents:
481
diff
changeset
|
529 | ptrdiff_t loc_advance, |
d7ca126eab7f
add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents:
481
diff
changeset
|
530 | 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
|
531 | 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
|
532 | ) { |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
533 | const void *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
|
534 | |
d7ca126eab7f
add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents:
481
diff
changeset
|
535 | while (left != NULL && right != NULL) { |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
536 | const void *left_data = ll_data(left); |
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
537 | const void *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
|
538 | 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
|
539 | 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
|
540 | left = ll_advance(left); |
d7ca126eab7f
add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents:
481
diff
changeset
|
541 | right = ll_advance(right); |
d7ca126eab7f
add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents:
481
diff
changeset
|
542 | } |
d7ca126eab7f
add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents:
481
diff
changeset
|
543 | |
d7ca126eab7f
add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents:
481
diff
changeset
|
544 | 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
|
545 | 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
|
546 | else { return 0; } |
d7ca126eab7f
add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents:
481
diff
changeset
|
547 | } |
d7ca126eab7f
add cx_linked_list_compare() and simplifies some tests
Mike Becker <universe@uap-core.de>
parents:
481
diff
changeset
|
548 | |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
549 | void cx_linked_list_reverse( |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
550 | void **begin, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
551 | void **end, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
552 | ptrdiff_t loc_prev, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
553 | ptrdiff_t loc_next |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
554 | ) { |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
555 | assert(begin != NULL); |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
556 | assert(loc_next >= 0); |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
557 | |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
558 | // swap all links |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
559 | void *prev = NULL; |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
560 | void *cur = *begin; |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
561 | while (cur != NULL) { |
480
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
562 | void *next = ll_next(cur); |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
563 | |
480
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
564 | ll_next(cur) = prev; |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
565 | if (loc_prev >= 0) { |
480
e3be53a3354f
add cx_linked_list_find()
Mike Becker <universe@uap-core.de>
parents:
478
diff
changeset
|
566 | ll_prev(cur) = next; |
473
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
567 | } |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
568 | |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
569 | prev = cur; |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
570 | cur = next; |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
571 | } |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
572 | |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
573 | // update begin and end |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
574 | if (end != NULL) { |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
575 | *end = *begin; |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
576 | } |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
577 | *begin = prev; |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
578 | } |
1bd4b8c28722
add cx_linked_list_{prev, remove, reverse}
Mike Becker <universe@uap-core.de>
parents:
469
diff
changeset
|
579 | |
628
1e2be40f0cb5
use //-style single line comments everywhere
Mike Becker <universe@uap-core.de>
parents:
592
diff
changeset
|
580 | // HIGH LEVEL LINKED LIST IMPLEMENTATION |
398
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
581 | |
447
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
582 | 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
|
583 | struct cx_linked_list_node { |
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
584 | cx_linked_list_node *prev; |
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
585 | 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
|
586 | char payload[]; |
447
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
587 | }; |
402
a34b93911956
use named fields to access node memory
Mike Becker <universe@uap-core.de>
parents:
401
diff
changeset
|
588 | |
446
668757098b73
remove unnecessary fields from linked list node and simplifies cx_ll_add()
Mike Becker <universe@uap-core.de>
parents:
441
diff
changeset
|
589 | #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
|
590 | #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
|
591 | #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
|
592 | |
398
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
593 | typedef struct { |
500
eb9e7bd40a8e
do not hide pointers behind typedefs
Mike Becker <universe@uap-core.de>
parents:
499
diff
changeset
|
594 | 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
|
595 | 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
|
596 | cx_linked_list_node *end; |
398
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
597 | } cx_linked_list; |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
598 | |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
599 | static cx_linked_list_node *cx_ll_node_at( |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
600 | const cx_linked_list *list, |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
601 | size_t index |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
602 | ) { |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
603 | if (index >= list->base.collection.size) { |
447
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
604 | return NULL; |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
605 | } else if (index > list->base.collection.size / 2) { |
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
606 | return cx_linked_list_at(list->end, list->base.collection.size - 1, CX_LL_LOC_PREV, index); |
447
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
607 | } else { |
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
608 | 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
|
609 | } |
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
610 | } |
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
611 | |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
612 | static cx_linked_list_node *cx_ll_malloc_node(const struct cx_list_s *list) { |
879
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
613 | return cxMalloc(list->collection.allocator, |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
614 | sizeof(cx_linked_list_node) + list->collection.elem_size); |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
615 | } |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
616 | |
499
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
617 | static int cx_ll_insert_at( |
500
eb9e7bd40a8e
do not hide pointers behind typedefs
Mike Becker <universe@uap-core.de>
parents:
499
diff
changeset
|
618 | struct cx_list_s *list, |
499
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
619 | cx_linked_list_node *node, |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
620 | const void *elem |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
621 | ) { |
448
37c5d2fdb36b
implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents:
447
diff
changeset
|
622 | |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
623 | // create the new new_node |
879
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
624 | cx_linked_list_node *new_node = cx_ll_malloc_node(list); |
448
37c5d2fdb36b
implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents:
447
diff
changeset
|
625 | |
37c5d2fdb36b
implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents:
447
diff
changeset
|
626 | // sortir if failed |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
627 | if (new_node == NULL) return 1; |
448
37c5d2fdb36b
implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents:
447
diff
changeset
|
628 | |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
629 | // initialize new new_node |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
630 | new_node->prev = new_node->next = NULL; |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
631 | memcpy(new_node->payload, elem, list->collection.elem_size); |
448
37c5d2fdb36b
implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents:
447
diff
changeset
|
632 | |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
633 | // insert |
499
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
634 | 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
|
635 | cx_linked_list_insert_chain( |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
636 | (void **) &ll->begin, (void **) &ll->end, |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
637 | 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
|
638 | node, new_node, new_node |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
639 | ); |
448
37c5d2fdb36b
implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents:
447
diff
changeset
|
640 | |
37c5d2fdb36b
implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents:
447
diff
changeset
|
641 | // increase the size and return |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
642 | list->collection.size++; |
448
37c5d2fdb36b
implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents:
447
diff
changeset
|
643 | return 0; |
37c5d2fdb36b
implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents:
447
diff
changeset
|
644 | } |
37c5d2fdb36b
implement cx_ll_insert()
Mike Becker <universe@uap-core.de>
parents:
447
diff
changeset
|
645 | |
638
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
646 | static size_t cx_ll_insert_array( |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
647 | struct cx_list_s *list, |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
648 | size_t index, |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
649 | const void *array, |
638
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
650 | size_t n |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
651 | ) { |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
652 | // out-of bounds and corner case check |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
653 | if (index > list->collection.size || n == 0) return 0; |
638
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
654 | |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
655 | // find position efficiently |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
656 | 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
|
657 | |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
658 | // perform first insert |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
659 | if (0 != cx_ll_insert_at(list, node, array)) { |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
660 | return 1; |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
661 | } |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
662 | |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
663 | // is there more? |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
664 | if (n == 1) return 1; |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
665 | |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
666 | // we now know exactly where we are |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
667 | 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
|
668 | |
879
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
669 | // we can add the remaining nodes and immediately advance to the inserted node |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
670 | const char *source = array; |
638
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
671 | for (size_t i = 1; i < n; i++) { |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
672 | source += list->collection.elem_size; |
638
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
673 | if (0 != cx_ll_insert_at(list, node, source)) { |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
674 | return i; |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
675 | } |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
676 | node = node->next; |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
677 | } |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
678 | return n; |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
679 | } |
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
680 | |
641
d402fead3386
add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents:
640
diff
changeset
|
681 | static int cx_ll_insert_element( |
d402fead3386
add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents:
640
diff
changeset
|
682 | struct cx_list_s *list, |
d402fead3386
add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents:
640
diff
changeset
|
683 | size_t index, |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
684 | const void *element |
641
d402fead3386
add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents:
640
diff
changeset
|
685 | ) { |
d402fead3386
add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents:
640
diff
changeset
|
686 | 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
|
687 | } |
d402fead3386
add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents:
640
diff
changeset
|
688 | |
880
54133f14043f
fix cx_ll_insert_sorted_cmp_func not being thread local
Mike Becker <universe@uap-core.de>
parents:
879
diff
changeset
|
689 | static _Thread_local cx_compare_func cx_ll_insert_sorted_cmp_func; |
879
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
690 | |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
691 | static int cx_ll_insert_sorted_cmp_helper(const void *l, const void *r) { |
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
692 | const cx_linked_list_node *left = l; |
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
693 | const cx_linked_list_node *right = r; |
879
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
694 | return cx_ll_insert_sorted_cmp_func(left->payload, right->payload); |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
695 | } |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
696 | |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
697 | static size_t cx_ll_insert_sorted( |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
698 | struct cx_list_s *list, |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
699 | const void *array, |
879
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
700 | size_t n |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
701 | ) { |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
702 | // special case |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
703 | if (n == 0) return 0; |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
704 | |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
705 | // create a new chain of nodes |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
706 | cx_linked_list_node *chain = cx_ll_malloc_node(list); |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
707 | if (chain == NULL) return 0; |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
708 | |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
709 | memcpy(chain->payload, array, list->collection.elem_size); |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
710 | chain->prev = NULL; |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
711 | chain->next = NULL; |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
712 | |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
713 | // add all elements from the array to that chain |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
714 | cx_linked_list_node *prev = chain; |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
715 | const char *src = array; |
879
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
716 | size_t inserted = 1; |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
717 | for (; inserted < n; inserted++) { |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
718 | cx_linked_list_node *next = cx_ll_malloc_node(list); |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
719 | if (next == NULL) break; |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
720 | src += list->collection.elem_size; |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
721 | memcpy(next->payload, src, list->collection.elem_size); |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
722 | prev->next = next; |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
723 | next->prev = prev; |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
724 | prev = next; |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
725 | } |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
726 | prev->next = NULL; |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
727 | |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
728 | // invoke the low level function |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
729 | cx_linked_list *ll = (cx_linked_list *) list; |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
730 | cx_ll_insert_sorted_cmp_func = list->collection.cmpfunc; |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
731 | cx_linked_list_insert_sorted_chain( |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
732 | (void **) &ll->begin, |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
733 | (void **) &ll->end, |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
734 | CX_LL_LOC_PREV, |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
735 | CX_LL_LOC_NEXT, |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
736 | chain, |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
737 | cx_ll_insert_sorted_cmp_helper |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
738 | ); |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
739 | |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
740 | // adjust the list metadata |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
741 | list->collection.size += inserted; |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
742 | |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
743 | return inserted; |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
744 | } |
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
745 | |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
746 | static size_t cx_ll_remove( |
500
eb9e7bd40a8e
do not hide pointers behind typedefs
Mike Becker <universe@uap-core.de>
parents:
499
diff
changeset
|
747 | struct cx_list_s *list, |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
748 | size_t index, |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
749 | size_t num, |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
750 | void *targetbuf |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
751 | ) { |
447
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
752 | cx_linked_list *ll = (cx_linked_list *) list; |
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
753 | 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
|
754 | |
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
755 | // out-of-bounds check |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
756 | if (node == NULL) return 0; |
664
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
757 | |
476
60ff4561dc04
change contract of cx_linked_list_remove()
Mike Becker <universe@uap-core.de>
parents:
475
diff
changeset
|
758 | // remove |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
759 | size_t removed = cx_linked_list_remove_chain( |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
760 | (void **) &ll->begin, |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
761 | (void **) &ll->end, |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
762 | CX_LL_LOC_PREV, |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
763 | CX_LL_LOC_NEXT, |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
764 | node, |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
765 | num |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
766 | ); |
447
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
767 | |
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
768 | // adjust size |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
769 | list->collection.size -= removed; |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
770 | |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
771 | // copy or destroy the removed chain |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
772 | if (targetbuf == NULL) { |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
773 | cx_linked_list_node *n = node; |
962
cd418898af5c
remove cx_for_n() macro - fixes #467
Mike Becker <universe@uap-core.de>
parents:
950
diff
changeset
|
774 | for (size_t i = 0; i < removed; i++) { |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
775 | // element destruction |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
776 | cx_invoke_destructor(list, n->payload); |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
777 | |
925
fd6e191f3268
fix invalid reads when removing linked list nodes
Mike Becker <universe@uap-core.de>
parents:
919
diff
changeset
|
778 | // free the node and advance |
fd6e191f3268
fix invalid reads when removing linked list nodes
Mike Becker <universe@uap-core.de>
parents:
919
diff
changeset
|
779 | void *next = n->next; |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
780 | cxFree(list->collection.allocator, n); |
925
fd6e191f3268
fix invalid reads when removing linked list nodes
Mike Becker <universe@uap-core.de>
parents:
919
diff
changeset
|
781 | n = next; |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
782 | } |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
783 | } else { |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
784 | char *dest = targetbuf; |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
785 | cx_linked_list_node *n = node; |
962
cd418898af5c
remove cx_for_n() macro - fixes #467
Mike Becker <universe@uap-core.de>
parents:
950
diff
changeset
|
786 | for (size_t i = 0; i < removed; i++) { |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
787 | // copy payload |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
788 | memcpy(dest, n->payload, list->collection.elem_size); |
447
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
789 | |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
790 | // advance target buffer |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
791 | dest += list->collection.elem_size; |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
792 | |
925
fd6e191f3268
fix invalid reads when removing linked list nodes
Mike Becker <universe@uap-core.de>
parents:
919
diff
changeset
|
793 | // free the node and advance |
fd6e191f3268
fix invalid reads when removing linked list nodes
Mike Becker <universe@uap-core.de>
parents:
919
diff
changeset
|
794 | void *next = n->next; |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
795 | cxFree(list->collection.allocator, n); |
925
fd6e191f3268
fix invalid reads when removing linked list nodes
Mike Becker <universe@uap-core.de>
parents:
919
diff
changeset
|
796 | n = next; |
919
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
797 | } |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
798 | } |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
799 | |
75da57d4634e
add possibility to remove arrays of data and retrieve removed data
Mike Becker <universe@uap-core.de>
parents:
890
diff
changeset
|
800 | return removed; |
398
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
801 | } |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
802 | |
664
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
803 | static void cx_ll_clear(struct cx_list_s *list) { |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
804 | if (list->collection.size == 0) return; |
664
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
805 | |
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
806 | 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
|
807 | 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
|
808 | 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
|
809 | 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
|
810 | cx_linked_list_node *next = node->next; |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
811 | cxFree(list->collection.allocator, node); |
677
b09aae58bba4
refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents:
670
diff
changeset
|
812 | node = next; |
664
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
813 | } |
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
814 | ll->begin = ll->end = NULL; |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
815 | list->collection.size = 0; |
664
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
816 | } |
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
817 | |
647
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
818 | #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
|
819 | #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
|
820 | #endif |
926
8fdd8d78c14b
fix several survivors of east-const and some missing consts
Mike Becker <universe@uap-core.de>
parents:
925
diff
changeset
|
821 | const unsigned cx_linked_list_swap_sbo_size = CX_LINKED_LIST_SWAP_SBO_SIZE; |
647
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
822 | |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
823 | static int cx_ll_swap( |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
824 | struct cx_list_s *list, |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
825 | size_t i, |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
826 | size_t j |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
827 | ) { |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
828 | if (i >= list->collection.size || j >= list->collection.size) return 1; |
647
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
829 | if (i == j) return 0; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
830 | |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
831 | // 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
|
832 | cx_linked_list *ll = (cx_linked_list *) list; |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
833 | size_t mid = list->collection.size / 2; |
647
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
834 | size_t left, right; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
835 | if (i < j) { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
836 | left = i; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
837 | right = j; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
838 | } else { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
839 | left = j; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
840 | right = i; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
841 | } |
950
37e7f92de46b
fix missing pointer initializations
Mike Becker <universe@uap-core.de>
parents:
926
diff
changeset
|
842 | cx_linked_list_node *nleft = NULL, *nright = NULL; |
647
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
843 | if (left < mid && right < mid) { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
844 | // 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
|
845 | nleft = cx_ll_node_at(ll, left); |
807
c8d692131b1e
remove flags to disable SBO in tests - fix #343 fix #358
Mike Becker <universe@uap-core.de>
parents:
764
diff
changeset
|
846 | assert(nleft != NULL); |
647
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
847 | nright = nleft; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
848 | 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
|
849 | nright = nright->next; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
850 | } |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
851 | } 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
|
852 | // 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
|
853 | nright = cx_ll_node_at(ll, right); |
807
c8d692131b1e
remove flags to disable SBO in tests - fix #343 fix #358
Mike Becker <universe@uap-core.de>
parents:
764
diff
changeset
|
854 | assert(nright != NULL); |
647
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
855 | nleft = nright; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
856 | 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
|
857 | nleft = nleft->prev; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
858 | } |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
859 | } else { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
860 | // 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
|
861 | |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
862 | // 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
|
863 | size_t closest; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
864 | size_t other; |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
865 | size_t diff2boundary = list->collection.size - right - 1; |
647
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
866 | if (left <= diff2boundary) { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
867 | closest = left; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
868 | other = right; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
869 | 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
|
870 | } else { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
871 | closest = right; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
872 | other = left; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
873 | diff2boundary = left; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
874 | 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
|
875 | } |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
876 | |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
877 | // 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
|
878 | if (right - left <= diff2boundary) { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
879 | // 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
|
880 | if (closest == left) { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
881 | nright = nleft; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
882 | 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
|
883 | nright = nright->next; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
884 | } |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
885 | } else { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
886 | nleft = nright; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
887 | 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
|
888 | nleft = nleft->prev; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
889 | } |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
890 | } |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
891 | } else { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
892 | // 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
|
893 | if (closest == left) { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
894 | 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
|
895 | } else { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
896 | 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
|
897 | } |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
898 | } |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
899 | } |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
900 | |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
901 | if (list->collection.elem_size > CX_LINKED_LIST_SWAP_SBO_SIZE) { |
647
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
902 | 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
|
903 | 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
|
904 | 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
|
905 | 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
|
906 | |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
907 | if (prev == NULL) { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
908 | ll->begin = nright; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
909 | } else { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
910 | prev->next = nright; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
911 | } |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
912 | nright->prev = prev; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
913 | if (midstart == nright) { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
914 | // 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
|
915 | nright->next = nleft; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
916 | nleft->prev = nright; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
917 | } else { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
918 | // 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
|
919 | nright->next = midstart; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
920 | midstart->prev = nright; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
921 | midend->next = nleft; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
922 | nleft->prev = midend; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
923 | } |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
924 | nleft->next = next; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
925 | if (next == NULL) { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
926 | ll->end = nleft; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
927 | } else { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
928 | next->prev = nleft; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
929 | } |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
930 | } else { |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
931 | // swap payloads to avoid relinking |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
932 | char buf[CX_LINKED_LIST_SWAP_SBO_SIZE]; |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
933 | memcpy(buf, nleft->payload, list->collection.elem_size); |
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
934 | memcpy(nleft->payload, nright->payload, list->collection.elem_size); |
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
935 | memcpy(nright->payload, buf, list->collection.elem_size); |
647
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
936 | } |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
937 | |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
938 | return 0; |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
939 | } |
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
940 | |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
941 | static void *cx_ll_at( |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
942 | const struct cx_list_s *list, |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
943 | size_t index |
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
944 | ) { |
439
9a5adedd6de6
add high-level function cxListAt()
Mike Becker <universe@uap-core.de>
parents:
438
diff
changeset
|
945 | cx_linked_list *ll = (cx_linked_list *) list; |
447
87b2cdd668ed
implement cx_ll_remove()
Mike Becker <universe@uap-core.de>
parents:
446
diff
changeset
|
946 | 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
|
947 | 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
|
948 | } |
28bc3e10ac28
add special linked list implementation for storing pointers
Mike Becker <universe@uap-core.de>
parents:
457
diff
changeset
|
949 | |
764
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
950 | 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
|
951 | struct cx_list_s *list, |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
952 | const void *elem, |
764
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
953 | bool remove |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
954 | ) { |
764
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
955 | if (remove) { |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
956 | 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
|
957 | cx_linked_list_node *node; |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
958 | 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
|
959 | (void **) &node, |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
960 | ll->begin, |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
961 | CX_LL_LOC_NEXT, CX_LL_LOC_DATA, |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
962 | list->collection.cmpfunc, elem |
764
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
963 | ); |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
964 | if (node != NULL) { |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
965 | 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
|
966 | 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
|
967 | CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node); |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
968 | list->collection.size--; |
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
969 | cxFree(list->collection.allocator, node); |
764
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
970 | } |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
971 | return index; |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
972 | } else { |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
973 | return cx_linked_list_find( |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
974 | ((cx_linked_list *) list)->begin, |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
975 | CX_LL_LOC_NEXT, CX_LL_LOC_DATA, |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
976 | list->collection.cmpfunc, elem |
764
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
977 | ); |
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
978 | } |
466
28bc3e10ac28
add special linked list implementation for storing pointers
Mike Becker <universe@uap-core.de>
parents:
457
diff
changeset
|
979 | } |
28bc3e10ac28
add special linked list implementation for storing pointers
Mike Becker <universe@uap-core.de>
parents:
457
diff
changeset
|
980 | |
500
eb9e7bd40a8e
do not hide pointers behind typedefs
Mike Becker <universe@uap-core.de>
parents:
499
diff
changeset
|
981 | 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
|
982 | 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
|
983 | 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
|
984 | CX_LL_LOC_PREV, CX_LL_LOC_NEXT, CX_LL_LOC_DATA, |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
985 | list->collection.cmpfunc); |
469
0458bff0b1cd
add high level list sort and inlines method invocation functions
Mike Becker <universe@uap-core.de>
parents:
468
diff
changeset
|
986 | } |
0458bff0b1cd
add high level list sort and inlines method invocation functions
Mike Becker <universe@uap-core.de>
parents:
468
diff
changeset
|
987 | |
500
eb9e7bd40a8e
do not hide pointers behind typedefs
Mike Becker <universe@uap-core.de>
parents:
499
diff
changeset
|
988 | static void cx_ll_reverse(struct cx_list_s *list) { |
490 | 989 | cx_linked_list *ll = (cx_linked_list *) list; |
521
e5dc54131d55
add test for cxListCompare
Mike Becker <universe@uap-core.de>
parents:
509
diff
changeset
|
990 | cx_linked_list_reverse((void **) &ll->begin, (void **) &ll->end, CX_LL_LOC_PREV, CX_LL_LOC_NEXT); |
490 | 991 | } |
992 | ||
488
9138acaa494b
add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents:
487
diff
changeset
|
993 | static int cx_ll_compare( |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
994 | const struct cx_list_s *list, |
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
995 | const struct cx_list_s *other |
488
9138acaa494b
add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents:
487
diff
changeset
|
996 | ) { |
9138acaa494b
add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents:
487
diff
changeset
|
997 | cx_linked_list *left = (cx_linked_list *) list; |
9138acaa494b
add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents:
487
diff
changeset
|
998 | cx_linked_list *right = (cx_linked_list *) other; |
9138acaa494b
add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents:
487
diff
changeset
|
999 | return cx_linked_list_compare(left->begin, right->begin, |
9138acaa494b
add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents:
487
diff
changeset
|
1000 | CX_LL_LOC_NEXT, CX_LL_LOC_DATA, |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
1001 | list->collection.cmpfunc); |
488
9138acaa494b
add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents:
487
diff
changeset
|
1002 | } |
9138acaa494b
add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents:
487
diff
changeset
|
1003 | |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
1004 | static bool cx_ll_iter_valid(const void *it) { |
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
1005 | const 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
|
1006 | return iter->elem_handle != NULL; |
494
6ce8cfa10a96
add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents:
490
diff
changeset
|
1007 | } |
6ce8cfa10a96
add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents:
490
diff
changeset
|
1008 | |
630
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
1009 | static void cx_ll_iter_next(void *it) { |
853
d4baf4dd55c3
simplify iterator structures
Mike Becker <universe@uap-core.de>
parents:
850
diff
changeset
|
1010 | struct cx_iterator_s *iter = it; |
854
fe0d69d72bcd
fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents:
853
diff
changeset
|
1011 | if (iter->base.remove) { |
fe0d69d72bcd
fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents:
853
diff
changeset
|
1012 | iter->base.remove = false; |
853
d4baf4dd55c3
simplify iterator structures
Mike Becker <universe@uap-core.de>
parents:
850
diff
changeset
|
1013 | struct cx_list_s *list = iter->src_handle.m; |
d4baf4dd55c3
simplify iterator structures
Mike Becker <universe@uap-core.de>
parents:
850
diff
changeset
|
1014 | cx_linked_list *ll = iter->src_handle.m; |
495
2856c74e18ba
add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents:
494
diff
changeset
|
1015 | 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
|
1016 | 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
|
1017 | 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
|
1018 | 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
|
1019 | CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node); |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
1020 | list->collection.size--; |
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
1021 | cxFree(list->collection.allocator, node); |
495
2856c74e18ba
add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents:
494
diff
changeset
|
1022 | } else { |
2856c74e18ba
add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents:
494
diff
changeset
|
1023 | iter->index++; |
2856c74e18ba
add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents:
494
diff
changeset
|
1024 | 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
|
1025 | iter->elem_handle = node->next; |
2856c74e18ba
add the feature to remove items during iteration
Mike Becker <universe@uap-core.de>
parents:
494
diff
changeset
|
1026 | } |
494
6ce8cfa10a96
add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents:
490
diff
changeset
|
1027 | } |
6ce8cfa10a96
add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents:
490
diff
changeset
|
1028 | |
655
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
1029 | static void cx_ll_iter_prev(void *it) { |
853
d4baf4dd55c3
simplify iterator structures
Mike Becker <universe@uap-core.de>
parents:
850
diff
changeset
|
1030 | struct cx_iterator_s *iter = it; |
854
fe0d69d72bcd
fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents:
853
diff
changeset
|
1031 | if (iter->base.remove) { |
fe0d69d72bcd
fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents:
853
diff
changeset
|
1032 | iter->base.remove = false; |
853
d4baf4dd55c3
simplify iterator structures
Mike Becker <universe@uap-core.de>
parents:
850
diff
changeset
|
1033 | struct cx_list_s *list = iter->src_handle.m; |
d4baf4dd55c3
simplify iterator structures
Mike Becker <universe@uap-core.de>
parents:
850
diff
changeset
|
1034 | cx_linked_list *ll = iter->src_handle.m; |
655
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
1035 | cx_linked_list_node *node = iter->elem_handle; |
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
1036 | iter->elem_handle = node->prev; |
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
1037 | 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
|
1038 | cx_invoke_destructor(list, node->payload); |
655
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
1039 | 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
|
1040 | CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node); |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
1041 | list->collection.size--; |
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
1042 | cxFree(list->collection.allocator, node); |
655
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
1043 | } else { |
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
1044 | iter->index--; |
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
1045 | cx_linked_list_node *node = iter->elem_handle; |
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
1046 | iter->elem_handle = node->prev; |
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
1047 | } |
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
1048 | } |
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
1049 | |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
1050 | static void *cx_ll_iter_current(const void *it) { |
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
1051 | const 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
|
1052 | 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
|
1053 | return node->payload; |
6ce8cfa10a96
add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents:
490
diff
changeset
|
1054 | } |
6ce8cfa10a96
add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents:
490
diff
changeset
|
1055 | |
6ce8cfa10a96
add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents:
490
diff
changeset
|
1056 | static CxIterator cx_ll_iterator( |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
1057 | const struct cx_list_s *list, |
655
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
1058 | size_t index, |
7340c4255f1f
implement backwards iterator - fixes #238
Mike Becker <universe@uap-core.de>
parents:
654
diff
changeset
|
1059 | bool backwards |
494
6ce8cfa10a96
add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents:
490
diff
changeset
|
1060 | ) { |
6ce8cfa10a96
add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents:
490
diff
changeset
|
1061 | CxIterator iter; |
6ce8cfa10a96
add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents:
490
diff
changeset
|
1062 | iter.index = index; |
853
d4baf4dd55c3
simplify iterator structures
Mike Becker <universe@uap-core.de>
parents:
850
diff
changeset
|
1063 | iter.src_handle.c = list; |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
1064 | iter.elem_handle = cx_ll_node_at((const cx_linked_list *) list, index); |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
1065 | iter.elem_size = list->collection.elem_size; |
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
1066 | iter.elem_count = list->collection.size; |
854
fe0d69d72bcd
fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents:
853
diff
changeset
|
1067 | iter.base.valid = cx_ll_iter_valid; |
fe0d69d72bcd
fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents:
853
diff
changeset
|
1068 | iter.base.current = cx_ll_iter_current; |
fe0d69d72bcd
fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents:
853
diff
changeset
|
1069 | iter.base.next = backwards ? cx_ll_iter_prev : cx_ll_iter_next; |
fe0d69d72bcd
fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents:
853
diff
changeset
|
1070 | iter.base.mutating = false; |
fe0d69d72bcd
fix members inherited by macro or include are not documented
Mike Becker <universe@uap-core.de>
parents:
853
diff
changeset
|
1071 | iter.base.remove = false; |
494
6ce8cfa10a96
add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents:
490
diff
changeset
|
1072 | return iter; |
6ce8cfa10a96
add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents:
490
diff
changeset
|
1073 | } |
6ce8cfa10a96
add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents:
490
diff
changeset
|
1074 | |
499
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
1075 | static int cx_ll_insert_iter( |
853
d4baf4dd55c3
simplify iterator structures
Mike Becker <universe@uap-core.de>
parents:
850
diff
changeset
|
1076 | CxIterator *iter, |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
1077 | const void *elem, |
499
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
1078 | int prepend |
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
1079 | ) { |
853
d4baf4dd55c3
simplify iterator structures
Mike Becker <universe@uap-core.de>
parents:
850
diff
changeset
|
1080 | struct cx_list_s *list = iter->src_handle.m; |
499
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
1081 | cx_linked_list_node *node = iter->elem_handle; |
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
1082 | if (node != NULL) { |
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
1083 | assert(prepend >= 0 && prepend <= 1); |
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
1084 | cx_linked_list_node *choice[2] = {node, node->prev}; |
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
1085 | int result = cx_ll_insert_at(list, choice[prepend], elem); |
874
cdce47f34d48
fix inserting via iterator correctly increases element count
Mike Becker <universe@uap-core.de>
parents:
856
diff
changeset
|
1086 | if (result == 0) { |
cdce47f34d48
fix inserting via iterator correctly increases element count
Mike Becker <universe@uap-core.de>
parents:
856
diff
changeset
|
1087 | iter->elem_count++; |
cdce47f34d48
fix inserting via iterator correctly increases element count
Mike Becker <universe@uap-core.de>
parents:
856
diff
changeset
|
1088 | if (prepend) { |
cdce47f34d48
fix inserting via iterator correctly increases element count
Mike Becker <universe@uap-core.de>
parents:
856
diff
changeset
|
1089 | iter->index++; |
cdce47f34d48
fix inserting via iterator correctly increases element count
Mike Becker <universe@uap-core.de>
parents:
856
diff
changeset
|
1090 | } |
cdce47f34d48
fix inserting via iterator correctly increases element count
Mike Becker <universe@uap-core.de>
parents:
856
diff
changeset
|
1091 | } |
499
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
1092 | return result; |
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
1093 | } else { |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
1094 | int result = cx_ll_insert_element(list, list->collection.size, elem); |
874
cdce47f34d48
fix inserting via iterator correctly increases element count
Mike Becker <universe@uap-core.de>
parents:
856
diff
changeset
|
1095 | if (result == 0) { |
cdce47f34d48
fix inserting via iterator correctly increases element count
Mike Becker <universe@uap-core.de>
parents:
856
diff
changeset
|
1096 | iter->elem_count++; |
cdce47f34d48
fix inserting via iterator correctly increases element count
Mike Becker <universe@uap-core.de>
parents:
856
diff
changeset
|
1097 | iter->index = list->collection.size; |
cdce47f34d48
fix inserting via iterator correctly increases element count
Mike Becker <universe@uap-core.de>
parents:
856
diff
changeset
|
1098 | } |
499
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
1099 | return result; |
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
1100 | } |
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
1101 | } |
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
1102 | |
524 | 1103 | static void cx_ll_destructor(CxList *list) { |
1104 | cx_linked_list *ll = (cx_linked_list *) list; | |
1105 | ||
1106 | cx_linked_list_node *node = ll->begin; | |
1107 | while (node) { | |
708
1caed6c9ba68
fix inconsistent destructor requirements for list and map classes
Mike Becker <universe@uap-core.de>
parents:
703
diff
changeset
|
1108 | cx_invoke_destructor(list, node->payload); |
524 | 1109 | void *next = node->next; |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
1110 | cxFree(list->collection.allocator, node); |
524 | 1111 | node = next; |
1112 | } | |
708
1caed6c9ba68
fix inconsistent destructor requirements for list and map classes
Mike Becker <universe@uap-core.de>
parents:
703
diff
changeset
|
1113 | |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
1114 | cxFree(list->collection.allocator, list); |
524 | 1115 | } |
1116 | ||
451
db06dda7ac4d
make cx_linked_list_class static
Mike Becker <universe@uap-core.de>
parents:
448
diff
changeset
|
1117 | static cx_list_class cx_linked_list_class = { |
524 | 1118 | cx_ll_destructor, |
641
d402fead3386
add new pointer list wrapper - resolves #234
Mike Becker <universe@uap-core.de>
parents:
640
diff
changeset
|
1119 | cx_ll_insert_element, |
638
eafb45eefc51
add cxListInsertArray() - fixes #224
Mike Becker <universe@uap-core.de>
parents:
630
diff
changeset
|
1120 | cx_ll_insert_array, |
879
9c24a4eb5ac9
implement optimized sorted insert for linked lists - resolves #415
Mike Becker <universe@uap-core.de>
parents:
876
diff
changeset
|
1121 | cx_ll_insert_sorted, |
499
3dc9075df822
add cxListInsertAfter() and cxListInsertBefore()
Mike Becker <universe@uap-core.de>
parents:
495
diff
changeset
|
1122 | cx_ll_insert_iter, |
398
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
1123 | cx_ll_remove, |
664
af5bf4603a5d
add cxListClear and fix missing destructor invocations - #241 #246
Mike Becker <universe@uap-core.de>
parents:
662
diff
changeset
|
1124 | cx_ll_clear, |
647
2e6e9d9f2159
implement swap function for list elements - fixes #218
Mike Becker <universe@uap-core.de>
parents:
641
diff
changeset
|
1125 | cx_ll_swap, |
439
9a5adedd6de6
add high-level function cxListAt()
Mike Becker <universe@uap-core.de>
parents:
438
diff
changeset
|
1126 | cx_ll_at, |
764
ccbdbd088455
add cxListFindRemove and cx_linked_list_find_node
Mike Becker <universe@uap-core.de>
parents:
763
diff
changeset
|
1127 | cx_ll_find_remove, |
488
9138acaa494b
add cxLinkedListFromArray() and cxListCompare()
Mike Becker <universe@uap-core.de>
parents:
487
diff
changeset
|
1128 | cx_ll_sort, |
490 | 1129 | cx_ll_compare, |
494
6ce8cfa10a96
add iterator interface + linked list iterator
Mike Becker <universe@uap-core.de>
parents:
490
diff
changeset
|
1130 | cx_ll_reverse, |
630
ac5e7f789048
separate iterators and mutating iterators
Mike Becker <universe@uap-core.de>
parents:
629
diff
changeset
|
1131 | cx_ll_iterator, |
398
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
1132 | }; |
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
1133 | |
670
4ad8ea3aee49
allow NULL for allocator and comparator
Mike Becker <universe@uap-core.de>
parents:
667
diff
changeset
|
1134 | CxList *cxLinkedListCreate( |
890
54565fd74e74
move all const keywords to the west - fixes #426
Mike Becker <universe@uap-core.de>
parents:
880
diff
changeset
|
1135 | const CxAllocator *allocator, |
677
b09aae58bba4
refactoring of collections to make use of destructors in map implementations
Mike Becker <universe@uap-core.de>
parents:
670
diff
changeset
|
1136 | cx_compare_func comparator, |
855
35bcb3216c0d
fix inconsistent use of item_size and elem_size
Mike Becker <universe@uap-core.de>
parents:
854
diff
changeset
|
1137 | size_t elem_size |
481
eef025d82a34
add several new linked list functions
Mike Becker <universe@uap-core.de>
parents:
480
diff
changeset
|
1138 | ) { |
670
4ad8ea3aee49
allow NULL for allocator and comparator
Mike Becker <universe@uap-core.de>
parents:
667
diff
changeset
|
1139 | if (allocator == NULL) { |
4ad8ea3aee49
allow NULL for allocator and comparator
Mike Becker <universe@uap-core.de>
parents:
667
diff
changeset
|
1140 | allocator = cxDefaultAllocator; |
4ad8ea3aee49
allow NULL for allocator and comparator
Mike Becker <universe@uap-core.de>
parents:
667
diff
changeset
|
1141 | } |
4ad8ea3aee49
allow NULL for allocator and comparator
Mike Becker <universe@uap-core.de>
parents:
667
diff
changeset
|
1142 | |
503
a89857072ace
add new destructor API and apply it to CxList
Mike Becker <universe@uap-core.de>
parents:
500
diff
changeset
|
1143 | 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
|
1144 | if (list == NULL) return NULL; |
398
8d506ed6c1c0
adds first draft for linked list implementation
Mike Becker <universe@uap-core.de>
parents:
diff
changeset
|
1145 | |
435
0fe204d50f54
change inheritance model for lists
Mike Becker <universe@uap-core.de>
parents:
428
diff
changeset
|
1146 | list->base.cl = &cx_linked_list_class; |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
1147 | list->base.collection.allocator = allocator; |
406
9cbea761fbf7
adds cxLinkedListWrap and cxLinkedListRecalculateSize
Mike Becker <universe@uap-core.de>
parents:
404
diff
changeset
|
1148 | |
855
35bcb3216c0d
fix inconsistent use of item_size and elem_size
Mike Becker <universe@uap-core.de>
parents:
854
diff
changeset
|
1149 | if (elem_size > 0) { |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
1150 | list->base.collection.elem_size = elem_size; |
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
1151 | list->base.collection.cmpfunc = comparator; |
667
2f88a7c13a28
add CX_STORE_POINTERS special "item size" for lists
Mike Becker <universe@uap-core.de>
parents:
666
diff
changeset
|
1152 | } else { |
856
6bbbf219251d
fix name of collection base member (to avoid base.base)
Mike Becker <universe@uap-core.de>
parents:
855
diff
changeset
|
1153 | list->base.collection.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
|
1154 | cxListStorePointers((CxList *) list); |
2f88a7c13a28
add CX_STORE_POINTERS special "item size" for lists
Mike Becker <universe@uap-core.de>
parents:
666
diff
changeset
|
1155 | } |
2f88a7c13a28
add CX_STORE_POINTERS special "item size" for lists
Mike Becker <universe@uap-core.de>
parents:
666
diff
changeset
|
1156 | |
500
eb9e7bd40a8e
do not hide pointers behind typedefs
Mike Becker <universe@uap-core.de>
parents:
499
diff
changeset
|
1157 | return (CxList *) list; |
406
9cbea761fbf7
adds cxLinkedListWrap and cxLinkedListRecalculateSize
Mike Becker <universe@uap-core.de>
parents:
404
diff
changeset
|
1158 | } |