summaryrefslogtreecommitdiff
path: root/lib/list.h
blob: c039a0bae5e6d365213b6bf344ce21add8a62fa3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/* Copyright (C) 2001, 2002, 2003 Red Hat, Inc.
   Written by Ulrich Drepper <drepper@redhat.com>, 2001.

   This program is Open Source software; you can redistribute it and/or
   modify it under the terms of the Open Software License version 1.0 as
   published by the Open Source Initiative.

   You should have received a copy of the Open Software License along
   with this program; if not, you may obtain a copy of the Open Software
   License version 1.0 from http://www.opensource.org/licenses/osl.php or
   by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
   3001 King Ranch Road, Ukiah, CA 95482.   */

#ifndef LIST_H
#define LIST_H	1

/* Add element to the end of a circular, double-linked list.  */
#define CDBL_LIST_ADD_REAR(first, newp) \
  do {									      \
    __typeof (newp) _newp = (newp);					      \
    assert (_newp->next == NULL);					      \
    assert (_newp->previous == NULL);					      \
    if (unlikely ((first) == NULL))					      \
      (first) = _newp->next = _newp->previous = _newp;			      \
    else								      \
      {									      \
	_newp->next = (first);						      \
	_newp->previous = (first)->previous;				      \
	_newp->previous->next = _newp->next->previous = _newp;		      \
      }									      \
  } while (0)

/* Remove element from circular, double-linked list.  */
#define CDBL_LIST_DEL(first, elem) \
  do {									      \
    __typeof (elem) _elem = (elem);					      \
    /* Check whether the element is indeed on the list.  */		      \
    assert (first != NULL && _elem != NULL				      \
	    && (first != elem						      \
		|| ({ __typeof (elem) _runp = first->next;		      \
		      while (_runp != first)				      \
			if (_runp == _elem)				      \
			  break;					      \
			else						      \
		          _runp = _runp->next;				      \
		      _runp == _elem; })));				      \
    if (unlikely (_elem->next == _elem))				      \
      first = NULL;							      \
    else								      \
      {									      \
	_elem->next->previous = _elem->previous;			      \
	_elem->previous->next = _elem->next;				      \
	if (unlikely (first == _elem))					      \
	  first = _elem->next;						      \
      }									      \
     assert ((_elem->next = _elem->previous = NULL, 1));		      \
  } while (0)


/* Add element to the front of a single-linked list.  */
#define SNGL_LIST_PUSH(first, newp) \
  do {									      \
    __typeof (newp) _newp = (newp);					      \
    assert (_newp->next == NULL);					      \
    _newp->next = first;						      \
    first = _newp;							      \
  } while (0)


/* Add element to the rear of a circular single-linked list.  */
#define CSNGL_LIST_ADD_REAR(first, newp) \
  do {									      \
    __typeof (newp) _newp = (newp);					      \
    assert (_newp->next == NULL);					      \
    if (unlikely ((first) == NULL))					      \
      (first) = _newp->next = _newp;					      \
    else								      \
      {									      \
	_newp->next = (first)->next;					      \
	(first) = (first)->next = _newp;				      \
      }									      \
  } while (0)


#endif	/* list.h */