/src/freeradius-server/src/freeradius-devel/util/lst.h
Line | Count | Source |
1 | | #pragma once |
2 | | /* |
3 | | * This program is free software; you can redistribute it and/or modify |
4 | | * it under the terms of the GNU General Public License as published by |
5 | | * the Free Software Foundation; either version 2 of the License, or |
6 | | * (at your option) any later version. |
7 | | * |
8 | | * This program is distributed in the hope that it will be useful, |
9 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | | * GNU General Public License for more details. |
12 | | * |
13 | | * You should have received a copy of the GNU General Public License |
14 | | * along with this program; if not, write to the Free Software |
15 | | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
16 | | */ |
17 | | |
18 | | /** Structures and prototypes for leftmost skeleton trees (LSTs) |
19 | | * |
20 | | * @file src/lib/util/lst.h |
21 | | * |
22 | | * @copyright 2021 Network RADIUS SAS (legal@networkradius.com) |
23 | | */ |
24 | | RCSIDH(lst_h, "$Id: 820bdb0f6c461937d236d6fa304d698e7f37eb5b $") |
25 | | |
26 | | #ifdef __cplusplus |
27 | | extern "C" { |
28 | | #endif |
29 | | |
30 | | #include <freeradius-devel/build.h> |
31 | | #include <freeradius-devel/util/misc.h> |
32 | | #include <freeradius-devel/util/talloc.h> |
33 | | |
34 | | #include <stdint.h> |
35 | | |
36 | | typedef struct fr_lst_s fr_lst_t; |
37 | | |
38 | | /* |
39 | | * The type of LST indexes. |
40 | | * The type passed to fr_lst_alloc() and fr_lst_talloc_alloc() in _type must be the |
41 | | * type of a structure with a member of type fr_lst_index_t. That member's name must be |
42 | | * passed as the _field argument. |
43 | | */ |
44 | | typedef unsigned int fr_lst_index_t; |
45 | | |
46 | | typedef fr_lst_index_t fr_lst_iter_t; |
47 | | |
48 | | /** Creates an LST that can be used with non-talloced elements |
49 | | * |
50 | | * @param[in] _ctx Talloc ctx to allocate LST in. |
51 | | * @param[in] _cmp Comparator used to compare elements. |
52 | | * @param[in] _type Of elements. |
53 | | * @param[in] _field to store LST indexes in. |
54 | | * @param[in] _init initial capacity (0 for default initial size); |
55 | | * the capacity will be rounded up to a power of two. |
56 | | * @return |
57 | | * - A pointer to the new LST. |
58 | | * - NULL on error |
59 | | */ |
60 | | #define fr_lst_alloc(_ctx, _cmp, _type, _field, _init) \ |
61 | | _fr_lst_alloc(_ctx, _cmp, NULL, (size_t)offsetof(_type, _field), _init) |
62 | | |
63 | | /** Creates an LST that verifies elements are of a specific talloc type |
64 | | * |
65 | | * @param[in] _ctx Talloc ctx to allocate LST in. |
66 | | * @param[in] _cmp Comparator used to compare elements. |
67 | | * @param[in] _talloc_type of elements. |
68 | | * @param[in] _field to store heap indexes in. |
69 | | * @param[in] _init initial capacity (0 for default initial size); |
70 | | * the capacity will be rounded up to a power of two. |
71 | | * @return |
72 | | * - A pointer to the new LST. |
73 | | * - NULL on error. |
74 | | */ |
75 | | #define fr_lst_talloc_alloc(_ctx, _cmp, _talloc_type, _field, _init) \ |
76 | 0 | _fr_lst_alloc(_ctx, _cmp, #_talloc_type, (size_t)offsetof(_talloc_type, _field), _init) |
77 | | |
78 | | fr_lst_t *_fr_lst_alloc(TALLOC_CTX *ctx, fr_cmp_t cmp, char const *type, size_t offset, fr_lst_index_t init) CC_HINT(nonnull(2)); |
79 | | |
80 | | /** Check if an entry is inserted into an LST. |
81 | | * |
82 | | * @param[in] lst_id An fr_lst_index_t value *as stored in an item* |
83 | | * |
84 | | * Thus one should only pass this function an index as retrieved directly from |
85 | | * the item, *not* the value returned by item_index() (q.v.). |
86 | | * |
87 | | * This checks a necessary condition for a fr_lst_index_t value to be |
88 | | * that of an inserted entry. A more complete check would need the entry |
89 | | * itself and a pointer to the fr_lst_t it may be inserted in. |
90 | | * Provided here to let heap users move to LSTs. |
91 | | */ |
92 | | static inline bool fr_lst_entry_inserted(fr_lst_index_t lst_id) |
93 | 0 | { |
94 | 0 | return (lst_id > 0); |
95 | 0 | } Unexecuted instantiation: timer.c:fr_lst_entry_inserted Unexecuted instantiation: lst.c:fr_lst_entry_inserted |
96 | | |
97 | | void *fr_lst_peek(fr_lst_t *lst) CC_HINT(nonnull); |
98 | | |
99 | | void *fr_lst_pop(fr_lst_t *lst) CC_HINT(nonnull); |
100 | | |
101 | | int fr_lst_insert(fr_lst_t *lst, void *data) CC_HINT(nonnull); |
102 | | |
103 | | int fr_lst_extract(fr_lst_t *lst, void *data) CC_HINT(nonnull); |
104 | | |
105 | | unsigned int fr_lst_num_elements(fr_lst_t *lst) CC_HINT(nonnull); |
106 | | |
107 | | |
108 | | void *fr_lst_iter_init(fr_lst_t *lst, fr_lst_iter_t *iter) CC_HINT(nonnull); |
109 | | |
110 | | void *fr_lst_iter_next(fr_lst_t *lst, fr_lst_iter_t *iter) CC_HINT(nonnull); |
111 | | |
112 | | #ifndef TALLOC_GET_TYPE_ABORT_NOOP |
113 | | void fr_lst_verify(char const *file, int line, fr_lst_t const *lst); |
114 | | #define FR_LST_VERIFY(_lst) fr_lst_verify(__FILE__, __LINE__, _lst) |
115 | | #elif !defined(NDEBUG) |
116 | | #define FR_LST_VERIFY(_lst) fr_assert(_lst) |
117 | | #else |
118 | | #define FR_LST_VERIFY(_lst) |
119 | | #endif |
120 | | |
121 | | /** Iterate over the contents of an LST |
122 | | * |
123 | | * @note The initializer section of a for loop can't declare variables with distinct |
124 | | * base types, so we require a containing block, and can't follow the standard |
125 | | * do {...} while(0) dodge. The code to be run for each item in the LST should |
126 | | * thus start with one open brace and end with two close braces, and shouldn't |
127 | | * be followed with a semicolon. |
128 | | * This may fake out code formatting programs and code-aware editors. |
129 | | * |
130 | | * @param[in] _lst to iterate over. |
131 | | * @param[in] _type of item the heap contains. |
132 | | * @param[in] _data Name of variable holding a pointer to the LST element. |
133 | | * Will be declared in the scope of the loop. |
134 | | */ |
135 | | #define fr_lst_foreach(_lst, _type, _data) \ |
136 | | { \ |
137 | | fr_lst_iter_t _iter; \ |
138 | | for (_type *_data = fr_lst_iter_init(_lst, &_iter); _data; _data = fr_lst_iter_next(_lst, &_iter)) |
139 | | |
140 | | #ifdef __cplusplus |
141 | | } |
142 | | #endif |