src/linked_list.c

Sun, 14 Jan 2024 13:50:17 +0100

author
Mike Becker <universe@uap-core.de>
date
Sun, 14 Jan 2024 13:50:17 +0100
changeset 806
e06249e09f99
parent 764
ccbdbd088455
child 807
c8d692131b1e
permissions
-rw-r--r--

add constant for reading out strstr sbo size - relates to #343

also fixes the related test which was working with the old SBO size of 256 and was broken after increasing it to 512

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

mercurial