xref: /dflybsd-src/contrib/lvm2/dist/lib/datastruct/list.c (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
1*86d7f5d3SJohn Marino /*	$NetBSD: list.c,v 1.1.1.1 2008/12/22 00:17:54 haad Exp $	*/
2*86d7f5d3SJohn Marino 
3*86d7f5d3SJohn Marino /*
4*86d7f5d3SJohn Marino  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
5*86d7f5d3SJohn Marino  * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
6*86d7f5d3SJohn Marino  *
7*86d7f5d3SJohn Marino  * This file is part of LVM2.
8*86d7f5d3SJohn Marino  *
9*86d7f5d3SJohn Marino  * This copyrighted material is made available to anyone wishing to use,
10*86d7f5d3SJohn Marino  * modify, copy, or redistribute it subject to the terms and conditions
11*86d7f5d3SJohn Marino  * of the GNU Lesser General Public License v.2.1.
12*86d7f5d3SJohn Marino  *
13*86d7f5d3SJohn Marino  * You should have received a copy of the GNU Lesser General Public License
14*86d7f5d3SJohn Marino  * along with this program; if not, write to the Free Software Foundation,
15*86d7f5d3SJohn Marino  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16*86d7f5d3SJohn Marino  */
17*86d7f5d3SJohn Marino 
18*86d7f5d3SJohn Marino #include "lib.h"
19*86d7f5d3SJohn Marino 
20*86d7f5d3SJohn Marino /*
21*86d7f5d3SJohn Marino  * Initialise a list before use.
22*86d7f5d3SJohn Marino  * The list head's next and previous pointers point back to itself.
23*86d7f5d3SJohn Marino  */
dm_list_init(struct dm_list * head)24*86d7f5d3SJohn Marino void dm_list_init(struct dm_list *head)
25*86d7f5d3SJohn Marino {
26*86d7f5d3SJohn Marino 	head->n = head->p = head;
27*86d7f5d3SJohn Marino }
28*86d7f5d3SJohn Marino 
29*86d7f5d3SJohn Marino /*
30*86d7f5d3SJohn Marino  * Insert an element before 'head'.
31*86d7f5d3SJohn Marino  * If 'head' is the list head, this adds an element to the end of the list.
32*86d7f5d3SJohn Marino  */
dm_list_add(struct dm_list * head,struct dm_list * elem)33*86d7f5d3SJohn Marino void dm_list_add(struct dm_list *head, struct dm_list *elem)
34*86d7f5d3SJohn Marino {
35*86d7f5d3SJohn Marino 	assert(head->n);
36*86d7f5d3SJohn Marino 
37*86d7f5d3SJohn Marino 	elem->n = head;
38*86d7f5d3SJohn Marino 	elem->p = head->p;
39*86d7f5d3SJohn Marino 
40*86d7f5d3SJohn Marino 	head->p->n = elem;
41*86d7f5d3SJohn Marino 	head->p = elem;
42*86d7f5d3SJohn Marino }
43*86d7f5d3SJohn Marino 
44*86d7f5d3SJohn Marino /*
45*86d7f5d3SJohn Marino  * Insert an element after 'head'.
46*86d7f5d3SJohn Marino  * If 'head' is the list head, this adds an element to the front of the list.
47*86d7f5d3SJohn Marino  */
dm_list_add_h(struct dm_list * head,struct dm_list * elem)48*86d7f5d3SJohn Marino void dm_list_add_h(struct dm_list *head, struct dm_list *elem)
49*86d7f5d3SJohn Marino {
50*86d7f5d3SJohn Marino 	assert(head->n);
51*86d7f5d3SJohn Marino 
52*86d7f5d3SJohn Marino 	elem->n = head->n;
53*86d7f5d3SJohn Marino 	elem->p = head;
54*86d7f5d3SJohn Marino 
55*86d7f5d3SJohn Marino 	head->n->p = elem;
56*86d7f5d3SJohn Marino 	head->n = elem;
57*86d7f5d3SJohn Marino }
58*86d7f5d3SJohn Marino 
59*86d7f5d3SJohn Marino /*
60*86d7f5d3SJohn Marino  * Delete an element from its list.
61*86d7f5d3SJohn Marino  * Note that this doesn't change the element itself - it may still be safe
62*86d7f5d3SJohn Marino  * to follow its pointers.
63*86d7f5d3SJohn Marino  */
dm_list_del(struct dm_list * elem)64*86d7f5d3SJohn Marino void dm_list_del(struct dm_list *elem)
65*86d7f5d3SJohn Marino {
66*86d7f5d3SJohn Marino 	elem->n->p = elem->p;
67*86d7f5d3SJohn Marino 	elem->p->n = elem->n;
68*86d7f5d3SJohn Marino }
69*86d7f5d3SJohn Marino 
70*86d7f5d3SJohn Marino /*
71*86d7f5d3SJohn Marino  * Remove an element from existing list and insert before 'head'.
72*86d7f5d3SJohn Marino  */
dm_list_move(struct dm_list * head,struct dm_list * elem)73*86d7f5d3SJohn Marino void dm_list_move(struct dm_list *head, struct dm_list *elem)
74*86d7f5d3SJohn Marino {
75*86d7f5d3SJohn Marino         dm_list_del(elem);
76*86d7f5d3SJohn Marino         dm_list_add(head, elem);
77*86d7f5d3SJohn Marino }
78*86d7f5d3SJohn Marino 
79*86d7f5d3SJohn Marino /*
80*86d7f5d3SJohn Marino  * Is the list empty?
81*86d7f5d3SJohn Marino  */
dm_list_empty(const struct dm_list * head)82*86d7f5d3SJohn Marino int dm_list_empty(const struct dm_list *head)
83*86d7f5d3SJohn Marino {
84*86d7f5d3SJohn Marino 	return head->n == head;
85*86d7f5d3SJohn Marino }
86*86d7f5d3SJohn Marino 
87*86d7f5d3SJohn Marino /*
88*86d7f5d3SJohn Marino  * Is this the first element of the list?
89*86d7f5d3SJohn Marino  */
dm_list_start(const struct dm_list * head,const struct dm_list * elem)90*86d7f5d3SJohn Marino int dm_list_start(const struct dm_list *head, const struct dm_list *elem)
91*86d7f5d3SJohn Marino {
92*86d7f5d3SJohn Marino 	return elem->p == head;
93*86d7f5d3SJohn Marino }
94*86d7f5d3SJohn Marino 
95*86d7f5d3SJohn Marino /*
96*86d7f5d3SJohn Marino  * Is this the last element of the list?
97*86d7f5d3SJohn Marino  */
dm_list_end(const struct dm_list * head,const struct dm_list * elem)98*86d7f5d3SJohn Marino int dm_list_end(const struct dm_list *head, const struct dm_list *elem)
99*86d7f5d3SJohn Marino {
100*86d7f5d3SJohn Marino 	return elem->n == head;
101*86d7f5d3SJohn Marino }
102*86d7f5d3SJohn Marino 
103*86d7f5d3SJohn Marino /*
104*86d7f5d3SJohn Marino  * Return first element of the list or NULL if empty
105*86d7f5d3SJohn Marino  */
dm_list_first(const struct dm_list * head)106*86d7f5d3SJohn Marino struct dm_list *dm_list_first(const struct dm_list *head)
107*86d7f5d3SJohn Marino {
108*86d7f5d3SJohn Marino 	return (dm_list_empty(head) ? NULL : head->n);
109*86d7f5d3SJohn Marino }
110*86d7f5d3SJohn Marino 
111*86d7f5d3SJohn Marino /*
112*86d7f5d3SJohn Marino  * Return last element of the list or NULL if empty
113*86d7f5d3SJohn Marino  */
dm_list_last(const struct dm_list * head)114*86d7f5d3SJohn Marino struct dm_list *dm_list_last(const struct dm_list *head)
115*86d7f5d3SJohn Marino {
116*86d7f5d3SJohn Marino 	return (dm_list_empty(head) ? NULL : head->p);
117*86d7f5d3SJohn Marino }
118*86d7f5d3SJohn Marino 
119*86d7f5d3SJohn Marino /*
120*86d7f5d3SJohn Marino  * Return the previous element of the list, or NULL if we've reached the start.
121*86d7f5d3SJohn Marino  */
dm_list_prev(const struct dm_list * head,const struct dm_list * elem)122*86d7f5d3SJohn Marino struct dm_list *dm_list_prev(const struct dm_list *head, const struct dm_list *elem)
123*86d7f5d3SJohn Marino {
124*86d7f5d3SJohn Marino 	return (dm_list_start(head, elem) ? NULL : elem->p);
125*86d7f5d3SJohn Marino }
126*86d7f5d3SJohn Marino 
127*86d7f5d3SJohn Marino /*
128*86d7f5d3SJohn Marino  * Return the next element of the list, or NULL if we've reached the end.
129*86d7f5d3SJohn Marino  */
dm_list_next(const struct dm_list * head,const struct dm_list * elem)130*86d7f5d3SJohn Marino struct dm_list *dm_list_next(const struct dm_list *head, const struct dm_list *elem)
131*86d7f5d3SJohn Marino {
132*86d7f5d3SJohn Marino 	return (dm_list_end(head, elem) ? NULL : elem->n);
133*86d7f5d3SJohn Marino }
134*86d7f5d3SJohn Marino 
135*86d7f5d3SJohn Marino /*
136*86d7f5d3SJohn Marino  * Return the number of elements in a list by walking it.
137*86d7f5d3SJohn Marino  */
dm_list_size(const struct dm_list * head)138*86d7f5d3SJohn Marino unsigned int dm_list_size(const struct dm_list *head)
139*86d7f5d3SJohn Marino {
140*86d7f5d3SJohn Marino 	unsigned int s = 0;
141*86d7f5d3SJohn Marino 	const struct dm_list *v;
142*86d7f5d3SJohn Marino 
143*86d7f5d3SJohn Marino 	dm_list_iterate(v, head)
144*86d7f5d3SJohn Marino 	    s++;
145*86d7f5d3SJohn Marino 
146*86d7f5d3SJohn Marino 	return s;
147*86d7f5d3SJohn Marino }
148