5151/// If Cavl is used in throughput-critical code, then it is recommended to disable assertion checks as they may
5252/// be costly in terms of execution time.
5353#ifndef CAVL2_ASSERT
54- #if defined(CAVL2_NO_ASSERT ) && CAVL2_NO_ASSERT
55- #define CAVL2_ASSERT (x ) (void)0
56- #else
57- #include <assert.h>
58- #define CAVL2_ASSERT (x ) assert(x)
59- #endif
54+ # if defined(CAVL2_NO_ASSERT ) && CAVL2_NO_ASSERT
55+ # define CAVL2_ASSERT (x ) (void) 0
56+ # else
57+ # include <assert.h>
58+ # define CAVL2_ASSERT (x ) assert(x)
59+ # endif
6060#endif
6161
6262#ifdef __cplusplus
6363// This is, strictly speaking, useless because we do not define any functions with external linkage here,
6464// but it tells static analyzers that what follows should be interpreted as C code rather than C++.
65- extern "C"
66- {
65+ extern "C" {
6766#endif
6867
6968// ---------------------------------------- PUBLIC API SECTION ----------------------------------------
@@ -82,11 +81,11 @@ extern "C"
8281/// };
8382struct cavl2_t
8483{
85- struct cavl2_t * up ; ///< Parent node, NULL in the root.
86- struct cavl2_t * lr [2 ]; ///< Left child (lesser), right child (greater).
87- int_fast8_t bf ; ///< Balance factor is positive when right-heavy. Allowed values are {-1, 0, +1}.
84+ struct cavl2_t * up ; ///< Parent node, NULL in the root.
85+ struct cavl2_t * lr [2 ]; ///< Left child (lesser), right child (greater).
86+ int_fast8_t bf ; ///< Balance factor is positive when right-heavy. Allowed values are {-1, 0, +1}.
8887};
89- #define CAVL2_T struct cavl2_t
88+ # define CAVL2_T struct cavl2_t
9089#endif
9190
9291#if defined(static_assert ) || defined(__cplusplus )
@@ -97,7 +96,7 @@ static_assert(sizeof(CAVL2_T) <= sizeof(void* [4]), "Bad size");
9796/// The type shall be a signed integer type.
9897/// Only three possible states of the result are considered: negative, zero, and positive; the magnitude is ignored.
9998#ifndef CAVL2_RELATION
100- #define CAVL2_RELATION ptrdiff_t
99+ # define CAVL2_RELATION ptrdiff_t
101100#endif
102101/// Returns POSITIVE if the search target is GREATER than the provided node, negative if smaller, zero on match (found).
103102typedef CAVL2_RELATION (* cavl2_comparator_t )(const void * user , const CAVL2_T * node );
@@ -144,7 +143,8 @@ static inline CAVL2_T* cavl2_extremum(CAVL2_T* const root, const bool maximum)
144143{
145144 CAVL2_T * result = NULL ;
146145 CAVL2_T * c = root ;
147- while (c != NULL ) {
146+ while (c != NULL )
147+ {
148148 result = c ;
149149 c = c -> lr [maximum ];
150150 }
@@ -167,13 +167,18 @@ static inline CAVL2_T* cavl2_max(CAVL2_T* const root) { return cavl2_extremum(ro
167167static inline CAVL2_T * cavl2_next_greater (CAVL2_T * const node )
168168{
169169 CAVL2_T * c = NULL ;
170- if (node != NULL ) {
171- if (node -> lr [1 ] != NULL ) {
170+ if (node != NULL )
171+ {
172+ if (node -> lr [1 ] != NULL )
173+ {
172174 c = cavl2_min (node -> lr [1 ]);
173- } else {
175+ }
176+ else
177+ {
174178 const CAVL2_T * n = node ;
175179 CAVL2_T * p = node -> up ;
176- while ((p != NULL ) && (p -> lr [1 ] == n )) {
180+ while ((p != NULL ) && (p -> lr [1 ] == n ))
181+ {
177182 n = p ;
178183 p = p -> up ;
179184 }
@@ -187,7 +192,7 @@ static inline CAVL2_T* cavl2_next_greater(CAVL2_T* const node)
187192/// It is meant for use with cavl2_find_or_insert().
188193static inline CAVL2_T * cavl2_trivial_factory (void * const user )
189194{
190- return (CAVL2_T * )user ;
195+ return (CAVL2_T * ) user ;
191196}
192197
193198/// A convenience macro for use when a struct is a member of multiple AVL trees. For example:
@@ -209,8 +214,8 @@ static inline CAVL2_T* cavl2_trivial_factory(void* const user)
209214/// struct my_type_t* my_struct = CAVL2_TO_OWNER(tree_node_b, struct my_type_t, tree_b);
210215///
211216/// The result is undefined if the tree_node_ptr is not a valid pointer to the tree node. Check for NULL first.
212- #define CAVL2_TO_OWNER (tree_node_ptr , owner_type , owner_tree_node_field ) \
213- ((owner_type*)(void*)(((char*)(tree_node_ptr)) - offsetof(owner_type, owner_tree_node_field))) // NOLINT
217+ #define CAVL2_TO_OWNER (tree_node_ptr , owner_type , owner_tree_node_field ) \
218+ ((owner_type*) (void*) (((char*) (tree_node_ptr)) - offsetof(owner_type, owner_tree_node_field))) // NOLINT
214219
215220// ---------------------------------------- END OF PUBLIC API SECTION ----------------------------------------
216221// ---------------------------------------- POLICE LINE DO NOT CROSS ----------------------------------------
@@ -220,13 +225,15 @@ static inline void _cavl2_rotate(CAVL2_T* const x, const bool r)
220225{
221226 CAVL2_ASSERT ((x != NULL ) && (x -> lr [!r ] != NULL ) && ((x -> bf >= -1 ) && (x -> bf <= +1 )));
222227 CAVL2_T * const z = x -> lr [!r ];
223- if (x -> up != NULL ) {
228+ if (x -> up != NULL )
229+ {
224230 x -> up -> lr [x -> up -> lr [1 ] == x ] = z ;
225231 }
226232 z -> up = x -> up ;
227233 x -> up = z ;
228234 x -> lr [!r ] = z -> lr [r ];
229- if (x -> lr [!r ] != NULL ) {
235+ if (x -> lr [!r ] != NULL )
236+ {
230237 x -> lr [!r ]-> up = x ;
231238 }
232239 z -> lr [r ] = x ;
@@ -239,43 +246,57 @@ static inline CAVL2_T* _cavl2_adjust_balance(CAVL2_T* const x, const bool increm
239246{
240247 CAVL2_ASSERT ((x != NULL ) && ((x -> bf >= -1 ) && (x -> bf <= +1 )));
241248 CAVL2_T * out = x ;
242- const int_fast8_t new_bf = (int_fast8_t )(x -> bf + (increment ? +1 : -1 ));
243- if ((new_bf < -1 ) || (new_bf > 1 )) {
244- const bool r = new_bf < 0 ; // bf<0 if left-heavy --> right rotation is needed.
245- const int_fast8_t sign = r ? +1 : -1 ; // Positive if we are rotating right.
249+ const int_fast8_t new_bf = (int_fast8_t ) (x -> bf + (increment ? +1 : -1 ));
250+ if ((new_bf < -1 ) || (new_bf > 1 ))
251+ {
252+ const bool r = new_bf < 0 ; // bf<0 if left-heavy --> right rotation is needed.
253+ const int_fast8_t sign = r ? +1 : -1 ; // Positive if we are rotating right.
246254 CAVL2_T * const z = x -> lr [!r ];
247- CAVL2_ASSERT (z != NULL ); // Heavy side cannot be empty. NOLINTNEXTLINE(clang-analyzer-core.NullDereference)
248- if ((z -> bf * sign ) <= 0 ) { // Parent and child are heavy on the same side or the child is balanced.
255+ CAVL2_ASSERT (z != NULL ); // Heavy side cannot be empty. NOLINTNEXTLINE(clang-analyzer-core.NullDereference)
256+ if ((z -> bf * sign ) <= 0 )
257+ { // Parent and child are heavy on the same side or the child is balanced.
249258 out = z ;
250259 _cavl2_rotate (x , r );
251- if (0 == z -> bf ) {
252- x -> bf = (int_fast8_t )(- sign );
253- z -> bf = (int_fast8_t )(+ sign );
254- } else {
260+ if (0 == z -> bf )
261+ {
262+ x -> bf = (int_fast8_t ) (- sign );
263+ z -> bf = (int_fast8_t ) (+ sign );
264+ }
265+ else
266+ {
255267 x -> bf = 0 ;
256268 z -> bf = 0 ;
257269 }
258- } else { // Otherwise, the child needs to be rotated in the opposite direction first.
270+ }
271+ else
272+ { // Otherwise, the child needs to be rotated in the opposite direction first.
259273 CAVL2_T * const y = z -> lr [r ];
260- CAVL2_ASSERT (y != NULL ); // Heavy side cannot be empty.
274+ CAVL2_ASSERT (y != NULL ); // Heavy side cannot be empty.
261275 out = y ;
262276 _cavl2_rotate (z , !r );
263277 _cavl2_rotate (x , r );
264- if ((y -> bf * sign ) < 0 ) {
265- x -> bf = (int_fast8_t )(+ sign );
278+ if ((y -> bf * sign ) < 0 )
279+ {
280+ x -> bf = (int_fast8_t ) (+ sign );
266281 y -> bf = 0 ;
267282 z -> bf = 0 ;
268- } else if ((y -> bf * sign ) > 0 ) {
283+ }
284+ else if ((y -> bf * sign ) > 0 )
285+ {
269286 x -> bf = 0 ;
270287 y -> bf = 0 ;
271- z -> bf = (int_fast8_t )(- sign );
272- } else {
288+ z -> bf = (int_fast8_t ) (- sign );
289+ }
290+ else
291+ {
273292 x -> bf = 0 ;
274293 z -> bf = 0 ;
275294 }
276295 }
277- } else {
278- x -> bf = new_bf ; // Balancing not needed, just update the balance factor and call it a day.
296+ }
297+ else
298+ {
299+ x -> bf = new_bf ; // Balancing not needed, just update the balance factor and call it a day.
279300 }
280301 return out ;
281302}
@@ -286,20 +307,21 @@ static inline CAVL2_T* _cavl2_adjust_balance(CAVL2_T* const x, const bool increm
286307static inline CAVL2_T * _cavl2_retrace_on_growth (CAVL2_T * const added )
287308{
288309 CAVL2_ASSERT ((added != NULL ) && (0 == added -> bf ));
289- CAVL2_T * c = added ; // Child
290- CAVL2_T * p = added -> up ; // Parent
291- while (p != NULL ) {
292- const bool r = p -> lr [1 ] == c ; // c is the right child of parent
310+ CAVL2_T * c = added ; // Child
311+ CAVL2_T * p = added -> up ; // Parent
312+ while (p != NULL )
313+ {
314+ const bool r = p -> lr [1 ] == c ; // c is the right child of parent
293315 CAVL2_ASSERT (p -> lr [r ] == c );
294316 c = _cavl2_adjust_balance (p , r );
295317 p = c -> up ;
296- if (0 ==
297- c -> bf ) { // The height change of the subtree made this parent perfectly balanced (as all things should be),
298- break ; // hence, the height of the outer subtree is unchanged, so upper balance factors are unchanged.
318+ if (0 == c -> bf )
319+ { // The height change of the subtree made this parent perfectly balanced (as all things should be),
320+ break ; // hence, the height of the outer subtree is unchanged, so upper balance factors are unchanged.
299321 }
300322 }
301323 CAVL2_ASSERT (c != NULL );
302- return (NULL == p ) ? c : NULL ; // New root or nothing.
324+ return (NULL == p ) ? c : NULL ; // New root or nothing.
303325}
304326
305327static inline CAVL2_T * cavl2_find_or_insert (CAVL2_T * * const root ,
@@ -309,29 +331,35 @@ static inline CAVL2_T* cavl2_find_or_insert(CAVL2_T** const root,
309331 const cavl2_factory_t factory )
310332{
311333 CAVL2_T * out = NULL ;
312- if ((root != NULL ) && (comparator != NULL )) {
334+ if ((root != NULL ) && (comparator != NULL ))
335+ {
313336 CAVL2_T * up = * root ;
314337 CAVL2_T * * n = root ;
315- while (* n != NULL ) {
338+ while (* n != NULL )
339+ {
316340 const CAVL2_RELATION cmp = comparator (user_comparator , * n );
317- if (0 == cmp ) {
341+ if (0 == cmp )
342+ {
318343 out = * n ;
319344 break ;
320345 }
321346 up = * n ;
322347 n = & (* n )-> lr [cmp > 0 ];
323348 CAVL2_ASSERT ((NULL == * n ) || ((* n )-> up == up ));
324349 }
325- if (NULL == out ) {
350+ if (NULL == out )
351+ {
326352 out = (NULL == factory ) ? NULL : factory (user_factory );
327- if (out != NULL ) {
328- * n = out ; // Overwrite the pointer to the new node in the parent node.
353+ if (out != NULL )
354+ {
355+ * n = out ; // Overwrite the pointer to the new node in the parent node.
329356 out -> lr [0 ] = NULL ;
330357 out -> lr [1 ] = NULL ;
331358 out -> up = up ;
332359 out -> bf = 0 ;
333360 CAVL2_T * const rt = _cavl2_retrace_on_growth (out );
334- if (rt != NULL ) {
361+ if (rt != NULL )
362+ {
335363 * root = rt ;
336364 }
337365 }
@@ -342,71 +370,90 @@ static inline CAVL2_T* cavl2_find_or_insert(CAVL2_T** const root,
342370
343371static inline void cavl2_remove (CAVL2_T * * const root , const CAVL2_T * const node )
344372{
345- if ((root != NULL ) && (node != NULL )) {
346- CAVL2_ASSERT (* root != NULL ); // Otherwise, the node would have to be NULL.
373+ if ((root != NULL ) && (node != NULL ))
374+ {
375+ CAVL2_ASSERT (* root != NULL ); // Otherwise, the node would have to be NULL.
347376 CAVL2_ASSERT ((node -> up != NULL ) || (node == * root ));
348- CAVL2_T * p = NULL ; // The lowest parent node that suffered a shortening of its subtree.
349- bool r = false; // Which side of the above was shortened.
377+ CAVL2_T * p = NULL ; // The lowest parent node that suffered a shortening of its subtree.
378+ bool r = false; // Which side of the above was shortened.
350379 // The first step is to update the topology and remember the node where to start the retracing from later.
351380 // Balancing is not performed yet so we may end up with an unbalanced tree.
352- if ((node -> lr [0 ] != NULL ) && (node -> lr [1 ] != NULL )) {
381+ if ((node -> lr [0 ] != NULL ) && (node -> lr [1 ] != NULL ))
382+ {
353383 CAVL2_T * const re = cavl2_extremum (node -> lr [1 ], false);
354384 CAVL2_ASSERT ((re != NULL ) && (NULL == re -> lr [0 ]) && (re -> up != NULL ));
355385 re -> bf = node -> bf ;
356386 re -> lr [0 ] = node -> lr [0 ];
357387 re -> lr [0 ]-> up = re ;
358- if (re -> up != node ) {
359- p = re -> up ; // Retracing starts with the ex-parent of our replacement node.
388+ if (re -> up != node )
389+ {
390+ p = re -> up ; // Retracing starts with the ex-parent of our replacement node.
360391 CAVL2_ASSERT (p -> lr [0 ] == re );
361- p -> lr [0 ] = re -> lr [1 ]; // Reducing the height of the left subtree here.
362- if (p -> lr [0 ] != NULL ) {
392+ p -> lr [0 ] = re -> lr [1 ]; // Reducing the height of the left subtree here.
393+ if (p -> lr [0 ] != NULL )
394+ {
363395 p -> lr [0 ]-> up = p ;
364396 }
365397 re -> lr [1 ] = node -> lr [1 ];
366398 re -> lr [1 ]-> up = re ;
367399 r = false;
368- } else // In this case, we are reducing the height of the right subtree, so r=1.
400+ }
401+ else // In this case, we are reducing the height of the right subtree, so r=1.
369402 {
370- p = re ; // Retracing starts with the replacement node itself as we are deleting its parent.
371- r = true; // The right child of the replacement node remains the same so we don't bother relinking it.
403+ p = re ; // Retracing starts with the replacement node itself as we are deleting its parent.
404+ r = true; // The right child of the replacement node remains the same so we don't bother relinking it.
372405 }
373406 re -> up = node -> up ;
374- if (re -> up != NULL ) {
375- re -> up -> lr [re -> up -> lr [1 ] == node ] = re ; // Replace link in the parent of node.
376- } else {
407+ if (re -> up != NULL )
408+ {
409+ re -> up -> lr [re -> up -> lr [1 ] == node ] = re ; // Replace link in the parent of node.
410+ }
411+ else
412+ {
377413 * root = re ;
378414 }
379- } else { // Either or both of the children are NULL.
415+ }
416+ else
417+ { // Either or both of the children are NULL.
380418 p = node -> up ;
381419 const bool rr = node -> lr [1 ] != NULL ;
382- if (node -> lr [rr ] != NULL ) {
420+ if (node -> lr [rr ] != NULL )
421+ {
383422 node -> lr [rr ]-> up = p ;
384423 }
385- if (p != NULL ) {
424+ if (p != NULL )
425+ {
386426 r = p -> lr [1 ] == node ;
387427 p -> lr [r ] = node -> lr [rr ];
388- if (p -> lr [r ] != NULL ) {
428+ if (p -> lr [r ] != NULL )
429+ {
389430 p -> lr [r ]-> up = p ;
390431 }
391- } else {
432+ }
433+ else
434+ {
392435 * root = node -> lr [rr ];
393436 }
394437 }
395438 // Now that the topology is updated, perform the retracing to restore balance. We climb up adjusting the
396439 // balance factors until we reach the root or a parent whose balance factor becomes plus/minus one, which
397440 // means that that parent was able to absorb the balance delta; in other words, the height of the outer
398441 // subtree is unchanged, so upper balance factors shall be kept unchanged.
399- if (p != NULL ) {
442+ if (p != NULL )
443+ {
400444 CAVL2_T * c = NULL ;
401- for (;;) {
445+ for (;;)
446+ {
402447 c = _cavl2_adjust_balance (p , !r );
403448 p = c -> up ;
404- if ((c -> bf != 0 ) || (NULL == p )) { // Reached the root or the height difference is absorbed by c.
449+ if ((c -> bf != 0 ) || (NULL == p ))
450+ { // Reached the root or the height difference is absorbed by c.
405451 break ;
406452 }
407453 r = p -> lr [1 ] == c ;
408454 }
409- if (NULL == p ) {
455+ if (NULL == p )
456+ {
410457 CAVL2_ASSERT (c != NULL );
411458 * root = c ;
412459 }
0 commit comments