1ad43ddacSmrg/** 2ad43ddacSmrg * \file simple_list.h 3ad43ddacSmrg * Simple macros for type-safe, intrusive lists. 4ad43ddacSmrg * 5ad43ddacSmrg * Intended to work with a list sentinal which is created as an empty 6ad43ddacSmrg * list. Insert & delete are O(1). 7ad43ddacSmrg * 8ad43ddacSmrg * \author 9ad43ddacSmrg * (C) 1997, Keith Whitwell 10ad43ddacSmrg */ 11ad43ddacSmrg 12ad43ddacSmrg/* 13ad43ddacSmrg * Mesa 3-D graphics library 14ad43ddacSmrg * Version: 3.5 15ad43ddacSmrg * 16ad43ddacSmrg * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. 17ad43ddacSmrg * 18ad43ddacSmrg * Permission is hereby granted, free of charge, to any person obtaining a 19ad43ddacSmrg * copy of this software and associated documentation files (the "Software"), 20ad43ddacSmrg * to deal in the Software without restriction, including without limitation 21ad43ddacSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 22ad43ddacSmrg * and/or sell copies of the Software, and to permit persons to whom the 23ad43ddacSmrg * Software is furnished to do so, subject to the following conditions: 24ad43ddacSmrg * 25ad43ddacSmrg * The above copyright notice and this permission notice shall be included 26ad43ddacSmrg * in all copies or substantial portions of the Software. 27ad43ddacSmrg * 28ad43ddacSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 29ad43ddacSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30ad43ddacSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 31ad43ddacSmrg * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 32ad43ddacSmrg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 33ad43ddacSmrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 34ad43ddacSmrg */ 35ad43ddacSmrg 36ad43ddacSmrg 37ad43ddacSmrg#ifndef _SIMPLE_LIST_H 38ad43ddacSmrg#define _SIMPLE_LIST_H 39ad43ddacSmrg 40ad43ddacSmrgstruct simple_node { 41ad43ddacSmrg struct simple_node *next; 42ad43ddacSmrg struct simple_node *prev; 43ad43ddacSmrg}; 44ad43ddacSmrg 45ad43ddacSmrg/** 46ad43ddacSmrg * Remove an element from list. 47ad43ddacSmrg * 48ad43ddacSmrg * \param elem element to remove. 49ad43ddacSmrg */ 50ad43ddacSmrg#define remove_from_list(elem) \ 51ad43ddacSmrgdo { \ 52ad43ddacSmrg (elem)->next->prev = (elem)->prev; \ 53ad43ddacSmrg (elem)->prev->next = (elem)->next; \ 54ad43ddacSmrg} while (0) 55ad43ddacSmrg 56ad43ddacSmrg/** 57ad43ddacSmrg * Insert an element to the list head. 58ad43ddacSmrg * 59ad43ddacSmrg * \param list list. 60ad43ddacSmrg * \param elem element to insert. 61ad43ddacSmrg */ 62ad43ddacSmrg#define insert_at_head(list, elem) \ 63ad43ddacSmrgdo { \ 64ad43ddacSmrg (elem)->prev = list; \ 65ad43ddacSmrg (elem)->next = (list)->next; \ 66ad43ddacSmrg (list)->next->prev = elem; \ 67ad43ddacSmrg (list)->next = elem; \ 68ad43ddacSmrg} while(0) 69ad43ddacSmrg 70ad43ddacSmrg/** 71ad43ddacSmrg * Insert an element to the list tail. 72ad43ddacSmrg * 73ad43ddacSmrg * \param list list. 74ad43ddacSmrg * \param elem element to insert. 75ad43ddacSmrg */ 76ad43ddacSmrg#define insert_at_tail(list, elem) \ 77ad43ddacSmrgdo { \ 78ad43ddacSmrg (elem)->next = list; \ 79ad43ddacSmrg (elem)->prev = (list)->prev; \ 80ad43ddacSmrg (list)->prev->next = elem; \ 81ad43ddacSmrg (list)->prev = elem; \ 82ad43ddacSmrg} while(0) 83ad43ddacSmrg 84ad43ddacSmrg/** 85ad43ddacSmrg * Move an element to the list head. 86ad43ddacSmrg * 87ad43ddacSmrg * \param list list. 88ad43ddacSmrg * \param elem element to move. 89ad43ddacSmrg */ 90ad43ddacSmrg#define move_to_head(list, elem) \ 91ad43ddacSmrgdo { \ 92ad43ddacSmrg remove_from_list(elem); \ 93ad43ddacSmrg insert_at_head(list, elem); \ 94ad43ddacSmrg} while (0) 95ad43ddacSmrg 96ad43ddacSmrg/** 97ad43ddacSmrg * Move an element to the list tail. 98ad43ddacSmrg * 99ad43ddacSmrg * \param list list. 100ad43ddacSmrg * \param elem element to move. 101ad43ddacSmrg */ 102ad43ddacSmrg#define move_to_tail(list, elem) \ 103ad43ddacSmrgdo { \ 104ad43ddacSmrg remove_from_list(elem); \ 105ad43ddacSmrg insert_at_tail(list, elem); \ 106ad43ddacSmrg} while (0) 107ad43ddacSmrg 108ad43ddacSmrg/** 109ad43ddacSmrg * Make a empty list empty. 110ad43ddacSmrg * 111ad43ddacSmrg * \param sentinal list (sentinal element). 112ad43ddacSmrg */ 113ad43ddacSmrg#define make_empty_list(sentinal) \ 114ad43ddacSmrgdo { \ 115ad43ddacSmrg (sentinal)->next = sentinal; \ 116ad43ddacSmrg (sentinal)->prev = sentinal; \ 117ad43ddacSmrg} while (0) 118ad43ddacSmrg 119ad43ddacSmrg/** 120ad43ddacSmrg * Get list first element. 121ad43ddacSmrg * 122ad43ddacSmrg * \param list list. 123ad43ddacSmrg * 124ad43ddacSmrg * \return pointer to first element. 125ad43ddacSmrg */ 126ad43ddacSmrg#define first_elem(list) ((list)->next) 127ad43ddacSmrg 128ad43ddacSmrg/** 129ad43ddacSmrg * Get list last element. 130ad43ddacSmrg * 131ad43ddacSmrg * \param list list. 132ad43ddacSmrg * 133ad43ddacSmrg * \return pointer to last element. 134ad43ddacSmrg */ 135ad43ddacSmrg#define last_elem(list) ((list)->prev) 136ad43ddacSmrg 137ad43ddacSmrg/** 138ad43ddacSmrg * Get next element. 139ad43ddacSmrg * 140ad43ddacSmrg * \param elem element. 141ad43ddacSmrg * 142ad43ddacSmrg * \return pointer to next element. 143ad43ddacSmrg */ 144ad43ddacSmrg#define next_elem(elem) ((elem)->next) 145ad43ddacSmrg 146ad43ddacSmrg/** 147ad43ddacSmrg * Get previous element. 148ad43ddacSmrg * 149ad43ddacSmrg * \param elem element. 150ad43ddacSmrg * 151ad43ddacSmrg * \return pointer to previous element. 152ad43ddacSmrg */ 153ad43ddacSmrg#define prev_elem(elem) ((elem)->prev) 154ad43ddacSmrg 155ad43ddacSmrg/** 156ad43ddacSmrg * Test whether element is at end of the list. 157ad43ddacSmrg * 158ad43ddacSmrg * \param list list. 159ad43ddacSmrg * \param elem element. 160ad43ddacSmrg * 161ad43ddacSmrg * \return non-zero if element is at end of list, or zero otherwise. 162ad43ddacSmrg */ 163ad43ddacSmrg#define at_end(list, elem) ((elem) == (list)) 164ad43ddacSmrg 165ad43ddacSmrg/** 166ad43ddacSmrg * Test if a list is empty. 167ad43ddacSmrg * 168ad43ddacSmrg * \param list list. 169ad43ddacSmrg * 170ad43ddacSmrg * \return non-zero if list empty, or zero otherwise. 171ad43ddacSmrg */ 172ad43ddacSmrg#define is_empty_list(list) ((list)->next == (list)) 173ad43ddacSmrg 174ad43ddacSmrg/** 175ad43ddacSmrg * Walk through the elements of a list. 176ad43ddacSmrg * 177ad43ddacSmrg * \param ptr pointer to the current element. 178ad43ddacSmrg * \param list list. 179ad43ddacSmrg * 180ad43ddacSmrg * \note It should be followed by a { } block or a single statement, as in a \c 181ad43ddacSmrg * for loop. 182ad43ddacSmrg */ 183ad43ddacSmrg#define foreach(ptr, list) \ 184ad43ddacSmrg for( ptr=(list)->next ; ptr!=list ; ptr=(ptr)->next ) 185ad43ddacSmrg 186ad43ddacSmrg/** 187ad43ddacSmrg * Walk through the elements of a list. 188ad43ddacSmrg * 189ad43ddacSmrg * Same as #foreach but lets you unlink the current value during a list 190ad43ddacSmrg * traversal. Useful for freeing a list, element by element. 191ad43ddacSmrg * 192ad43ddacSmrg * \param ptr pointer to the current element. 193ad43ddacSmrg * \param t temporary pointer. 194ad43ddacSmrg * \param list list. 195ad43ddacSmrg * 196ad43ddacSmrg * \note It should be followed by a { } block or a single statement, as in a \c 197ad43ddacSmrg * for loop. 198ad43ddacSmrg */ 199ad43ddacSmrg#define foreach_s(ptr, t, list) \ 200ad43ddacSmrg for(ptr=(list)->next,t=(ptr)->next; list != ptr; ptr=t, t=(t)->next) 201ad43ddacSmrg 202ad43ddacSmrg#endif 203