]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
vector: defaults and indexes
authorKevin Harwell <kharwell@digium.com>
Tue, 25 Apr 2017 16:43:26 +0000 (11:43 -0500)
committerKevin Harwell <kharwell@digium.com>
Wed, 26 Apr 2017 18:24:44 +0000 (13:24 -0500)
Added an pre-defined integer vector declaration. This makes integer vectors
easier to declare and pass around. Also, added the ability to default a vector
up to a given size with a default value. Lastly, added functionality that
returns the "nth" index of a matching value.

Also, updated a unit test to test these changes.

Change-Id: Iaf4b51b2540eda57cb43f67aa59cf1d96cdbcaa5

include/asterisk/vector.h
tests/test_vector.c

index 6b4e6324276f788c46de9568973cec8914bbaa7b..2073baedf64a69a7c17c531f08c4b3967865a34c 100644 (file)
@@ -48,6 +48,9 @@
                size_t current;                 \
        }
 
+/*! \brief Integer vector definition */
+AST_VECTOR(ast_vector_int, int);
+
 /*!
  * \brief Define a vector structure with a read/write lock
  *
        res;                                                                                    \
 })
 
+/*!
+ * \brief Default a vector up to size with the given value.
+ *
+ * \note If a size of 0 is given then all elements in the given vector are set.
+ * \note The vector will grow to the given size if needed.
+ *
+ * \param vec Vector to default.
+ * \param size The number of elements to default
+ * \param value The default value to set each element to
+ */
+#define AST_VECTOR_DEFAULT(vec, size, value) ({ \
+       int res = 0;                                                    \
+       typeof((size)) __size = (size) ? (size) : AST_VECTOR_SIZE(vec); \
+       size_t idx;                                                     \
+       for (idx = 0; idx < __size; ++idx) {                            \
+               res = AST_VECTOR_REPLACE(vec, idx, value);              \
+               if (res == -1) {                                        \
+                       break;                                          \
+               }                                                       \
+       }                                                               \
+       res;                                                            \
+})
+
 /*!
  * \brief Insert an element at a specific position in a vector, growing the vector if needed.
  *
        (vec)->elems[__idx];                    \
 })
 
+/*!
+ * \brief Get the nth index from a vector that matches the given comparison
+ *
+ * \param vec Vector to get from.
+ * \param nth The nth index to find
+ * \param value Value to pass into comparator.
+ * \param cmp Comparator function/macros (called as \c cmp(elem, value))
+ *
+ * \return a pointer to the element that was found or NULL
+ */
+#define AST_VECTOR_GET_INDEX_NTH(vec, nth, value, cmp) ({ \
+       int res = -1; \
+       size_t idx; \
+       typeof(nth) __nth = (nth); \
+       typeof(value) __value = (value); \
+       for (idx = 0; idx < (vec)->current; ++idx) { \
+               if (cmp((vec)->elems[idx], __value) && !(--__nth)) {    \
+                       res = (int)idx;                                 \
+                       break; \
+               } \
+       } \
+       res; \
+})
+
+/*!
+ * \brief Get the 1st index from a vector that matches the given comparison
+ *
+ * \param vec Vector to get from.
+ * \param value Value to pass into comparator.
+ * \param cmp Comparator function/macros (called as \c cmp(elem, value))
+ *
+ * \return a pointer to the element that was found or NULL
+ */
+#define AST_VECTOR_GET_INDEX(vec, value, cmp) \
+       AST_VECTOR_GET_INDEX_NTH(vec, 1, value, cmp)
+
 /*!
  * \brief Get an element from a vector that matches the given comparison
  *
index 8ca4efa1abf233e84bb5690abac56eaa0f368272..8e0d121ddf2239fb9370dfa8d5721ff347e5938a 100644 (file)
@@ -282,6 +282,25 @@ AST_TEST_DEFINE(basic_ops_integer)
        ast_test_validate_cleanup(test, *(int *)AST_VECTOR_GET_CMP(&sv1, AAA,  AST_VECTOR_ELEM_DEFAULT_CMP) == AAA, rc, cleanup);
        ast_test_validate_cleanup(test, *(int *)AST_VECTOR_GET_CMP(&sv1, ZZZ, AST_VECTOR_ELEM_DEFAULT_CMP) == ZZZ, rc, cleanup);
 
+       /* Default first value */
+       ast_test_validate_cleanup(test, AST_VECTOR_DEFAULT(&sv1, 1, CCC) == 0, rc, cleanup);
+       ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == CCC, rc, cleanup);
+       ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == ZZZ, rc, cleanup);
+       /* Default all values */
+       ast_test_validate_cleanup(test, AST_VECTOR_DEFAULT(&sv1, 0, AAA) == 0, rc, cleanup);
+       ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
+       ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == AAA, rc, cleanup);
+       ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 2) == AAA, rc, cleanup);
+       ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 3) == AAA, rc, cleanup);
+       /* Default more values than are currently in the vector */
+       ast_test_validate_cleanup(test, AST_VECTOR_DEFAULT(&sv1, 5, BBB) == 0, rc, cleanup);
+       ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 4) == BBB, rc, cleanup);
+
+       /* Check getting index(es) */
+       ast_test_validate_cleanup(test, AST_VECTOR_GET_INDEX(&sv1, BBB, AST_VECTOR_ELEM_DEFAULT_CMP) == 0, rc, cleanup);
+       ast_test_validate_cleanup(test, AST_VECTOR_GET_INDEX_NTH(&sv1, 2, BBB, AST_VECTOR_ELEM_DEFAULT_CMP) == 1, rc, cleanup);
+       ast_test_validate_cleanup(test, AST_VECTOR_GET_INDEX_NTH(&sv1, 4, BBB, AST_VECTOR_ELEM_DEFAULT_CMP) == 3, rc, cleanup);
+
        AST_VECTOR_FREE(&sv1);
        ast_test_validate(test, sv1.elems == NULL);
        ast_test_validate(test, sv1.current == 0);