This is an automated email from the ASF dual-hosted git repository.
pnoltes pushed a commit to branch feature/674-add-element-type-to-array-list
in repository https://gitbox.apache.org/repos/asf/celix.git
The following commit(s) were added to
refs/heads/feature/674-add-element-type-to-array-list by this push:
new 1f324c5b #674 Add array list equal and copy function
1f324c5b is described below
commit 1f324c5b2bb5ff20defaa9f2bdb32a66d1d33034
Author: Pepijn Noltes <[email protected]>
AuthorDate: Mon Feb 5 19:56:44 2024 +0100
#674 Add array list equal and copy function
---
libs/utils/gtest/src/ArrayListTestSuite.cc | 61 +++++++++++++++++++++++++
libs/utils/include/celix_array_list.h | 73 ++++++++++++++++++++++--------
libs/utils/src/array_list.c | 60 ++++++++++++++++++++++++
3 files changed, 175 insertions(+), 19 deletions(-)
diff --git a/libs/utils/gtest/src/ArrayListTestSuite.cc
b/libs/utils/gtest/src/ArrayListTestSuite.cc
index 6a508188..18069db7 100644
--- a/libs/utils/gtest/src/ArrayListTestSuite.cc
+++ b/libs/utils/gtest/src/ArrayListTestSuite.cc
@@ -376,6 +376,67 @@ TEST_F(ArrayListTestSuite, SortTypedArrayLists) {
EXPECT_EQ(0,
celix_version_compareToMajorMinor(celix_arrayList_getVersion(versionList, 4),
3, 2));
}
+TEST_F(ArrayListTestSuite, EqualCheck) {
+ //Given a selection of long list and a double list
+ celix_autoptr(celix_array_list_t) list1 =
celix_arrayList_createLongArray();
+ celix_arrayList_addLong(list1, 1L);
+ celix_autoptr(celix_array_list_t) list2 =
celix_arrayList_createLongArray(); //same as list1
+ celix_arrayList_addLong(list2, 1L);
+ celix_autoptr(celix_array_list_t) list3 =
celix_arrayList_createLongArray(); //different values than list1
+ celix_arrayList_addLong(list3, 2L);
+ celix_autoptr(celix_array_list_t) list4 =
celix_arrayList_createLongArray(); //different size than list1
+ celix_arrayList_addLong(list4, 1L);
+ celix_arrayList_addLong(list4, 2L);
+ celix_autoptr(celix_array_list_t) list5 =
celix_arrayList_createDoubleArray(); //different type than list1
+ celix_arrayList_addDouble(list5, 1.0);
+
+ //The lists can be checked for equality
+ EXPECT_TRUE(celix_arrayList_equals(list1, list2));
+ EXPECT_TRUE(celix_arrayList_equals(list1, list1));
+ EXPECT_TRUE(celix_arrayList_equals(nullptr, nullptr));
+
+ EXPECT_FALSE(celix_arrayList_equals(nullptr, list1));
+ EXPECT_FALSE(celix_arrayList_equals(list1, nullptr));
+ EXPECT_FALSE(celix_arrayList_equals(list1, list3));
+ EXPECT_FALSE(celix_arrayList_equals(list1, list4));
+ EXPECT_FALSE(celix_arrayList_equals(list1, list5));
+}
+
+TEST_F(ArrayListTestSuite, CopyArrayTest) {
+ // Given a long, string, string ref and version list
+ celix_autoptr(celix_array_list_t) longList =
celix_arrayList_createLongArray();
+ celix_arrayList_addLong(longList, 1L);
+ celix_arrayList_addLong(longList, 2L);
+ celix_arrayList_addLong(longList, 3L);
+
+ celix_autoptr(celix_array_list_t) stringList =
celix_arrayList_createStringArray();
+ celix_arrayList_addString(stringList, "1");
+ celix_arrayList_addString(stringList, "2");
+ celix_arrayList_addString(stringList, "3");
+
+ celix_autoptr(celix_array_list_t) stringRefList =
celix_arrayList_createStringRefArray();
+ celix_arrayList_addString(stringRefList, "1");
+ celix_arrayList_addString(stringRefList, "2");
+ celix_arrayList_addString(stringRefList, "3");
+
+ celix_autoptr(celix_array_list_t) versionList =
celix_arrayList_createVersionArray();
+ celix_arrayList_assignVersion(versionList, celix_version_create(1, 0, 0,
""));
+ celix_arrayList_assignVersion(versionList, celix_version_create(2, 0, 0,
""));
+ celix_arrayList_assignVersion(versionList, celix_version_create(3, 0, 0,
""));
+
+ // When copying the lists
+ celix_autoptr(celix_array_list_t) longListCopy =
celix_arrayList_copy(longList);
+ celix_autoptr(celix_array_list_t) stringListCopy =
celix_arrayList_copy(stringList);
+ celix_autoptr(celix_array_list_t) stringRefListCopy =
celix_arrayList_copy(stringRefList);
+ celix_autoptr(celix_array_list_t) versionListCopy =
celix_arrayList_copy(versionList);
+
+ // Then the copied lists are equal to the original lists
+ EXPECT_TRUE(celix_arrayList_equals(longList, longListCopy));
+ EXPECT_TRUE(celix_arrayList_equals(stringList, stringListCopy));
+ EXPECT_TRUE(celix_arrayList_equals(stringRefList, stringRefListCopy));
+ EXPECT_TRUE(celix_arrayList_equals(versionList, versionListCopy));
+}
+
TEST_F(ArrayListTestSuite, TestSimpleRemovedCallbacksForArrayList) {
celix_array_list_create_options_t opts{};
opts.simpleRemovedCallback = free;
diff --git a/libs/utils/include/celix_array_list.h
b/libs/utils/include/celix_array_list.h
index b4c2dc58..3a0b0ff9 100644
--- a/libs/utils/include/celix_array_list.h
+++ b/libs/utils/include/celix_array_list.h
@@ -163,7 +163,7 @@ typedef struct celix_array_list_create_options {
#ifndef __cplusplus
/**
- * @brief C Macro to create a empty string_hash_map_create_options_t type.
+ * @brief C Macro to create a empty celix_array_list_create_options_t type.
*/
#define CELIX_EMPTY_ARRAY_LIST_CREATE_OPTIONS
\
{
\
@@ -331,7 +331,7 @@ int celix_arrayList_size(const celix_array_list_t *list);
* Can be used for array list with element type
CELIX_ARRAY_LIST_ELEMENT_TYPE_POINTER or
* CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
*
- * @param map The array list.
+ * @param list The array list.
* @param index The entry index to return.
* @return Returns the pointer value for the index. Returns NULL if index is
out of bound.
*/
@@ -357,7 +357,7 @@ const char* celix_arrayList_getString(const
celix_array_list_t *list, int index)
* Can be used for array list with element type
CELIX_ARRAY_LIST_ELEMENT_TYPE_INT or
* CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
*
- * @param map The array list.
+ * @param list The array list.
* @param index The entry index to return.
* @return Returns the int value for the index. Returns 0 if index is out of
bound.
*/
@@ -370,7 +370,7 @@ int celix_arrayList_getInt(const celix_array_list_t *list,
int index);
* Can be used for array list with element type
CELIX_ARRAY_LIST_ELEMENT_TYPE_LONG or
* CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
*
- * @param map The array list.
+ * @param list The array list.
* @param index The entry index to return.
* @return Returns the long value for the index. Returns 0 if index is out of
bound.
*/
@@ -383,7 +383,7 @@ long int celix_arrayList_getLong(const celix_array_list_t
*list, int index);
* Can be used for array list with element type
CELIX_ARRAY_LIST_ELEMENT_TYPE_UINT or
* CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
*
- * @param map The array list.
+ * @param list The array list.
* @param index The entry index to return.
* @return Returns the unsigned int value for the index. Returns 0 if index is
out of bound.
*/
@@ -396,7 +396,7 @@ unsigned int celix_arrayList_getUInt(const
celix_array_list_t *list, int index);
* Can be used for array list with element type
CELIX_ARRAY_LIST_ELEMENT_TYPE_ULONG or
* CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
*
- * @param map The array list.
+ * @param list The array list.
* @param index The entry index to return.
* @return Returns the unsigned long value for the index. Returns 0 if index
is out of bound.
*/
@@ -409,7 +409,7 @@ unsigned long int celix_arrayList_getULong(const
celix_array_list_t *list, int i
* Can be used for array list with element type
CELIX_ARRAY_LIST_ELEMENT_TYPE_FLOAT or
* CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
*
- * @param map The array list.
+ * @param list The array list.
* @param index The entry index to return.
* @return Returns the float value for the index. Returns 0 if index is out of
bound.
*/
@@ -422,7 +422,7 @@ float celix_arrayList_getFloat(const celix_array_list_t
*list, int index);
* Can be used for array list with element type
CELIX_ARRAY_LIST_ELEMENT_TYPE_DOUBLE or
* CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
*
- * @param map The array list.
+ * @param list The array list.
* @param index The entry index to return.
* @return Returns the double value for the index. Returns 0 if index is out
of bound.
*/
@@ -435,7 +435,7 @@ double celix_arrayList_getDouble(const celix_array_list_t
*list, int index);
* Can be used for array list with element type
CELIX_ARRAY_LIST_ELEMENT_TYPE_BOOL or
* CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
*
- * @param map The array list.
+ * @param list The array list.
* @param index The entry index to return.
* @return Returns the bool value for the index. Returns false if index is out
of bound.
*/
@@ -448,7 +448,7 @@ bool celix_arrayList_getBool(const celix_array_list_t
*list, int index);
* Can be used for array list with element type
CELIX_ARRAY_LIST_ELEMENT_TYPE_SIZE or
* CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
*
- * @param map The array list.
+ * @param list The array list.
* @param index The entry index to return.
* @return Returns the size_t value for the index. Returns 0 if index is out
of bound.
*/
@@ -474,7 +474,7 @@ const celix_version_t* celix_arrayList_getVersion(const
celix_array_list_t *list
* Can be used for array list with element type
CELIX_ARRAY_LIST_ELEMENT_TYPE_POINTER or
* CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
*
- * @param map The array list.
+ * @param list The array list.
* @param value The pointer value to add to the array list.
* @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list
is out of memory.
*/
@@ -518,7 +518,7 @@ celix_status_t
celix_arrayList_assignString(celix_array_list_t* list, char* valu
* Can be used for array list with element type
CELIX_ARRAY_LIST_ELEMENT_TYPE_INT or
* CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
*
- * @param map The array list.
+ * @param list The array list.
* @param value The int value to add to the array list.
* @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list
is out of memory.
*/
@@ -531,7 +531,7 @@ celix_status_t celix_arrayList_addInt(celix_array_list_t*
list, int value);
* Can be used for array list with element type
CELIX_ARRAY_LIST_ELEMENT_TYPE_LONG or
* CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
*
- * @param map The array list.
+ * @param list The array list.
* @param value The long value to add to the array list.
* @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list
is out of memory.
*/
@@ -544,7 +544,7 @@ celix_status_t celix_arrayList_addLong(celix_array_list_t*
list, long value);
* Can be used for array list with element type
CELIX_ARRAY_LIST_ELEMENT_TYPE_UINT or
* CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
*
- * @param map The array list.
+ * @param list The array list.
* @param value The unsigned int value to add to the array list.
* @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list
is out of memory.
*/
@@ -557,7 +557,7 @@ celix_status_t celix_arrayList_addUInt(celix_array_list_t*
list, unsigned int va
* Can be used for array list with element type
CELIX_ARRAY_LIST_ELEMENT_TYPE_ULONG or
* CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
*
- * @param map The array list.
+ * @param list The array list.
* @param value The unsigned long value to add to the array list.
* @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list
is out of memory.
*/
@@ -570,7 +570,7 @@ celix_status_t celix_arrayList_addULong(celix_array_list_t*
list, unsigned long
* Can be used for array list with element type
CELIX_ARRAY_LIST_ELEMENT_TYPE_FLOAT or
* CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
*
- * @param map The array list.
+ * @param list The array list.
* @param value The float value to add to the array list.
* @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list
is out of memory.
*/
@@ -583,7 +583,7 @@ celix_status_t celix_arrayList_addFloat(celix_array_list_t*
list, float value);
* Can be used for array list with element type
CELIX_ARRAY_LIST_ELEMENT_TYPE_DOUBLE or
* CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
*
- * @param map The array list.
+ * @param list The array list.
* @param value The double value to add to the array list.
* @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list
is out of memory.
*/
@@ -596,7 +596,7 @@ celix_status_t
celix_arrayList_addDouble(celix_array_list_t* list, double value)
* Can be used for array list with element type
CELIX_ARRAY_LIST_ELEMENT_TYPE_BOOL or
* CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
*
- * @param map The array list.
+ * @param list The array list.
* @param value The bool value to add to the array list.
* @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list
is out of memory.
*/
@@ -609,7 +609,7 @@ celix_status_t celix_arrayList_addBool(celix_array_list_t*
list, bool value);
* Can be used for array list with element type
CELIX_ARRAY_LIST_ELEMENT_TYPE_SIZE or
* CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED.
*
- * @param map The array list.
+ * @param list The array list.
* @param value The size_t value to add to the array list.
* @return CELIX_SUCCESS if the value is added, CELIX_ENOMEM if the array list
is out of memory.
*/
@@ -835,6 +835,41 @@ void celix_arrayList_sortEntries(celix_array_list_t *list,
celix_array_list_comp
CELIX_UTILS_EXPORT
void celix_arrayList_sort(celix_array_list_t *list);
+/**
+ * @brief Check if the array list are equal.
+ *
+ * Equal is defined as:
+ * - The array list have the same size
+ * - The array list have the same element type
+ * - The array list have the same equals callback
+ * - The array list have the same values at the same index
+ *
+ * Note that the remove callback and compare callback are ignored.
+ *
+ * If both array list are NULL, they are considered equal.
+ *
+ * @param listA The first array list.
+ * @param listB The second array list.
+ * @return true if the array list are equal, false otherwise.
+ */
+CELIX_UTILS_EXPORT
+bool celix_arrayList_equals(const celix_array_list_t* listA, const
celix_array_list_t* listB);
+
+/**
+ * @Brief Copy the array list to a new array list.
+ *
+ * The new array list will have the same element type and the same callbacks
as the original array list.
+ * If the element type is CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING, the strings
will be copied and
+ * if the element type is CELIX_ARRAY_LIST_ELEMENT_TYPE_VERSION, the versions
will be copied.
+ * For all other element types the values will be copied.
+ *
+ * @param[in] list The array list to copy.
+ * @return A new array list with the same element type and values as the
original array list or NULL if the original
+ * array list is NULL or out of memory.
+ */
+CELIX_UTILS_EXPORT
+celix_array_list_t* celix_arrayList_copy(const celix_array_list_t* list);
+
#ifdef __cplusplus
}
#endif
diff --git a/libs/utils/src/array_list.c b/libs/utils/src/array_list.c
index cf668150..59108cf9 100644
--- a/libs/utils/src/array_list.c
+++ b/libs/utils/src/array_list.c
@@ -715,6 +715,66 @@ void celix_arrayList_sort(celix_array_list_t *list) {
}
}
+bool celix_arrayList_equals(const celix_array_list_t* listA, const
celix_array_list_t* listB) {
+ if (listA == listB) {
+ return true;
+ }
+ if (!listA || !listB) {
+ return false;
+ }
+ if (listA->size != listB->size) {
+ return false;
+ }
+ if (listA->equalsCallback != listB->equalsCallback) {
+ return false;
+ }
+ for (int i = 0; i < listA->size; ++i) {
+ if (!listA->equalsCallback(listA->elementData[i],
listB->elementData[i])) {
+ return false;
+ }
+ }
+ return true;
+}
+
+celix_array_list_t* celix_arrayList_copy(const celix_array_list_t* list) {
+ celix_array_list_create_options_t opts =
CELIX_EMPTY_ARRAY_LIST_CREATE_OPTIONS;
+ opts.elementType = list->elementType;
+ opts.equalsCallback = list->equalsCallback;
+ opts.compareCallback = list->compareCallback;
+ opts.removedCallback = list->removedCallback;
+ opts.removedCallbackData = list->removedCallbackData;
+ opts.simpleRemovedCallback = list->simpleRemovedCallback;
+ celix_autoptr(celix_array_list_t) copy =
celix_arrayList_createWithOptions(&opts);
+ if (!copy) {
+ celix_err_push("Failed to create copy list. Out of memory.");
+ return NULL;
+ }
+
+ for (int i = 0; i < celix_arrayList_size(list); ++i) {
+ celix_array_list_entry_t entry = list->elementData[i];
+ if (copy->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING) {
+ entry.stringVal = celix_utils_strdup(entry.stringVal);
+ if (entry.stringVal == NULL) {
+ celix_err_push("Failed to copy string entry. Out of memory.");
+ return NULL;
+ }
+ } else if (copy->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_VERSION)
{
+ entry.versionVal = celix_version_copy(entry.versionVal);
+ if (entry.versionVal == NULL) {
+ celix_err_push("Failed to copy version entry. Out of memory.");
+ return NULL;
+ }
+ }
+ celix_status_t status = celix_arrayList_addEntry(copy, entry);
+ if (status != CELIX_SUCCESS) {
+ celix_err_push("Failed to add entry to copy list.");
+ return NULL;
+ }
+ }
+
+ return celix_steal_ptr(copy);
+}
+
void celix_arrayList_sortEntries(celix_array_list_t *list,
celix_array_list_compare_entries_fp compare) {
#if defined(__APPLE__)
qsort_r(list->elementData, list->size, sizeof(celix_array_list_entry_t),
compare, celix_arrayList_compareEntries);