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);

Reply via email to