rsys

Basic data structures and low-level features
git clone git://git.meso-star.fr/rsys.git
Log | Files | Refs | README | LICENSE

list.h (4065B)


      1 /* Copyright (C) 2013-2023, 2025 Vincent Forest (vaplv@free.fr)
      2  *
      3  * The RSys library is free software: you can redistribute it and/or modify
      4  * it under the terms of the GNU General Public License as published
      5  * by the Free Software Foundation, either version 3 of the License, or
      6  * (at your option) any later version.
      7  *
      8  * The RSys library 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 the RSys library. If not, see <http://www.gnu.org/licenses/>. */
     15 
     16 #ifndef LIST_H
     17 #define LIST_H
     18 
     19 #include "rsys.h"
     20 
     21 struct list_node {
     22   struct list_node* next;
     23   struct list_node* prev;
     24 };
     25 
     26 /******************************************************************************
     27  * Private functions
     28  ******************************************************************************/
     29 static FINLINE void
     30 add_node__
     31   (struct list_node* node,
     32    struct list_node* prev,
     33    struct list_node* next)
     34 {
     35   ASSERT(node && prev && next);
     36   next->prev = node;
     37   node->next = next;
     38   node->prev = prev;
     39   prev->next = node;
     40 }
     41 
     42 static FINLINE void
     43 del_node__(struct list_node* prev, struct list_node* next)
     44 {
     45   ASSERT(prev && next);
     46   next->prev = prev;
     47   prev->next = next;
     48 }
     49 
     50 /******************************************************************************
     51  * Helper macros
     52  ******************************************************************************/
     53 #define LIST_FOR_EACH(Pos, List)                                               \
     54   for(Pos = (List)->next; Pos != (List); Pos = Pos->next)
     55 
     56 #define LIST_FOR_EACH_REVERSE(Pos, List)                                       \
     57   for(Pos = (List)->prev; Pos != (List); Pos = Pos->prev)
     58 
     59 /* Safe against removal of list entry. */
     60 #define LIST_FOR_EACH_SAFE(Pos, Tmp, List)                                     \
     61   for((Pos) = (List)->next, (Tmp) = (Pos)->next;                               \
     62       (Pos) != (List);                                                         \
     63       (Pos) = Tmp, Tmp = (Pos)->next)
     64 
     65 /* Safe against removal of list entry. */
     66 #define LIST_FOR_EACH_REVERSE_SAFE(Pos, Tmp, List)                             \
     67   for((Pos) = (List)->prev, (Tmp) = (Pos)->prev;                               \
     68       (Pos) != (List);                                                         \
     69       (Pos) = Tmp, Tmp = (Pos)->prev)
     70 
     71 /******************************************************************************
     72  * Node list functions
     73  ******************************************************************************/
     74 static FINLINE void
     75 list_init(struct list_node* node)
     76 {
     77   ASSERT(node);
     78   node->next = node;
     79   node->prev = node;
     80 }
     81 
     82 static FINLINE char
     83 is_list_empty(const struct list_node* node)
     84 {
     85   ASSERT(node);
     86   return node->next == node;
     87 }
     88 
     89 static FINLINE struct list_node*
     90 list_head(struct list_node* node)
     91 {
     92   ASSERT(node && !is_list_empty(node));
     93   return node->next;
     94 }
     95 
     96 static FINLINE struct list_node*
     97 list_tail(struct list_node* node)
     98 {
     99   ASSERT(node && !is_list_empty(node));
    100   return node->prev;
    101 }
    102 
    103 static FINLINE void
    104 list_add(struct list_node* list, struct list_node* node)
    105 {
    106   ASSERT(list && node && is_list_empty(node));
    107   add_node__(node, list, list->next);
    108 }
    109 
    110 static FINLINE void
    111 list_add_tail(struct list_node* list, struct list_node* node)
    112 {
    113   ASSERT(list && node && is_list_empty(node));
    114   add_node__(node, list->prev, list);
    115 }
    116 
    117 static FINLINE void
    118 list_del(struct list_node* node)
    119 {
    120   ASSERT(node);
    121   del_node__(node->prev, node->next);
    122   list_init(node);
    123 }
    124 
    125 static FINLINE void
    126 list_move(struct list_node* node, struct list_node* list)
    127 {
    128   ASSERT(node && list);
    129   del_node__(node->prev, node->next);
    130   add_node__(node, list, list->next);
    131 }
    132 
    133 static FINLINE void
    134 list_move_tail(struct list_node* node, struct list_node* list)
    135 {
    136   ASSERT(node && list);
    137   del_node__(node->prev, node->next);
    138   add_node__(node, list->prev, list);
    139 }
    140 
    141 #endif /* LIST_H */