RTI Connext DDS Micro  Version 2.4.11
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
reda_circularlist.h
1 /*
2  * FILE: reda_circularlist.c - Circular list interface
3  *
4  * Copyright 2012-2015 Real-Time Innovations, Inc.
5  *
6  * No duplications, whole or partial, manual or electronic, may be made
7  * without express written permission. Any such copies, or
8  * revisions thereof, must display this notice unaltered.
9  * This code contains trade secrets of Real-Time Innovations, Inc.
10  *
11  * Modification History
12  * --------------------
13  * 05may2015,tk MICRO-1100/PR#14153 Added comments to is_linked() and
14  * unlink_node() for undefined behavior on an
15  * unlinked node
16  * 01dec2014,tk MICRO-963/PR#12377 Fixed comment
17  * 04jan2012,tk Written
18  */
19 /*ci
20  * \file
21  *
22  * \brief The REDA CircularList interface provides a platform independent API to
23  * manage a circular lists
24  *
25  * \defgroup REDACircularListClass REDA CircularList
26  *
27  * \ingroup REDAModule
28  *
29  * \details
30  *
31  * The REDA CircularList implements a circular list as a double linked list
32  * where the head is an empty list-node.
33  *
34  */
35 /*ci \addtogroup REDACircularListClass
36  * @{
37  */
38 #ifndef reda_circularlist_h
39 #define reda_circularlist_h
40 
41 #ifndef reda_dll_h
42 #include "reda/reda_dll.h"
43 #endif
44 
45 #ifdef __cplusplus
46 extern "C"
47 {
48 #endif
49 
50 /*ci
51  * \brief REDA_CircularListNode element
52  *
53  * \details
54  *
55  * Any node can be added to a circular list, and all APIs is assumed all nodes
56  * includes this node as the first element:
57  *
58  * \code
59  *
60  * struct MyNode
61  * {
62  * struct REDA_CircularListNode _node;
63  * ...
64  * };
65  * \endcode
66  *
67  * Note that REDA_CircularListNode does not contain a pointer to the node
68  * data (MyNode) above.
69  */
70 struct REDA_CircularListNode
71 {
72  struct REDA_CircularListNode *_prev;
73  struct REDA_CircularListNode *_next;
74 };
75 
76 /*ci
77  * \brief Abstract REDA_CircularList type
78  */
79 typedef struct REDA_CircularListNode REDA_CircularList_T;
80 
81 /*ci
82  * \brief Abstract REDA_CircularListNode type
83  */
84 typedef struct REDA_CircularListNode REDA_CircularListNode_T;
85 
86 /*ci
87  * \brief Initialize a circular list
88  *
89  * \details
90  *
91  * Initialize a circular list to an empty state. A variable of type
92  * REDA_CircularList_T should be initialized exactly once.
93  *
94  * \param[in] list circular list to initialize
95  */
96 REDADllExport void
97 REDA_CircularList_init(REDA_CircularList_T *list);
98 
99 /*ci
100  * \brief Initialize a circular list node
101  *
102  * \details
103  *
104  * Initialize a circular list node. An initialized node is not linked to
105  * any list. It is the callers responsiblilty to ensure that
106  * REDA_CircularListNode_init is <em> not </em> called on linked node.
107  *
108  * \param[in] node circular list node to initialize
109  *
110  */
111 REDADllExport void
112 REDA_CircularListNode_init(struct REDA_CircularListNode *node);
113 
114 /*ci
115  * \brief Link a circular list node after a node already in the list
116  *
117  * \details
118  *
119  * Link a circular list node after another node. Note that circular list
120  * head is a circular list node itself.
121  *
122  * \param[in] after circular list node to link after
123  * \param[in] node circular list node to add to the list
124  *
125  * \sa \ref REDA_CircularList_link_node_after
126  */
127 REDADllExport void
128 REDA_CircularList_link_node_after(struct REDA_CircularListNode *after,
129  struct REDA_CircularListNode *node);
130 
131 /*ci
132  * \brief Unlink a circular list node from a circular list
133  *
134  * \details
135  *
136  * Remove a node from a circular list. No memory deallocation takes place
137  * when a node is unlinked. Note that this functions accepts a node where
138  * both pointers already are NULL, but _does not_ perform any error checking.
139  * If an invalid node is passed in the behavior is undefined.
140  *
141  * \param[in] node circular list node to remove from a list
142  */
143 REDADllExport void
144 REDA_CircularList_unlink_node(struct REDA_CircularListNode *node);
145 
146 /*ci
147  * \brief Add a circular list node to the end of a circular list
148  *
149  * \details
150  *
151  * Append a circular list node to the end of a circular list.
152  *
153  * \param[in] list circular list node to append element to
154  * \param[in] node circular list node to append
155  *
156  */
157 REDADllExport void
158 REDA_CircularList_append(REDA_CircularList_T *list,
159  REDA_CircularListNode_T *node);
160 
161 #define REDA_CircularList_append(list_,node_) \
162  REDA_CircularList_link_node_after((list_)->_prev,node_)
163 
164 /*ci
165  * \brief Add a circular list node to the beginning of the circular list
166  *
167  * \details
168  *
169  * Add a circular list node to the beginning of a circular list
170  *
171  * \param[in] list circular list node to prepend element to
172  * \param[in] node circular list node to prepend
173  *
174  */
175 REDADllExport void
176 REDA_CircularList_prepend(REDA_CircularList_T *list,
177  REDA_CircularListNode_T *node);
178 
179 #define REDA_CircularList_prepend(list_,node_) \
180  REDA_CircularList_link_node_after((list_),node_)
181 
182 /*ci
183  * \brief Check if a circular list is empty
184  *
185  * \details
186  *
187  * Check if a circular list is empty
188  *
189  * \param[in] list circular list to check
190  *
191  * \return RTI_TRUE if circular list is empty, RTI_FALSE if not empty
192  */
193 REDADllExport RTI_BOOL
194 REDA_CircularList_is_empty(REDA_CircularList_T *list);
195 
196 
197 /*ci
198  * \brief Check if a node is at the head of the circular list head
199  *
200  * \details
201  *
202  * Check if a node is at the head of the circular list head
203  *
204  * \param[in] list circular list node to check
205  * \param[in] node circular list node to check
206  *
207  * \return RTI_TRUE if node is at head, RTI_FALSE if not
208  */
209 REDADllExport RTI_BOOL
210 REDA_CircularList_node_at_head(REDA_CircularList_T *list,
211  REDA_CircularListNode_T *node);
212 
213 #define REDA_CircularList_node_at_head(c_list_,c_node_) \
214  ((void*)(c_list_) == (void*)(c_node_))
215 
216 /*ci
217  * \brief Return the head of a circular list
218  *
219  * \details
220  *
221  * Return the head of a circular list
222  *
223  * \param[in] list circular list node to return head of
224  *
225  * \return pointer to first element in circular list
226  */
227 REDADllExport REDA_CircularListNode_T*
228 REDA_CircularList_get_first(REDA_CircularList_T *list);
229 
230 #define REDA_CircularList_get_first(c_list_) ((c_list_)->_next)
231 
232 /*ci
233  * \brief Return the last element of a circular list
234  *
235  * \details
236  *
237  * Return the last element of a circular list
238  *
239  * \param[in] list circular list node to return the last element of
240  *
241  * \return pointer to last element in circular list
242  */
243 REDADllExport REDA_CircularListNode_T*
244 REDA_CircularList_get_last(REDA_CircularList_T *list);
245 
246 #define REDA_CircularList_get_last(c_list_) ((c_list_)->_prev)
247 
248 /*ci
249  * \brief Return the next element after a node
250  *
251  * \details
252  *
253  * Given a node in the circular list node, return the element after the node
254  *
255  * \param[in] node circular list node to return the next element of
256  *
257  * \return pointer to element after the node
258  */
259 REDADllExport REDA_CircularListNode_T*
260 REDA_CircularListNode_get_next(REDA_CircularListNode_T *node);
261 
262 #define REDA_CircularListNode_get_next(c_node_) ((c_node_)->_next)
263 
264 /*ci
265  * \brief Return the previous element after a node
266  *
267  * \details
268  *
269  * Given a node in the circular list node, return the element before the node
270  *
271  * \param[in] node circular list node to return the previous element of
272  *
273  * \return pointer to element before the node
274  */
275 REDADllExport REDA_CircularListNode_T*
276 REDA_CircularListNode_get_prev(REDA_CircularListNode_T *node);
277 
278 #define REDA_CircularListNode_get_prev(c_node_) ((c_node_)->_prev)
279 
280 /*ci
281  * \brief Check if a node is linked into a circular list
282  *
283  * \details
284  *
285  * Check if a node is linked into a circular list. Note that this function
286  * does only returns TRUE is both pointers are non-NULL. That is, this function
287  * only works on a valid circular list-node where either both link pointers
288  * are NULL or not NULL. If an invalid node is passed in the behavior is
289  * undefined.
290  *
291  * \param[in] node circular list node to check
292  *
293  * \return RTI_TRUE if node is linked, RTI_FALSE if not
294  */
295 REDADllExport RTI_BOOL
296 REDA_CircularListNode_is_linked(REDA_CircularListNode_T *node);
297 
298 #ifdef __cplusplus
299 } /* extern "C" */
300 #endif
301 
302 #endif /* reda_circularlist_h */
303 
304 /*ci @} */

RTI Connext DDS Micro Version 2.4.11 Copyright © Mon Jul 23 2018 Real-Time Innovations, Inc