summaryrefslogtreecommitdiff
path: root/include/asterisk
diff options
context:
space:
mode:
authorGeorge Joseph <george.joseph@fairview5.com>2015-05-09 15:58:46 -0600
committerGeorge Joseph <george.joseph@fairview5.com>2015-05-11 15:49:06 -0500
commit87d8b36755805a2eaec54aa71ee088f365695817 (patch)
tree8023552d60354ffe3a8eda0d94d089416ec40e57 /include/asterisk
parent4da293459297ed66fbb85aa53e328bd560e73d17 (diff)
vector: Add REMOVE, ADD_SORTED and RESET macros
Based on feedback from Corey Farrell and Y Ateya, a few new macros have been added... AST_VECTOR_REMOVE which takes a parameter to indicate if order should be preserved. AST_VECTOR_ADD_SORTED which adds an element to a sorted vector. AST_VECTOR_RESET which cleans all elements from the vector leaving the storage intact. Change-Id: I41d32dbdf7137e0557134efeff9f9f1064b58d14
Diffstat (limited to 'include/asterisk')
-rw-r--r--include/asterisk/vector.h90
1 files changed, 73 insertions, 17 deletions
diff --git a/include/asterisk/vector.h b/include/asterisk/vector.h
index 255c30b43..0a13c560b 100644
--- a/include/asterisk/vector.h
+++ b/include/asterisk/vector.h
@@ -273,6 +273,36 @@
})
/*!
+ * \brief Add an element into a sorted vector
+ *
+ * \param vec Sorted vector to add to.
+ * \param elem Element to insert.
+ * \param cmp A strcmp compatible compare function.
+ *
+ * \return 0 on success.
+ * \return Non-zero on failure.
+ *
+ * \warning Use of this macro on an unsorted vector will produce unpredictable results
+ */
+#define AST_VECTOR_ADD_SORTED(vec, elem, cmp) ({ \
+ int res = 0; \
+ size_t __idx = (vec)->current; \
+ do { \
+ if (__make_room((vec)->current, vec) != 0) { \
+ res = -1; \
+ break; \
+ } \
+ while (__idx > 0 && (cmp((vec)->elems[__idx - 1], elem) > 0)) { \
+ (vec)->elems[__idx] = (vec)->elems[__idx - 1]; \
+ __idx--; \
+ } \
+ (vec)->elems[__idx] = elem; \
+ (vec)->current++; \
+ } while (0); \
+ res; \
+})
+
+/*!
* \brief Remove an element from a vector by index.
*
* Note that elements in the vector may be reordered, so that the remove can
@@ -280,35 +310,48 @@
*
* \param vec Vector to remove from.
* \param idx Index of the element to remove.
+ * \param preserve_order Preserve the vector order.
+ *
* \return The element that was removed.
*/
-#define AST_VECTOR_REMOVE_UNORDERED(vec, idx) ({ \
- typeof((vec)->elems[0]) res; \
- size_t __idx = (idx); \
- ast_assert(__idx < (vec)->current); \
- res = (vec)->elems[__idx]; \
- (vec)->elems[__idx] = (vec)->elems[--(vec)->current]; \
+#define AST_VECTOR_REMOVE(vec, idx, preserve_ordered) ({ \
+ typeof((vec)->elems[0]) res; \
+ size_t __idx = (idx); \
+ ast_assert(__idx < (vec)->current); \
+ res = (vec)->elems[__idx]; \
+ if ((preserve_ordered)) { \
+ size_t __move; \
+ __move = ((vec)->current - (__idx) - 1) * sizeof(typeof((vec)->elems[0])); \
+ memmove(&(vec)->elems[__idx], &(vec)->elems[__idx + 1], __move); \
+ (vec)->current--; \
+ } else { \
+ (vec)->elems[__idx] = (vec)->elems[--(vec)->current]; \
+ }; \
res; \
})
/*!
+ * \brief Remove an element from an unordered vector by index.
+ *
+ * Note that elements in the vector may be reordered, so that the remove can
+ * happen in constant time.
+ *
+ * \param vec Vector to remove from.
+ * \param idx Index of the element to remove.
+ * \return The element that was removed.
+ */
+#define AST_VECTOR_REMOVE_UNORDERED(vec, idx) \
+ AST_VECTOR_REMOVE(vec, idx, 0)
+
+/*!
* \brief Remove an element from a vector by index while maintaining order.
*
* \param vec Vector to remove from.
* \param idx Index of the element to remove.
* \return The element that was removed.
*/
-#define AST_VECTOR_REMOVE_ORDERED(vec, idx) ({ \
- typeof((vec)->elems[0]) res; \
- size_t __idx = (idx); \
- size_t __move; \
- ast_assert(__idx < (vec)->current); \
- res = (vec)->elems[__idx]; \
- __move = ((vec)->current - (__idx) - 1) * sizeof(typeof((vec)->elems[0])); \
- memmove(&(vec)->elems[__idx], &(vec)->elems[__idx + 1], __move); \
- (vec)->current--; \
- res; \
-})
+#define AST_VECTOR_REMOVE_ORDERED(vec, idx) \
+ AST_VECTOR_REMOVE(vec, idx, 1)
/*!
* \brief Remove an element from a vector that matches the given comparison
@@ -421,6 +464,17 @@
#define AST_VECTOR_SIZE(vec) (vec)->current
/*!
+ * \brief Reset vector.
+ *
+ * \param vec Vector to reset.
+ * \param callback A cleanup callback or AST_VECTOR_ELEM_CLEANUP_NOOP.
+ */
+#define AST_VECTOR_RESET(vec, cleanup) ({ \
+ AST_VECTOR_CALLBACK_VOID(vec, cleanup); \
+ (vec)->current = 0; \
+})
+
+/*!
* \brief Get an address of element in a vector.
*
* \param vec Vector to query.
@@ -508,6 +562,8 @@
* \brief Execute a callback on every element in a vector returning the matching
* elements in a new vector
*
+ * This macro basically provides a filtered clone.
+ *
* \param vec Vector to operate on.
* \param callback A callback that takes at least 1 argument (the element)
* plus number of optional arguments