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