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