1/* Copyright (C) 2001, 2002, 2003 Red Hat, Inc.
2   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
3
4   This program is Open Source software; you can redistribute it and/or
5   modify it under the terms of the Open Software License version 1.0 as
6   published by the Open Source Initiative.
7
8   You should have received a copy of the Open Software License along
9   with this program; if not, you may obtain a copy of the Open Software
10   License version 1.0 from http://www.opensource.org/licenses/osl.php or
11   by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
12   3001 King Ranch Road, Ukiah, CA 95482.   */
13
14#ifndef LIST_H
15#define LIST_H	1
16
17/* Add element to the end of a circular, double-linked list.  */
18#define CDBL_LIST_ADD_REAR(first, newp) \
19  do {									      \
20    __typeof (newp) _newp = (newp);					      \
21    assert (_newp->next == NULL);					      \
22    assert (_newp->previous == NULL);					      \
23    if (unlikely ((first) == NULL))					      \
24      (first) = _newp->next = _newp->previous = _newp;			      \
25    else								      \
26      {									      \
27	_newp->next = (first);						      \
28	_newp->previous = (first)->previous;				      \
29	_newp->previous->next = _newp->next->previous = _newp;		      \
30      }									      \
31  } while (0)
32
33/* Remove element from circular, double-linked list.  */
34#define CDBL_LIST_DEL(first, elem) \
35  do {									      \
36    __typeof (elem) _elem = (elem);					      \
37    /* Check whether the element is indeed on the list.  */		      \
38    assert (first != NULL && _elem != NULL				      \
39	    && (first != elem						      \
40		|| ({ __typeof (elem) _runp = first->next;		      \
41		      while (_runp != first)				      \
42			if (_runp == _elem)				      \
43			  break;					      \
44			else						      \
45		          _runp = _runp->next;				      \
46		      _runp == _elem; })));				      \
47    if (unlikely (_elem->next == _elem))				      \
48      first = NULL;							      \
49    else								      \
50      {									      \
51	_elem->next->previous = _elem->previous;			      \
52	_elem->previous->next = _elem->next;				      \
53	if (unlikely (first == _elem))					      \
54	  first = _elem->next;						      \
55      }									      \
56     assert ((_elem->next = _elem->previous = NULL, 1));		      \
57  } while (0)
58
59
60/* Add element to the front of a single-linked list.  */
61#define SNGL_LIST_PUSH(first, newp) \
62  do {									      \
63    __typeof (newp) _newp = (newp);					      \
64    assert (_newp->next == NULL);					      \
65    _newp->next = first;						      \
66    first = _newp;							      \
67  } while (0)
68
69
70/* Add element to the rear of a circular single-linked list.  */
71#define CSNGL_LIST_ADD_REAR(first, newp) \
72  do {									      \
73    __typeof (newp) _newp = (newp);					      \
74    assert (_newp->next == NULL);					      \
75    if (unlikely ((first) == NULL))					      \
76      (first) = _newp->next = _newp;					      \
77    else								      \
78      {									      \
79	_newp->next = (first)->next;					      \
80	(first) = (first)->next = _newp;				      \
81      }									      \
82  } while (0)
83
84
85#endif	/* list.h */
86