librnr  1.14.5
RoadNarrows Robotics Common Library 1
dlistvoid.h
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 /*! \file
3  *
4  * \brief Doubly linked list (dlist) of data pointers \#defines, types,
5  * and declarations.
6  *
7  * This file is configured to support a "poor man's" C version of class
8  * inheritance and templating.
9  *
10  * The "base" set of dlist data types and functions are DListVoid<<em>x</em>>
11  * named definitions with data types returning void*. These definitions are
12  * defined in librnr.
13  *
14  * A "derived" dlist can be defined using two \#define's
15  * (usually in a header file). Follow these \#defines with the inclusion of
16  * the this header file:
17  * <dl>
18  * <dt> \ref DLIST_DNAME </dt>
19  * <dd>
20  * The dlist derived namespace DList<\ref DLIST_DNAME><<em>x</em>>.
21  * </dd>
22  * <dt> \ref DLIST_DTYPE </dt>
23  * <dd> The dlist derived data type. </dd>
24  * </dl>
25  *
26  * Multiple dlist derived types and the base type may be used in the same C
27  * source.
28  *
29  * \sa
30  * dliststr.h for librnr string example. \n
31  * \ref example_dlist under "Related Pages" for another example.
32  *
33  * \pkgsynopsis
34  * RoadNarrows Robotics Common Library 1
35  *
36  * \pkgcomponent{Library}
37  * librnr
38  *
39  * \pkgfile{rnr/dlistvoid.h}
40  *
41  * \author Robin Knight (robin.knight@roadnarrows.com)
42  *
43  * \pkgcopyright{2005-2018,RoadNarrows LLC.,http://www.roadnarrows.com}
44  *
45  * \license{MIT}
46  *
47  * \EulaBegin
48  * See the README and EULA files for any copyright and licensing information.
49  * \EulaEnd
50  */
51 ////////////////////////////////////////////////////////////////////////////////
52 
53 #ifndef _RNR_DLISTVOID_H
54 #include <sys/types.h>
55 #include <stdio.h>
56 #endif // _RNR_DLISTVOID_H
57 
59 
60 
61 //-----------------------------------------------------------------------------
62 // Base and Derived DList Controls
63 //-----------------------------------------------------------------------------
64 
65 /*!
66  * Define the dlist name (must be literal).
67  *
68  * If \ref DLIST_DNAME is defined then a new set of dlist data types and
69  * functions will be defined, prefaced by DList<\ref DLIST_DNAME>.
70  *
71  * If \ref DLIST_DNAME is not defined, then the base set
72  * DListVoid<<em>x</em>> data types and functions will be used.
73  */
74 #ifndef DLIST_DNAME
75 #define DLIST_DNAME Void ///< base dlist name
76 #undef _DLIST_DERIVED ///< not a "derived" dlist
77 #else
78 #define _DLIST_DERIVED ///< derived dlist
79 #endif
80 #define _DLIST_NAME DLIST_DNAME ///< dlist name
81 
82 /*!
83  * Define the derived dlist data type (must be literal).
84  *
85  * If DLIST_DTYPE is defined then the data stored in the dlist and returned
86  * to the user or to callbacks will be \ref DLIST_DTYPE*.
87  *
88  * If \ref DLIST_DTYPE is not defined, then void is used.
89  */
90 #ifndef DLIST_DTYPE
91 #define DLIST_DTYPE void ///< base dlist data type
92 #endif
93 #define _DLIST_TYPE DLIST_DTYPE ///< dlist data type
94 
95 /*!
96  * Useful string concatenation macros.
97  */
98 #undef _CONCAT
99 #undef _CONCAT_
100 #define _CONCAT_(x, y) x ## y ///< build concatenation operator
101 #define _CONCAT(x, y) _CONCAT_(x, y) ///< now concatenate
102 
103 /*!
104  * \brief DList (base or derived) definition preface
105  */
106 #undef _DLIST_DEFPREFACE
107 #define _DLIST_DEFPREFACE _CONCAT(DList, _DLIST_NAME)
108 
109 /*!
110  * \brief DList (base or derived) definition name
111  */
112 #undef _DLIST_DEF
113 #define _DLIST_DEF(name) _CONCAT(_DLIST_DEFPREFACE, name)
114 
115 /*!
116  * DList (base or derived) node types.
117  */
118 #define _DLIST_HEAD _DLIST_DEF(_T) ///< dlist head
119 #define _DLIST_NODE _DLIST_DEF(Node_T) ///< dlist node
120 #define _DLIST_ITER _DLIST_DEF(Iter_T) ///< dlist iterator
121 
122 
123 //-----------------------------------------------------------------------------
124 // Base Data Types
125 //-----------------------------------------------------------------------------
126 
127 #ifndef _RNR_DLISTVOID_H
128 
129 /*!
130  * \brief Special dlist index value to insert before end-of-list.
131  */
132 #undef DLIST_INSERT_AT_END
133 #define DLIST_INSERT_AT_END (-1)
134 
135 /*!
136  * \brief Base: Node data comparator callback function type.
137  *
138  * \return Returns <0, 0, or >0 if pData1 is less than, equal, or greater than
139  * pData2, respectively.
140  */
141 typedef int (*DListVoidFuncDataCmp_T)(const void *, const void *);
142 
143 /*!
144  * \brief Base: Node data delete callback function type.
145  */
146 typedef void (*DListVoidFuncDataDelete_T)(void *);
147 
148 /*!
149  * \brief Base: Print node data callback function type.
150  * \sa DListVoidPrint()
151  */
152 typedef void (*DListVoidFuncDataPrint_T)(FILE *, void *);
153 
154 /*!
155  * Head and node stucture types.
156  */
157 typedef struct dlistvoid_head_t DListVoid_T; ///< base dlist head
158 typedef struct dlistvoid_node_t DListVoidNode_T; ///< base dlist node
159 
160 /*!
161  * \brief Base dlist iterator structure.
162  *
163  * \note void* is used instead of dnode_t* to hide implementation details but
164  * to also allow calling functions to define the iterator.
165  */
166 typedef struct
167 {
168  DListVoid_T *m_pHead; ///< pointer to dlistvoid head
169  void *m_pThis; ///< pointer to current dnode
170  void *m_pNext; ///< pointer to next dnode
172 
173 #endif // _RNR_DLISTVOID_H
174 
175 
176 //-----------------------------------------------------------------------------
177 // Derived Data Types
178 //-----------------------------------------------------------------------------
179 
180 #ifdef _DLIST_DERIVED
181 
182 /*!
183  * \brief Node data comparator callback function type.
184  *
185  * \par Name:
186  * DList<\ref DLIST_DNAME>FuncDataCmp_T
187  */
188 typedef int (*_DLIST_DEF(FuncDataCmp_T))(const _DLIST_TYPE *,
189  const _DLIST_TYPE *);
190 
191 /*!
192  * \brief Node data delete callback function type.
193  *
194  * \par Name:
195  * DList<\ref DLIST_DNAME>FuncDataDelete_T
196  */
197 typedef void (*_DLIST_DEF(FuncDataDelete_T))(_DLIST_TYPE *);
198 
199 /*!
200  * \brief Print node data callback function type.
201  *
202  * \par Name:
203  * DList<\ref DLIST_DNAME>FuncDataPrint_T
204  */
205 typedef void (*_DLIST_DEF(FuncDataPrint_T))(FILE *, _DLIST_TYPE *);
206 
207 /*!
208  * Head, node, and iterator stucture types.
209  *
210  * \par Name:
211  * DList<\ref DLIST_DNAME>_T \n
212  * DList<\ref DLIST_DNAME>Node_T \n
213  * DList<\ref DLIST_DNAME>Iter_T
214  */
215 typedef DListVoid_T _DLIST_HEAD; ///< dlist head
216 typedef DListVoidNode_T _DLIST_NODE; ///< dlist node
217 typedef DListVoidIter_T _DLIST_ITER; ///< dlist iterator
218 
219 #endif // _DLIST_DERIVED
220 
221 
222 //-----------------------------------------------------------------------------
223 // Base Prototypes
224 //-----------------------------------------------------------------------------
225 
226 #ifndef _RNR_DLISTVOID_H
227 
228 // Base
230  DListVoidFuncDataDelete_T fnDataDelete);
231 
232 // Base
233 extern void DListVoidDelete(DListVoid_T *pHead);
234 
235 // Base
236 extern void DListVoidDeleteAllNodes(DListVoid_T *pHead);
237 
238 // Base
239 extern void DListVoidDeleteNode(DListVoid_T *pHead, DListVoidNode_T *pNode);
240 
241 // Base
242 extern void DListVoidDeleteNodeAt(DListVoid_T *pHead, int iIndex);
243 
244 // Base
245 extern DListVoidNode_T *DListVoidUnlinkNodeAt(DListVoid_T *pHead, int iIndex);
246 
247 // Base
248 extern void *DListVoidUnlinkDataAt(DListVoid_T *pHead, int iIndex);
249 
250 // Base
251 extern DListVoidNode_T *DListVoidAppend(DListVoid_T *pHead, void *pData);
252 
253 // Base
254 extern DListVoidNode_T *DListVoidPrepend(DListVoid_T *pHead, void *pData);
255 
256 // Base
258  int iIndex,
259  void *pData);
260 
261 // Base
262 extern void *DListVoidGetNodeAt(DListVoid_T *pHead, int iIndex);
263 
264 // Base
265 extern void *DListVoidGetData(DListVoidNode_T *pNode);
266 
267 // Base
268 extern void *DListVoidGetDataAt(DListVoid_T *pHead, int iIndex);
269 
270 // Base
271 extern int DListVoidCount(DListVoid_T *pHead);
272 
273 // Base
275  DListVoidIter_T *pIter);
276 
277 // Base
279 
280 // Base
282  DListVoidIter_T *pIter);
283 
284 // Base
286 
287 // Base
289  const void *pData);
290 
291 // Base
292 extern void DListVoidPrint(DListVoid_T *pHead,
293  DListVoidFuncDataPrint_T fnDataPr,
294  FILE *fp);
295 
296 /*!
297  *
298  * \brief Attach user data to a new node and push on dlist stack.
299  *
300  * The dlist can serve as a LIFO stack (last in, first out) by using the
301  * push and pop operators.
302  *
303  * \param pHead Pointer to dlist (head).
304  * \param pData Pointer to user (allocated) data.
305  *
306  * \return Returns pointer to new node on success, NULL on failure.
307  */
309  void *pData)
310 {
311  return DListVoidPrepend(pHead, pData);
312 }
313 
314 /*!
315  * \brief Unlink node at top of dlist stack.
316  *
317  * The dlist can serve as a LIFO stack (last in, first out) by using the
318  * push and pop operators.
319  *
320  * \par Name:
321  * DList<\ref DLIST_DNAME>Pop()
322  *
323  * \param pHead Pointer to dlist (head).
324  *
325  * \return
326  * Returns void* to popped user data on success. \n
327  * NULL on empty stack or on failure.
328  */
329 static inline void *DListVoidPop(DListVoid_T *pHead)
330 {
331  return DListVoidUnlinkDataAt(pHead, 0);
332 }
333 
334 /*!
335  * \brief Attach user data to a new node and queue on dlist queue.
336  *
337  * The dlist can serve as a FIFO queue (first in, first out) by using the
338  * queue and dequeue operators.
339  *
340  * \par Name:
341  * DList<\ref DLIST_DNAME>Queue()
342  *
343  * \param pHead Pointer to dlist (head).
344  * \param pData Pointer to user (allocated) data.
345  *
346  * \return Returns pointer to new node on success, NULL on failure.
347  */
349  void *pData)
350 {
351  return DListVoidAppend(pHead, pData);
352 }
353 
354 /*!
355  * \brief Attach user data to a new node and queue on dlist queue.
356  * \brief Unlink node at the front of dlist queue.
357  *
358  * The dlist can serve as a FIFO queue (first in, first out) by using the
359  * queue and dequeue operators.
360  *
361  * \par Name:
362  * DList<\ref DLIST_DNAME>Dequeue()
363  *
364  * \param pHead Pointer to dlist (head).
365  *
366  * Returns pointer to dequeued node on success. \n
367  * NULL on empty queue or on failure.
368  */
369 static inline void *DListVoidDequeue(DListVoid_T *pHead)
370 {
371  return DListVoidUnlinkDataAt(pHead, 0);
372 }
373 
374 /*!
375  * \brief Initialize dlist iterator and return the data in first node in dlist.
376  *
377  * \par Name:
378  * DList<\ref DLIST_DNAME>IterDataFirst()
379  *
380  * \param pHead Pointer to dlist (head).
381  * \param pIter Pointer to iterator.
382  *
383  * \return
384  * Returns data in first node in dlist on success. \n
385  * NULL if dlist empty or on error.
386  */
387 static inline void *DListVoidIterDataFirst(DListVoid_T *pHead,
388  _DLIST_ITER *pIter)
389 {
390  return( DListVoidGetData(DListVoidIterNodeFirst(pHead, pIter)) );
391 }
392 
393 /*!
394  * \brief Get the data in the next iterated node in dlist.
395  *
396  * \par Name:
397  * DList<\ref DLIST_DNAME>IterDataNext()
398  *
399  * \param pIter Pointer to initialized iterator.
400  *
401  * \return
402  * Returns void* to popped user data on success. \n
403  * NULL if if at end of list or on error.
404  */
405 static inline void *DListVoidIterDataNext(_DLIST_ITER *pIter)
406 {
407  return( DListVoidGetData(DListVoidIterNodeNext(pIter)) );
408 }
409 
410 #endif // _RNR_DLISTVOID_H
411 
412 
413 //-----------------------------------------------------------------------------
414 // Derived Extensions
415 //-----------------------------------------------------------------------------
416 
417 #ifdef _DLIST_DERIVED
418 
419 /*!
420  * \brief Derived: Allocate and initialize new empty derived dlist.
421  *
422  * \par Name:
423  * DList<\ref DLIST_DNAME>New()
424  *
425  * \param fnDataCmp User-supplied data comparator function.
426  * NULL will disable some functions such as searches.
427  * \param fnDataDelete User-supplied data deallocator.
428  * NULL will cause user data not to be deleted.
429  *
430  * \return Returns pointer to new dlist (head) on success.
431  */
432 static inline _DLIST_HEAD *_DLIST_DEF(New)(_DLIST_DEF(FuncDataCmp_T) fnDataCmp,
433  _DLIST_DEF(FuncDataDelete_T) fnDataDelete)
434 {
435  return (_DLIST_HEAD *)DListVoidNew((DListVoidFuncDataCmp_T)fnDataCmp,
436  (DListVoidFuncDataDelete_T)fnDataDelete);
437 }
438 
439 /*!
440  * \brief Derived: Delete entire dlist.
441  *
442  * All user data are deleted with a per node callback to the user-supplied
443  * data delete function, if any. All nodes in the dlist and the dlist itself
444  * will be deleted. The dlist pointer will no longer be valid after this call.
445  *
446  * \par Name:
447  * DList<\ref DLIST_DNAME>Delete()
448  *
449  * \param pHead Pointer to dlist (head).
450  */
451 static inline void _DLIST_DEF(Delete)(_DLIST_HEAD *pHead)
452 {
453  DListVoidDelete(pHead);
454 }
455 
456 /*!
457  * \brief Derived: Unlink and delete all nodes and data from dlist,
458  * leaving dlist empty.
459  *
460  * User data are deleted with a per node callback to the user-supplied
461  * data delete function, if any.
462  *
463  * \par Name:
464  * DList<\ref DLIST_DNAME>DeleteAllNodes()
465  *
466  * \param pHead Pointer to dlist (head).
467  */
468 static inline void _DLIST_DEF(DeleteAllNodes)(_DLIST_HEAD *pHead)
469 {
471 }
472 
473 /*!
474  * \brief Derived: Unlink node from the dlist and delete the node and it's
475  * attached user data.
476  *
477  * User data are deleted with a callback to the user-supplied data delete
478  * function, if any.
479  *
480  * \par Name:
481  * DList<\ref DLIST_DNAME>DeleteNode()
482  *
483  * \param pHead Pointer to dlist (head).
484  * \param pNode Pointer to node to be deleted.
485  */
486 static inline void _DLIST_DEF(DeleteNode)(_DLIST_HEAD *pHead,
487  _DLIST_NODE *pNode)
488 {
489  DListVoidDeleteNode(pHead, pNode);
490 }
491 
492 /*!
493  * \brief Derived: Unlink the node from the dlist at the given index and delete
494  * it and it's attached user data.
495  *
496  * User data are deleted with a callback to the user-supplied data delete
497  * function, if any.
498  *
499  * \par Name:
500  * DList<\ref DLIST_DNAME>DeleteNodeAt()
501  *
502  * \param pHead Pointer to dlist (head).
503  * \param iIndex Index to dlist entry to delete.
504  */
505 static inline void _DLIST_DEF(DeleteNodeAt)(_DLIST_HEAD *pHead, int iIndex)
506 {
507  DListVoidDeleteNodeAt(pHead, iIndex);
508 }
509 
510 /*!
511  * \brief nlink the node from the dlist at the given index.
512  *
513  * The node and it's attached data are are deleted.
514  *
515  * \par Name:
516  * DList<\ref DLIST_DNAME>UnlinkNodeAt()
517  *
518  * \param pHead Pointer to dlist (head).
519  * \param iIndex Index to dlist entry to unlink.
520  *
521  * \return Returns pointer to unlinked node on success, NULL on failure.
522  */
523 static inline _DLIST_NODE *_DLIST_DEF(UnlinkNodeAt)(_DLIST_HEAD *pHead,
524  int iIndex)
525 {
526  return (_DLIST_NODE *)DListVoidUnlinkNodeAt(pHead, iIndex);
527 }
528 
529 /*!
530  * \brief Unlink the user data from the dlist at the given index.
531  *
532  * The node is deleted, but not the attached data.
533  *
534  * \par Name:
535  * DList<\ref DLIST_DNAME>UnlinkDataAt()
536  *
537  * \param pHead Pointer to dlist (head).
538  * \param iIndex Index to dlist entry to unlink.
539  *
540  * \return Returns DLIST_DTYPE* to user data on success, NULL on failure.
541  */
542 static inline _DLIST_TYPE *_DLIST_DEF(UnlinkDataAt)(_DLIST_HEAD *pHead,
543  int iIndex)
544 {
545  return (_DLIST_TYPE *)DListVoidUnlinkDataAt(pHead, iIndex);
546 }
547 
548 /*!
549  * \brief Derived: Attach user data to a new node and link to the end of dlist.
550  *
551  * \par Name:
552  * DList<\ref DLIST_DNAME>Append()
553  *
554  * \param pHead Pointer to dlist (head).
555  * \param pData Pointer to user (allocated) string.
556  *
557  * \return Returns pointer to new node on success, NULL on failure.
558  */
559 static inline _DLIST_NODE *_DLIST_DEF(Append)(_DLIST_HEAD *pHead,
560  _DLIST_TYPE *pData)
561 {
562  return (_DLIST_NODE *)DListVoidAppend(pHead, pData);
563 }
564 
565 /*!
566  * \brief Attach the user data to a new node and link to the start of dlist.
567  *
568  * \par Name:
569  * DList<\ref DLIST_DNAME>Prepend()
570  *
571  * \param pHead Pointer to dlist (head).
572  * \param pData Pointer to user (allocated) string.
573  *
574  * \return Returns pointer to new node on success, NULL on failure.
575  */
576 static inline _DLIST_NODE *_DLIST_DEF(Prepend)(_DLIST_HEAD *pHead,
577  _DLIST_TYPE *pData)
578 {
579  return (_DLIST_NODE *)DListVoidPrepend(pHead, pData);
580 }
581 
582 /*!
583  * \brief Attach the user data to a new node and insert before the dlist index.
584  *
585  * The special index value DLIST_INSERT_AT_END will insert at end-of-list
586  * (append).
587  *
588  * \par Name:
589  * DList<\ref DLIST_DNAME>Insert()
590  *
591  * \param pHead Pointer to dlist (head).
592  * \param iIndex Index to dlist entry where insertion occurs.
593  * \param pData Pointer to user (allocated) string.
594  *
595  * \return Returns pointer to new node on success, NULL on failure.
596  */
597 static inline _DLIST_NODE *_DLIST_DEF(Insert)(_DLIST_HEAD *pHead,
598  int iIndex,
599  _DLIST_TYPE *pData)
600 {
601  return (_DLIST_NODE *)DListVoidInsert(pHead, iIndex, pData);
602 }
603 
604 /*!
605  * \brief Derived: Get the node at the given dlist index.
606  *
607  * \par Name:
608  * DList<\ref DLIST_DNAME>GetNodeAt()
609  *
610  * \param pHead Pointer to dlist (head).
611  * \param iIndex Index to dlist entry to find.
612  *
613  * \return Returns node at index on success, NULL on failure.
614  */
615 static inline _DLIST_NODE *_DLIST_DEF(GetNodeAt)(_DLIST_HEAD *pHead, int iIndex)
616 {
617  return (_DLIST_NODE *)DListVoidGetNodeAt(pHead, iIndex);
618 }
619 
620 /*!
621  * \brief Derived: Get the user data from the given node.
622  *
623  * \par Name:
624  * DList<\ref DLIST_DNAME>GetData()
625  *
626  * \param pNode Pointer to node with data.
627  *
628  * \return Returns DLIST_DTYPE* to user string on success, NULL on failure.
629  */
630 static inline _DLIST_TYPE *_DLIST_DEF(GetData)(_DLIST_NODE *pNode)
631 {
632  return (_DLIST_TYPE *)DListVoidGetData(pNode);
633 }
634 
635 /*!
636  * \brief Derived: Get the user string from the dlist at the given index.
637  *
638  * \par Name:
639  * DList<\ref DLIST_DNAME>GetDataAt()
640  *
641  * \param pHead Pointer to dlist (head).
642  * \param iIndex Index to dlist entry.
643  *
644  * \return Returns char* to user string on success, NULL on failure.
645  */
646 static inline _DLIST_TYPE *_DLIST_DEF(GetDataAt)(_DLIST_HEAD *pHead, int iIndex)
647 {
648  return (_DLIST_TYPE *)DListVoidGetDataAt(pHead, iIndex);
649 }
650 
651 /*!
652  * \brief Derived: Get the number of nodes in dlist.
653  *
654  * \par Name:
655  * DList<\ref DLIST_DNAME>Count()
656  *
657  * \param pHead Pointer to dlist (head).
658  *
659  * \return Number of nodes in dlist.
660  */
661 static inline int _DLIST_DEF(Count)(_DLIST_HEAD *pHead)
662 {
663  return DListVoidCount(pHead);
664 }
665 
666 /*!
667  * \brief Derived: Initialize dlist iterator and return the first node in dlist.
668  *
669  * \par Name:
670  * DList<\ref DLIST_DNAME>IterNodeFirst()
671  *
672  * \param pHead Pointer to dlist (head).
673  * \param pIter Pointer to iterator.
674  *
675  * \return
676  * Returns first node in dlist on success.\n
677  * NULL if dlist empty or on error.
678  */
679 static inline _DLIST_NODE *_DLIST_DEF(IterNodeFirst)(_DLIST_HEAD *pHead,
680  _DLIST_ITER *pIter)
681 {
682  return (_DLIST_NODE *)DListVoidIterNodeFirst(pHead, pIter);
683 }
684 
685 /*!
686  * \brief Derived: Get the next iterated node in dlist.
687  *
688  * \par Name:
689  * DList<\ref DLIST_DNAME>IterNodeNext()
690  *
691  * \param pIter Pointer to initialized iterator.
692  *
693  * \return
694  * Returns next node in dlist on success.\n
695  * NULL if if at end of list or on error.
696  */
697 static inline _DLIST_NODE *_DLIST_DEF(IterNodeNext)(_DLIST_ITER *pIter)
698 {
699  return (_DLIST_NODE *)DListVoidIterNodeNext(pIter);
700 }
701 
702 /*!
703  * \brief Derived: Initialize dlist iterator and return the last node in dlist.
704  *
705  * \par Name:
706  * DList<\ref DLIST_DNAME>IterNodeLast()
707  *
708  * \param pHead Pointer to dlist (head).
709  * \param pIter Pointer to iterator.
710  *
711  * \return
712  * Returns last node in dlist on success.\n
713  * NULL if dlist empty or on error.
714  */
715 static inline _DLIST_NODE *_DLIST_DEF(IterNodeLast)(_DLIST_HEAD *pHead,
716  _DLIST_ITER *pIter)
717 {
718  return (_DLIST_NODE *)DListVoidIterNodeLast(pHead, pIter);
719 }
720 
721 /*!
722  * \brief Derived: Get the previous iterated node in dlist.
723  *
724  * \par Name:
725  * DList<\ref DLIST_DNAME>IterNodePrev()
726  *
727  * \param pIter Pointer to initialized iterator.
728  *
729  * \return
730  * Returns previous node in dlist on success.\n
731  * NULL if if at end of list or on error.
732  */
733 static inline _DLIST_NODE *_DLIST_DEF(IterNodePrev)(_DLIST_ITER *pIter)
734 {
735  return (_DLIST_NODE *)DListVoidIterNodePrev(pIter);
736 }
737 
738 /*!
739  * \brief Derived: Find the first node with the matching data.
740  *
741  * The user provided comparator function is used, if any.
742  *
743  * \par Name:
744  * DList<\ref DLIST_DNAME>FindNode()
745  *
746  * \param pHead Pointer to dlist (head).
747  * \param pData User data to find.
748  *
749  * \return
750  * Returns first node with mathcing data on success.\n
751  * NULL if no matches or on error.
752  */
753 static inline _DLIST_NODE *_DLIST_DEF(FindNode)(_DLIST_HEAD *pHead,
754  const _DLIST_TYPE *pData)
755 {
756  return (_DLIST_NODE *)DListVoidFindNode(pHead, pData);
757 }
758 
759 /*!
760  * \brief Derived: Traverse dlist and print.
761  *
762  * \par Name:
763  * DList<\ref DLIST_DNAME>Print()
764  *
765  * \param pHead Pointer to dlist (head).
766  * \param fnDataPr User data printing fucntion.
767  * \param fp Output file pointer.
768  */
769 static inline void _DLIST_DEF(Print)(_DLIST_HEAD *pHead,
770  _DLIST_DEF(FuncDataPrint_T) fnDataPr,
771  FILE *fp)
772 {
773  DListVoidPrint(pHead, (DListVoidFuncDataPrint_T)fnDataPr, fp);
774 }
775 
776 /*!
777  *
778  * \brief Attach user data to a new node and push on dlist stack.
779  *
780  * The dlist can serve as a LIFO stack (last in, first out) by using the
781  * push and pop operators.
782  *
783  * \par Name:
784  * DList<\ref DLIST_DNAME>Push()
785  *
786  * \param pHead Pointer to dlist (head).
787  * \param pData Pointer to user (allocated) data.
788  *
789  * \return Returns pointer to new node on success, NULL on failure.
790  */
791 static inline _DLIST_NODE *_DLIST_DEF(Push)(_DLIST_HEAD *pHead,
792  _DLIST_TYPE *pData)
793 {
794  return _DLIST_DEF(Prepend)(pHead, pData);
795 }
796 
797 /*!
798  * \brief Unlink node at top of dlist stack.
799  *
800  * The dlist can serve as a LIFO stack (last in, first out) by using the
801  * push and pop operators.
802  *
803  * \par Name:
804  * DList<\ref DLIST_DNAME>Pop()
805  *
806  * \param pHead Pointer to dlist (head).
807  *
808  * \return
809  * Returns void* to popped user data on success. \n
810  * NULL on empty stack or on failure.
811  */
812 static inline _DLIST_TYPE *_DLIST_DEF(Pop)(_DLIST_HEAD *pHead)
813 {
814  return _DLIST_DEF(UnlinkDataAt)(pHead, 0);
815 }
816 
817 /*!
818  * \brief Attach user data to a new node and queue on dlist queue.
819  *
820  * The dlist can serve as a FIFO queue (first in, first out) by using the
821  * queue and dequeue operators.
822  *
823  * \par Name:
824  * DList<\ref DLIST_DNAME>Queue()
825  *
826  * \param pHead Pointer to dlist (head).
827  * \param pData Pointer to user (allocated) data.
828  *
829  * \return Returns pointer to new node on success, NULL on failure.
830  */
831 static inline _DLIST_NODE *_DLIST_DEF(Queue)(_DLIST_HEAD *pHead,
832  _DLIST_TYPE *pData)
833 {
834  return _DLIST_DEF(Append)(pHead, pData);
835 }
836 
837 /*!
838  * \brief Attach user data to a new node and queue on dlist queue.
839  * \brief Unlink node at the front of dlist queue.
840  *
841  * The dlist can serve as a FIFO queue (first in, first out) by using the
842  * queue and dequeue operators.
843  *
844  * \par Name:
845  * DList<\ref DLIST_DNAME>Dequeue()
846  *
847  * \param pHead Pointer to dlist (head).
848  *
849  * Returns pointer to dequeued node on success. \n
850  * NULL on empty queue or on failure.
851  */
852 static inline _DLIST_TYPE *_DLIST_DEF(Dequeue)(_DLIST_HEAD *pHead)
853 {
854  return _DLIST_DEF(UnlinkDataAt)(pHead, 0);
855 }
856 
857 /*!
858  * \brief Initialize dlist iterator and return the data in first node in dlist.
859  *
860  * \par Name:
861  * DList<\ref DLIST_DNAME>IterDataFirst()
862  *
863  * \param pHead Pointer to dlist (head).
864  * \param pIter Pointer to iterator.
865  *
866  * \return
867  * Returns data in first node in dlist on success. \n
868  * NULL if dlist empty or on error.
869  */
870 static inline _DLIST_TYPE *_DLIST_DEF(IterDataFirst)(_DLIST_HEAD *pHead,
871  _DLIST_ITER *pIter)
872 {
873  return( _DLIST_DEF(GetData)(_DLIST_DEF(IterNodeFirst)(pHead, pIter)) );
874 }
875 
876 /*!
877  * \brief Get the data in the next iterated node in dlist.
878  *
879  * \par Name:
880  * DList<\ref DLIST_DNAME>IterDataNext()
881  *
882  * \param pIter Pointer to initialized iterator.
883  *
884  * \return
885  * Returns data in the next node on success. \n
886  * NULL if if at end of list or on error.
887  */
888 static inline _DLIST_TYPE *_DLIST_DEF(IterDataNext)(_DLIST_ITER *pIter)
889 {
890  return( _DLIST_DEF(GetData)(_DLIST_DEF(IterNodeNext)(pIter)) );
891 }
892 
893 /*!
894  * \brief Initialize dlist iterator and return the data in last node in dlist.
895  *
896  * \par Name:
897  * DList<\ref DLIST_DNAME>IterDataLast()
898  *
899  * \param pHead Pointer to dlist (head).
900  * \param pIter Pointer to iterator.
901  *
902  * \return
903  * Returns data in last node in dlist on success. \n
904  * NULL if dlist empty or on error.
905  */
906 static inline _DLIST_TYPE *_DLIST_DEF(IterDataLast)(_DLIST_HEAD *pHead,
907  _DLIST_ITER *pIter)
908 {
909  return( _DLIST_DEF(GetData)(_DLIST_DEF(IterNodeLast)(pHead, pIter)) );
910 }
911 
912 /*!
913  * \brief Get the data in the previous iterated node in dlist.
914  *
915  * \par Name:
916  * DList<\ref DLIST_DNAME>IterDataPrev()
917  *
918  * \param pIter Pointer to initialized iterator.
919  *
920  * \return
921  * Returns data in the previous node on success. \n
922  * NULL if if at end of list or on error.
923  */
924 static inline _DLIST_TYPE *_DLIST_DEF(IterDataPrev)(_DLIST_ITER *pIter)
925 {
926  return( _DLIST_DEF(GetData)(_DLIST_DEF(IterNodePrev)(pIter)) );
927 }
928 
929 #endif // _DLIST_DERIVED
930 
932 
933 
934 //-----------------------------------------------------------------------------
935 // Fix Up Defines
936 //-----------------------------------------------------------------------------
937 
938 /*!
939  * Undefine macros to allow redefinition.
940  */
941 #undef DLIST_DNAME
942 #undef DLIST_DTYPE
943 #undef _DLIST_DERIVED
944 #undef _DLIST_NAME
945 #undef _DLIST_TYPE
946 #undef _DLIST_HEAD
947 #undef _DLIST_NODE
948 #undef _DLIST_ITER
949 
950 #define _RNR_DLISTVOID_H ///< include base declaration only once
DListVoidNode_T * DListVoidIterNodeFirst(DListVoid_T *pHead, DListVoidIter_T *pIter)
Initialize dlist iterator and return the first node in dlist.
Definition: dlistvoid.c:531
void * DListVoidGetDataAt(DListVoid_T *pHead, int iIndex)
Get the user data from the dlist at the given index.
Definition: dlistvoid.c:496
void DListVoidDeleteAllNodes(DListVoid_T *pHead)
Unlink and delete all nodes and data from dlist, leaving dlist empty.
Definition: dlistvoid.c:161
void * m_pNext
pointer to next dnode
Definition: dlistvoid.h:170
int(* DListVoidFuncDataCmp_T)(const void *, const void *)
Base: Node data comparator callback function type.
Definition: dlistvoid.h:141
Base dlist iterator structure.
Definition: dlistvoid.h:166
DListVoidNode_T * DListVoidInsert(DListVoid_T *pHead, int iIndex, void *pData)
Attach the user data to a new node and insert before the dlist index.
Definition: dlistvoid.c:393
#define _DLIST_DEF(name)
DList (base or derived) definition name.
Definition: dlistvoid.h:113
void DListVoidDeleteNodeAt(DListVoid_T *pHead, int iIndex)
Unlink the node from the dlist at the given index and delete it and it&#39;s attached user data...
Definition: dlistvoid.c:228
DListVoidNode_T * DListVoidFindNode(DListVoid_T *pHead, const void *pData)
Find the first node with the matching data.
Definition: dlistvoid.c:645
void DListVoidDelete(DListVoid_T *pHead)
Delete entire dlist.
Definition: dlistvoid.c:140
DListVoidNode_T * DListVoidUnlinkNodeAt(DListVoid_T *pHead, int iIndex)
Unlink the node from the dlist at the given index.
Definition: dlistvoid.c:253
static void * DListVoidIterDataNext(DListVoidIter_T *pIter)
Get the data in the next iterated node in dlist.
Definition: dlistvoid.h:405
void * m_pThis
pointer to current dnode
Definition: dlistvoid.h:169
#define _DLIST_HEAD
dlist head
Definition: dlistvoid.h:118
void * DListVoidGetNodeAt(DListVoid_T *pHead, int iIndex)
Get the node at the given dlist index.
Definition: dlistvoid.c:442
DListVoidNode_T * DListVoidIterNodeLast(DListVoid_T *pHead, DListVoidIter_T *pIter)
Initialize dlist iterator and return the last node in dlist.
Definition: dlistvoid.c:587
#define C_DECLS_BEGIN
C declaration block begin in C.
Definition: rnrconfig.h:71
static void * DListVoidIterDataFirst(DListVoid_T *pHead, DListVoidIter_T *pIter)
Initialize dlist iterator and return the data in first node in dlist.
Definition: dlistvoid.h:387
static DListVoidNode_T * DListVoidPush(DListVoid_T *pHead, void *pData)
Attach user data to a new node and push on dlist stack.
Definition: dlistvoid.h:308
DListVoidNode_T * DListVoidIterNodeNext(DListVoidIter_T *pIter)
Get the next iterated node in dlist.
Definition: dlistvoid.c:559
void DListVoidDeleteNode(DListVoid_T *pHead, DListVoidNode_T *pNode)
Unlink node from the dlist and delete the node and it&#39;s attached user data.
Definition: dlistvoid.c:190
void(* DListVoidFuncDataDelete_T)(void *)
Base: Node data delete callback function type.
Definition: dlistvoid.h:146
DListVoidNode_T * DListVoidIterNodePrev(DListVoidIter_T *pIter)
Get the previous iterated node in dlist.
Definition: dlistvoid.c:615
#define _DLIST_NODE
dlist node
Definition: dlistvoid.h:119
#define C_DECLS_END
C declaration block end in C.
Definition: rnrconfig.h:72
DListVoidNode_T * DListVoidPrepend(DListVoid_T *pHead, void *pData)
Attach the user data to a new node and link to the start of dlist.
Definition: dlistvoid.c:357
void DListVoidPrint(DListVoid_T *pHead, DListVoidFuncDataPrint_T fnDataPr, FILE *fp)
Traverse dlist and print.
Definition: dlistvoid.c:679
Unit Tests (define to build test main)
Definition: dlistvoid.c:48
Doubly linked list node structure.
Definition: dlistvoid.c:59
void * DListVoidGetData(DListVoidNode_T *pNode)
Get the user data from the given node.
Definition: dlistvoid.c:483
void * DListVoidUnlinkDataAt(DListVoid_T *pHead, int iIndex)
Unlink the user data from the dlist at the given index.
Definition: dlistvoid.c:287
static DListVoidNode_T * DListVoidQueue(DListVoid_T *pHead, void *pData)
Attach user data to a new node and queue on dlist queue.
Definition: dlistvoid.h:348
void(* DListVoidFuncDataPrint_T)(FILE *, void *)
Base: Print node data callback function type.
Definition: dlistvoid.h:152
int DListVoidCount(DListVoid_T *pHead)
Get the number of nodes in dlist.
Definition: dlistvoid.c:517
DListVoidNode_T * DListVoidAppend(DListVoid_T *pHead, void *pData)
Attach user data to a new node and link to the end of dlist.
Definition: dlistvoid.c:325
#define _DLIST_ITER
dlist iterator
Definition: dlistvoid.h:120
#define _DLIST_TYPE
dlist data type
Definition: dlistvoid.h:93
DListVoid_T * DListVoidNew(DListVoidFuncDataCmp_T fnDataCmp, DListVoidFuncDataDelete_T fnDataDelete)
Allocate and initialize new empty dlist.
Definition: dlistvoid.c:110
static void * DListVoidPop(DListVoid_T *pHead)
Unlink node at top of dlist stack.
Definition: dlistvoid.h:329
static void * DListVoidDequeue(DListVoid_T *pHead)
Attach user data to a new node and queue on dlist queue.
Definition: dlistvoid.h:369
DListVoid_T * m_pHead
pointer to dlistvoid head
Definition: dlistvoid.h:168