summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/array.c91
-rw-r--r--tests/lib.c40
2 files changed, 91 insertions, 40 deletions
diff --git a/src/array.c b/src/array.c
index 58d3c7f..3236f67 100644
--- a/src/array.c
+++ b/src/array.c
@@ -17,20 +17,31 @@
#define al_array_is_empty(arr) ((arr).size == 0)
+#define al_array_offset(arr, i) ((arr).data + (i))
+
#define al_array_at(arr, i) ((arr).data[i])
#define al_array_last(arr) al_array_at(arr, (arr).size - 1)
#define al_array_reserve(arr, size) \
((arr).alloc = _al_array_reserve((void *)&(arr).data, al_array_item_size(arr), (arr).alloc, size))
-#define al_array_clone(dest, src) \
-AL_MACRO_WRAP \
-({ \
- al_array_init(dest); \
- al_array_reserve(dest, (src).size); \
- (dest).size = (src).size; \
- al_memcpy(&al_array_at(dest, 0), &al_array_at(src, 0), \
- al_array_item_size(dest) * (dest).size); \
+#define al_array_clone(dest, src) \
+AL_MACRO_WRAP \
+({ \
+ al_array_init(dest); \
+ al_array_reserve(dest, (src).size); \
+ (dest).size = (src).size; \
+ al_memcpy(al_array_offset(dest, 0), al_array_offset(src, 0), \
+ al_array_item_size(dest) * (dest).size); \
+})
+
+#define al_array_copy(dest, src) \
+AL_MACRO_WRAP \
+({ \
+ al_array_reserve(dest, (src).size); \
+ (dest).size = (src).size; \
+ al_memcpy(al_array_offset(dest, 0), al_array_offset(src, 0), \
+ al_array_item_size(dest) * (dest).size); \
})
#define al_array_push(arr, item) \
@@ -40,19 +51,19 @@ AL_MACRO_WRAP \
al_array_at(arr, (arr).size++) = item; \
})
-#define al_array_insert(arr, i, item) \
-AL_MACRO_WRAP \
-({ \
- if ((arr).size > i) { \
- al_array_reserve(arr, (arr).size + 1); \
- al_memmove(&al_array_at(arr, i + 1), &al_array_at(arr, i), \
- al_array_item_size(arr) * ((arr).size - i)); \
- (arr).size++; \
- } else { \
- al_array_reserve(arr, i + 1); \
- (arr).size = i + 1; \
- } \
- al_array_at(arr, i) = item; \
+#define al_array_insert(arr, i, item) \
+AL_MACRO_WRAP \
+({ \
+ if ((arr).size > i) { \
+ al_array_reserve(arr, (arr).size + 1); \
+ al_memmove(al_array_offset(arr, i + 1), al_array_offset(arr, i), \
+ al_array_item_size(arr) * ((arr).size - i)); \
+ (arr).size++; \
+ } else { \
+ al_array_reserve(arr, i + 1); \
+ (arr).size = i + 1; \
+ } \
+ al_array_at(arr, i) = item; \
})
#define al_array_pop(arr) al_array_at(arr, --(arr).size)
@@ -97,25 +108,25 @@ AL_MACRO_WRAP \
} \
})
-#define al_array_remove_at(arr, i) \
-AL_MACRO_WRAP \
-({ \
- if (i == (arr).size - 1) { \
- (arr).size--; \
- } else { \
- al_memmove(&al_array_at(arr, i), &al_array_at(arr, i + 1), \
- al_array_item_size(arr) * (--(arr).size - i)); \
- } \
+#define al_array_remove_at(arr, i) \
+AL_MACRO_WRAP \
+({ \
+ if (i == (arr).size - 1) { \
+ (arr).size--; \
+ } else { \
+ al_memmove(al_array_offset(arr, i), al_array_offset(arr, i + 1), \
+ al_array_item_size(arr) * (--(arr).size - i)); \
+ } \
})
-#define al_array_remove_range(arr, i, e) \
-AL_MACRO_WRAP \
-({ \
- if (e != (arr).size) { \
- al_memmove(&al_array_at(arr, i), &al_array_at(arr, e), \
- al_array_item_size(arr) * ((arr).size - e)); \
- } \
- (arr).size -= e - i; \
+#define al_array_remove_range(arr, i, e) \
+AL_MACRO_WRAP \
+({ \
+ if (e != (arr).size) { \
+ al_memmove(al_array_offset(arr, i), al_array_offset(arr, e), \
+ al_array_item_size(arr) * ((arr).size - e)); \
+ } \
+ (arr).size -= e - i; \
})
#ifdef AL_USE_STDLIB
@@ -134,10 +145,10 @@ AL_MACRO_WRAP \
for (u32 i = (arr).size; (i-- > 0 && (item = al_array_at(arr, i), 1));)
#define al_array_foreach_ptr(arr, i, item) \
- for (u32 i = 0; (i < (arr).size && (item = &al_array_at(arr, i), 1)); i++)
+ for (u32 i = 0; (i < (arr).size && (item = al_array_offset(arr, i), 1)); i++)
#define al_array_foreach_ptr_rev(arr, i, item) \
- for (u32 i = (arr).size; (i-- > 0 && (item = &al_array_at(arr, i), 1));)
+ for (u32 i = (arr).size; (i-- > 0 && (item = al_array_offset(arr, i), 1));)
#define al_array_remove_at_iter(arr, i) \
AL_MACRO_WRAP \
diff --git a/tests/lib.c b/tests/lib.c
index 64f886d..0923cf1 100644
--- a/tests/lib.c
+++ b/tests/lib.c
@@ -1,6 +1,12 @@
+#include <al/array.h>
#include <al/test.h>
+#include <al/lib.h>
#include <al/random.h>
+struct test_t {
+ u32 d;
+};
+
static bool lib_test_add_wrap(void)
{
AL_TEST_START("lib_add_wrap");
@@ -30,6 +36,39 @@ static bool lib_test_add_wrap(void)
AL_TEST_END();
}
+static bool lib_test_offset_vs_at_and_ref(void)
+{
+ AL_TEST_START("lib_offset_vs_at_and_ref");
+
+ array(struct test_t *) ar;
+ al_array_init(ar);
+
+ for (u32 i = 0; i < 10; i++) {
+ if (i == 4) {
+ al_array_push(ar, NULL);
+ } else {
+ al_array_push(ar, al_alloc_object(struct test_t));
+ }
+ }
+
+ AL_TEST_EQ(&al_array_at(ar, 2), al_array_offset(ar, 2), ptr);
+ AL_TEST_EQ(&al_array_at(ar, 3), al_array_offset(ar, 3), ptr);
+ AL_TEST_NEQ(*&al_array_at(ar, 3), NULL, ptr);
+ AL_TEST_EQ(&al_array_at(ar, 4), al_array_offset(ar, 4), ptr);
+ AL_TEST_EQ(*&al_array_at(ar, 4), *al_array_offset(ar, 4), ptr);
+ AL_TEST_NEQ(*&al_array_at(ar, 4), *al_array_offset(ar, 2), ptr);
+ AL_TEST_EQ(*&al_array_at(ar, 4), NULL, ptr);
+ AL_TEST_EQ(&al_array_at(ar, 5), al_array_offset(ar, 5), ptr);
+
+ for (u32 i = 0; i < 10; i++) {
+ if (i != 4) {
+ al_free(al_array_at(ar, i));
+ }
+ }
+
+ AL_TEST_END();
+}
+
/*
static bool lib_test_add_wrap_atomic(void)
{
@@ -63,6 +102,7 @@ bool lib_tests_run(void)
AL_TEST_START_GROUP("lib");
AL_TEST_RUN(lib_test_add_wrap);
+ AL_TEST_RUN(lib_test_offset_vs_at_and_ref);
//AL_TEST_RUN(lib_test_add_wrap_atomic);
AL_TEST_END_GROUP();