blob: 36e4196e1a74a34f514237a1867c314128c2719c [file] [log] [blame]
Benny Prijono9033e312005-11-21 02:08:39 +00001/* $Id$ */
2/*
Benny Prijono844653c2008-12-23 17:27:53 +00003 * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
4 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
Benny Prijono9033e312005-11-21 02:08:39 +00005 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#ifndef __PJ_LIST_H__
21#define __PJ_LIST_H__
22
23/**
24 * @file list.h
25 * @brief Linked List data structure.
26 */
27
28#include <pj/types.h>
29
30PJ_BEGIN_DECL
31
32/*
33 * @defgroup PJ_DS Data Structure.
Benny Prijono9033e312005-11-21 02:08:39 +000034 */
35
36/**
37 * @defgroup PJ_LIST Linked List
38 * @ingroup PJ_DS
39 * @{
40 *
41 * List in PJLIB is implemented as doubly-linked list, and it won't require
42 * dynamic memory allocation (just as all PJLIB data structures). The list here
43 * should be viewed more like a low level C list instead of high level C++ list
44 * (which normally are easier to use but require dynamic memory allocations),
45 * therefore all caveats with C list apply here too (such as you can NOT put
46 * a node in more than one lists).
47 *
48 * \section pj_list_example_sec Examples
49 *
50 * See below for examples on how to manipulate linked list:
51 * - @ref page_pjlib_samples_list_c
52 * - @ref page_pjlib_list_test
53 */
54
55
56/**
57 * Use this macro in the start of the structure declaration to declare that
58 * the structure can be used in the linked list operation. This macro simply
59 * declares additional member @a prev and @a next to the structure.
60 * @hideinitializer
61 */
62#define PJ_DECL_LIST_MEMBER(type) \
63 /** List @a prev. */ \
64 type *prev; \
65 /** List @a next. */ \
66 type *next
67
68
69/**
70 * This structure describes generic list node and list. The owner of this list
71 * must initialize the 'value' member to an appropriate value (typically the
72 * owner itself).
73 */
74struct pj_list
75{
76 PJ_DECL_LIST_MEMBER(void);
77};
78
79
80/**
81 * Initialize the list.
82 * Initially, the list will have no member, and function pj_list_empty() will
83 * always return nonzero (which indicates TRUE) for the newly initialized
84 * list.
85 *
86 * @param node The list head.
87 */
88PJ_INLINE(void) pj_list_init(pj_list_type * node)
89{
90 ((pj_list*)node)->next = ((pj_list*)node)->prev = node;
91}
92
93
94/**
95 * Check that the list is empty.
96 *
97 * @param node The list head.
98 *
Benny Prijono05eb3e32009-08-12 22:31:49 +000099 * @return Non-zero if the list is empty, or zero if it is not empty.
Benny Prijono9033e312005-11-21 02:08:39 +0000100 *
101 */
102PJ_INLINE(int) pj_list_empty(const pj_list_type * node)
103{
104 return ((pj_list*)node)->next == node;
105}
106
107
108/**
109 * Insert the node to the list before the specified element position.
110 *
111 * @param pos The element to which the node will be inserted before.
112 * @param node The element to be inserted.
113 *
114 * @return void.
115 */
116PJ_IDECL(void) pj_list_insert_before(pj_list_type *pos, pj_list_type *node);
117
118
119/**
Benny Prijonofa73e3e2006-01-05 23:35:46 +0000120 * Insert the node to the back of the list. This is just an alias for
121 * #pj_list_insert_before().
122 *
123 * @param list The list.
124 * @param node The element to be inserted.
125 */
126PJ_INLINE(void) pj_list_push_back(pj_list_type *list, pj_list_type *node)
127{
128 pj_list_insert_before(list, node);
129}
130
131
132/**
Benny Prijono9033e312005-11-21 02:08:39 +0000133 * Inserts all nodes in \a nodes to the target list.
134 *
135 * @param lst The target list.
136 * @param nodes Nodes list.
137 */
138PJ_IDECL(void) pj_list_insert_nodes_before(pj_list_type *lst,
139 pj_list_type *nodes);
140
141/**
142 * Insert a node to the list after the specified element position.
143 *
144 * @param pos The element in the list which will precede the inserted
145 * element.
146 * @param node The element to be inserted after the position element.
147 *
148 * @return void.
149 */
150PJ_IDECL(void) pj_list_insert_after(pj_list_type *pos, pj_list_type *node);
151
Benny Prijonofa73e3e2006-01-05 23:35:46 +0000152
153/**
154 * Insert the node to the front of the list. This is just an alias for
155 * #pj_list_insert_after().
156 *
157 * @param list The list.
158 * @param node The element to be inserted.
159 */
160PJ_INLINE(void) pj_list_push_front(pj_list_type *list, pj_list_type *node)
161{
162 pj_list_insert_after(list, node);
163}
164
165
Benny Prijono9033e312005-11-21 02:08:39 +0000166/**
167 * Insert all nodes in \a nodes to the target list.
168 *
169 * @param lst The target list.
170 * @param nodes Nodes list.
171 */
172PJ_IDECL(void) pj_list_insert_nodes_after(pj_list_type *lst,
173 pj_list_type *nodes);
174
175
176/**
177 * Remove elements from the source list, and insert them to the destination
178 * list. The elements of the source list will occupy the
179 * front elements of the target list. Note that the node pointed by \a list2
180 * itself is not considered as a node, but rather as the list descriptor, so
181 * it will not be inserted to the \a list1. The elements to be inserted starts
182 * at \a list2->next. If \a list2 is to be included in the operation, use
183 * \a pj_list_insert_nodes_before.
184 *
185 * @param list1 The destination list.
186 * @param list2 The source list.
187 *
188 * @return void.
189 */
190PJ_IDECL(void) pj_list_merge_first(pj_list_type *list1, pj_list_type *list2);
191
192
193/**
194 * Remove elements from the second list argument, and insert them to the list
195 * in the first argument. The elements from the second list will be appended
196 * to the first list. Note that the node pointed by \a list2
197 * itself is not considered as a node, but rather as the list descriptor, so
198 * it will not be inserted to the \a list1. The elements to be inserted starts
199 * at \a list2->next. If \a list2 is to be included in the operation, use
200 * \a pj_list_insert_nodes_before.
201 *
202 * @param list1 The element in the list which will precede the inserted
203 * element.
204 * @param list2 The element in the list to be inserted.
205 *
206 * @return void.
207 */
208PJ_IDECL(void) pj_list_merge_last( pj_list_type *list1, pj_list_type *list2);
209
210
211/**
212 * Erase the node from the list it currently belongs.
213 *
214 * @param node The element to be erased.
215 */
216PJ_IDECL(void) pj_list_erase(pj_list_type *node);
217
218
219/**
220 * Find node in the list.
221 *
222 * @param list The list head.
223 * @param node The node element to be searched.
224 *
225 * @return The node itself if it is found in the list, or NULL if it is not
226 * found in the list.
227 */
228PJ_IDECL(pj_list_type*) pj_list_find_node(pj_list_type *list,
229 pj_list_type *node);
230
231
232/**
233 * Search the list for the specified value, using the specified comparison
234 * function. This function iterates on nodes in the list, started with the
235 * first node, and call the user supplied comparison function until the
236 * comparison function returns ZERO.
237 *
238 * @param list The list head.
239 * @param value The user defined value to be passed in the comparison
240 * function
241 * @param comp The comparison function, which should return ZERO to
242 * indicate that the searched value is found.
243 *
244 * @return The first node that matched, or NULL if it is not found.
245 */
246PJ_IDECL(pj_list_type*) pj_list_search(pj_list_type *list, void *value,
247 int (*comp)(void *value,
248 const pj_list_type *node)
249 );
250
251
252/**
Benny Prijonoa5f4ff22006-02-19 01:28:21 +0000253 * Traverse the list to get the number of elements in the list.
254 *
255 * @param list The list head.
256 *
257 * @return Number of elements.
258 */
Benny Prijonob58b3e42008-05-16 13:27:46 +0000259PJ_IDECL(pj_size_t) pj_list_size(const pj_list_type *list);
Benny Prijonoa5f4ff22006-02-19 01:28:21 +0000260
261
262/**
Benny Prijono9033e312005-11-21 02:08:39 +0000263 * @}
264 */
265
266#if PJ_FUNCTIONS_ARE_INLINED
267# include "list_i.h"
268#endif
269
270PJ_END_DECL
271
272#endif /* __PJ_LIST_H__ */
273