vxlan: vxlan/vxlan.api API cleanup
[vpp.git] / src / vppinfra / llist.h
index 1648021..25fb95f 100644 (file)
@@ -51,6 +51,22 @@ typedef struct clib_llist_anchor
  * @return     pool entry index
  */
 #define clib_llist_entry_index(LP,E) ((E) - (LP))
+/**
+ * Get prev list entry index
+ *
+ * @param E    pool entry
+ * @name       list anchor name
+ * @return     previous index
+ */
+#define clib_llist_prev_index(E,name) _lprev(E,name)
+/**
+ * Get next list entry index
+ *
+ * @param E    pool entry
+ * @name       list anchor name
+ * @return     next index
+ */
+#define clib_llist_next_index(E,name) _lnext(E,name)
 /**
  * Get next pool entry
  *
@@ -102,7 +118,17 @@ do {                                                                       \
  * @param H    list head
  * @return     1 if sentinel is the only node part of the list, 0 otherwise
  */
-#define clib_llist_is_empty(LP,name,H) ((H) == clib_llist_next((LP),name,(H)))
+#define clib_llist_is_empty(LP,name,H)                                         \
+  (clib_llist_entry_index (LP,H) == (H)->name.next)
+/**
+ * Check if element is linked in a list
+ *
+ * @param E    list element
+ * @param name list anchor name
+ */
+#define clib_llist_elt_is_linked(E,name)                               \
+  ((E)->name.next != CLIB_LLIST_INVALID_INDEX                          \
+   && (E)->name.prev != CLIB_LLIST_INVALID_INDEX)
 /**
  * Insert entry between previous and next
  *
@@ -175,7 +201,22 @@ do {                                                                       \
   _lprev (_ll_var (N),name) = _lprev (E,name);                         \
   _lnext (E,name) = _lprev (E,name) = CLIB_LLIST_INVALID_INDEX;                \
 }while (0)
-
+/**
+ * Removes and returns the first element in the list.
+ *
+ * The element is not freed. It's the responsability of the caller to
+ * free it.
+ *
+ * @param LP   linked list pool
+ * @param name list anchor name
+ * @param E    storage the first entry
+ * @param H    list head entry
+ */
+#define clib_llist_pop_first(LP,name,E,H)                              \
+do {                                                                   \
+  E = clib_llist_next (LP,name,H);                                     \
+  clib_llist_remove (LP,name,E);                                       \
+} while (0)
 /**
  * Splice two lists at a given position
  *
@@ -222,6 +263,28 @@ do {                                                                       \
       (E) = _ll_var (n);                                               \
     }                                                                  \
 } while (0)
+/**
+ * Walk list starting at head safe
+ *
+ * @param LP   linked list pool
+ * @param name list anchor name
+ * @param HI   head index
+ * @param EI   entry index iterator
+ * @param body code to be executed
+ */
+#define clib_llist_foreach_safe(LP,name,H,E,body)                      \
+do {                                                                   \
+  clib_llist_index_t _ll_var (HI) = clib_llist_entry_index (LP, H);    \
+  clib_llist_index_t _ll_var (EI), _ll_var (NI);                       \
+  _ll_var (EI) = _lnext ((H),name);                                    \
+  while (_ll_var (EI) != _ll_var (HI))                                 \
+    {                                                                  \
+      (E) = pool_elt_at_index (LP, _ll_var (EI));                      \
+      _ll_var (NI) = _lnext ((E),name);                                        \
+      do { body; } while (0);                                          \
+      _ll_var (EI) = _ll_var (NI);                                     \
+    }                                                                  \
+} while (0)
 /**
  * Walk list starting at head in reverse order
  *