From df9d1c9c10d70045243670edfaddd8c627233dc6 Mon Sep 17 00:00:00 2001 From: jun <83899451+zeichensystem@users.noreply.github.com> Date: Thu, 30 Jan 2025 16:10:10 +0100 Subject: [PATCH] Add iter index functions --- src/guf_dbuf.h | 92 ++++++++++++++++++++++++++++++++++++++++++-------- src/guf_test.c | 14 +++++--- 2 files changed, 87 insertions(+), 19 deletions(-) diff --git a/src/guf_dbuf.h b/src/guf_dbuf.h index 8e2b0b2..ae91ba6 100644 --- a/src/guf_dbuf.h +++ b/src/guf_dbuf.h @@ -3,7 +3,7 @@ #include "guf_common.h" #include "guf_assert.h" #include "guf_alloc.h" - #define GUF_DBUF_FOREACH(DBUF, ELEM_TYPE, ELEM_PTR_NAME) for (ELEM_TYPE *ELEM_PTR_NAME = (DBUF).data, *end = (DBUF).data ? (DBUF).data + (DBUF).size : NULL; ELEM_PTR_NAME != end; ++ELEM_PTR_NAME) + #define GUF_DBUF_FOREACH(DBUF, ELEM_TYPE, ELEM_PTR_NAME) for (ELEM_TYPE *ELEM_PTR_NAME = (DBUF).data, *guf_foreach_end = (DBUF).data ? (DBUF).data + (DBUF).size : NULL; ELEM_PTR_NAME != guf_foreach_end; ++ELEM_PTR_NAME) #endif /* @@ -124,11 +124,14 @@ GUF_FN_KEYWORDS GUF_CAT(GUF_CNT_NAME, _iter) GUF_CAT(GUF_CNT_NAME, _end)(const G GUF_FN_KEYWORDS GUF_CAT(GUF_CNT_NAME, _iter) GUF_CAT(GUF_CNT_NAME, _rbegin)(const GUF_CNT_NAME* dbuf); GUF_FN_KEYWORDS GUF_CAT(GUF_CNT_NAME, _iter) GUF_CAT(GUF_CNT_NAME, _rend)(const GUF_CNT_NAME* dbuf); GUF_FN_KEYWORDS GUF_CAT(GUF_CNT_NAME, _iter) GUF_CAT(GUF_CNT_NAME, _iter_next)(const GUF_CNT_NAME *dbuf, GUF_CAT(GUF_CNT_NAME, _iter) it, ptrdiff_t step); +GUF_FN_KEYWORDS GUF_CAT(GUF_CNT_NAME, _iter) GUF_CAT(GUF_CNT_NAME, _iter_at_idx)(const GUF_CNT_NAME* dbuf, ptrdiff_t idx); +GUF_FN_KEYWORDS GUF_CAT(GUF_CNT_NAME, _iter) GUF_CAT(GUF_CNT_NAME, _reverse_iter_at_idx)(const GUF_CNT_NAME* dbuf, ptrdiff_t idx); +GUF_FN_KEYWORDS ptrdiff_t GUF_CAT(GUF_CNT_NAME, _iter_to_idx)(const GUF_CNT_NAME* dbuf, GUF_CAT(GUF_CNT_NAME, _iter) it); #if defined(GUF_T_IS_INTEGRAL_TYPE) || defined(GUF_T_EQ) GUF_FN_KEYWORDS GUF_CAT(GUF_CNT_NAME, _iter) GUF_CAT(GUF_CNT_NAME, _find)(GUF_CNT_NAME *dbuf, GUF_CAT(GUF_CNT_NAME, _iter) begin, GUF_CAT(GUF_CNT_NAME, _iter) end, const GUF_T *needle); GUF_FN_KEYWORDS GUF_CAT(GUF_CNT_NAME, _iter) GUF_CAT(GUF_CNT_NAME, _find_val)(GUF_CNT_NAME *dbuf, GUF_CAT(GUF_CNT_NAME, _iter) begin, GUF_CAT(GUF_CNT_NAME, _iter) end, GUF_T needle_val); -GUF_FN_KEYWORDS GUF_CAT(GUF_CNT_NAME, _iter) GUF_CAT(GUF_CNT_NAME, _find_if)(GUF_CNT_NAME *dbuf, GUF_CAT(GUF_CNT_NAME, _iter) *begin, GUF_CAT(GUF_CNT_NAME, _iter) *end, bool (*predicate)(const GUF_T *)); +GUF_FN_KEYWORDS GUF_CAT(GUF_CNT_NAME, _iter) GUF_CAT(GUF_CNT_NAME, _find_if)(GUF_CNT_NAME *dbuf, GUF_CAT(GUF_CNT_NAME, _iter) begin, GUF_CAT(GUF_CNT_NAME, _iter) end, bool (*predicate)(const GUF_T *)); #endif #if defined(GUF_IMPL) || defined(GUF_IMPL_STATIC) @@ -756,6 +759,8 @@ GUF_FN_KEYWORDS void GUF_CAT(GUF_CNT_NAME, _try_shrink_to_fit)(GUF_CNT_NAME *dbu } +/* Iterator functions */ + GUF_FN_KEYWORDS GUF_CAT(GUF_CNT_NAME, _iter) GUF_CAT(GUF_CNT_NAME, _begin)(const GUF_CNT_NAME* dbuf) { GUF_ASSERT_RELEASE(GUF_CAT(GUF_CNT_NAME, _valid)(dbuf)); @@ -792,6 +797,47 @@ GUF_FN_KEYWORDS GUF_CAT(GUF_CNT_NAME, _iter) GUF_CAT(GUF_CNT_NAME, _rend)(const }; } +GUF_FN_KEYWORDS GUF_CAT(GUF_CNT_NAME, _iter) GUF_CAT(GUF_CNT_NAME, _iter_at_idx)(const GUF_CNT_NAME* dbuf, ptrdiff_t idx) +{ + GUF_ASSERT(GUF_CAT(GUF_CNT_NAME, _valid)(dbuf)); + + GUF_CAT(GUF_CNT_NAME, _iter) it; + it.reverse = false; + if (idx < 0 || idx >= dbuf->size || !dbuf->data) { + it.ptr = GUF_CAT(GUF_CNT_NAME, _end)(dbuf).ptr; + } else { + it.ptr = dbuf->data + idx; + } + return it; +} + +GUF_FN_KEYWORDS GUF_CAT(GUF_CNT_NAME, _iter) GUF_CAT(GUF_CNT_NAME, _reverse_iter_at_idx)(const GUF_CNT_NAME* dbuf, ptrdiff_t idx) +{ + GUF_CAT(GUF_CNT_NAME, _iter) it = GUF_CAT(GUF_CNT_NAME, _iter_at_idx)(dbuf, idx); + it.reverse = true; + return it; +} + +static const ptrdiff_t GUF_CAT(GUF_CNT_NAME, _npos) = -1; + +GUF_FN_KEYWORDS ptrdiff_t GUF_CAT(GUF_CNT_NAME, _iter_to_idx)(const GUF_CNT_NAME* dbuf, GUF_CAT(GUF_CNT_NAME, _iter) it) +{ + GUF_ASSERT(GUF_CAT(GUF_CNT_NAME, _valid)(dbuf)); + + GUF_CAT(GUF_CNT_NAME, _iter) begin = GUF_CAT(GUF_CNT_NAME, _begin)(dbuf); + GUF_CAT(GUF_CNT_NAME, _iter) end = GUF_CAT(GUF_CNT_NAME, _end)(dbuf); + + if (it.ptr == NULL || begin.ptr == NULL || end.ptr == NULL || it.ptr < begin.ptr || it.ptr > end.ptr || !dbuf->data) { + return GUF_CAT(GUF_CNT_NAME, _npos); + } else if (it.ptr == end.ptr) { + return it.reverse ? -1 : dbuf->size; + } else { + ptrdiff_t idx = it.ptr - begin.ptr; + GUF_ASSERT(idx >= 0 && idx <= dbuf->size); + return idx; + } +} + GUF_FN_KEYWORDS GUF_CAT(GUF_CNT_NAME, _iter) GUF_CAT(GUF_CNT_NAME, _iter_next)(const GUF_CNT_NAME *dbuf, GUF_CAT(GUF_CNT_NAME, _iter) it, ptrdiff_t step) { GUF_ASSERT(GUF_CAT(GUF_CNT_NAME, _valid)(dbuf)); @@ -816,18 +862,14 @@ GUF_FN_KEYWORDS GUF_CAT(GUF_CNT_NAME, _iter) GUF_CAT(GUF_CNT_NAME, _iter_next)(c } else if (it.ptr == end_ptr && !it.reverse) { // Handle end() it_idx = dbuf->size + step; } else { - GUF_ASSERT_RELEASE(it.ptr >= dbuf->data && it.ptr < end_ptr && (ptrdiff_t)it.ptr - (ptrdiff_t)dbuf->data >= 0) - it_idx = (ptrdiff_t)(it.ptr - dbuf->data) + step; // TODO: is this legal? + GUF_ASSERT_RELEASE(it.ptr >= dbuf->data && it.ptr < end_ptr) + it_idx = (ptrdiff_t)(it.ptr - dbuf->data) + step; } - const ptrdiff_t len = end_ptr && dbuf->data ? end_ptr - dbuf->data : 0; + const ptrdiff_t len = (end_ptr && dbuf->data) ? end_ptr - dbuf->data : 0; GUF_ASSERT_RELEASE(len >= 0); - if (len == 0) { - it.ptr = end_ptr; - } else if (it_idx >= len) { - it.ptr = end_ptr; - } else if (it_idx < 0) { + if (len == 0 || it_idx >= len || it_idx < 0) { it.ptr = end_ptr; } else { GUF_ASSERT(dbuf->data && it.ptr); @@ -842,8 +884,20 @@ GUF_FN_KEYWORDS GUF_CAT(GUF_CNT_NAME, _iter) GUF_CAT(GUF_CNT_NAME, _find)(GUF_CN { GUF_ASSERT_RELEASE(GUF_CAT(GUF_CNT_NAME, _valid)(dbuf)); GUF_ASSERT_RELEASE(needle); + GUF_CAT(GUF_CNT_NAME, _iter) dbuf_end = GUF_CAT(GUF_CNT_NAME, _end)(dbuf); + dbuf_end.reverse = begin.reverse; - for (GUF_CAT(GUF_CNT_NAME, _iter) it = begin; it.ptr != end.ptr; it = GUF_CAT(GUF_CNT_NAME, _iter_next)(dbuf, it, 1)) { + ptrdiff_t begin_idx = GUF_CAT(GUF_CNT_NAME, _iter_to_idx)(dbuf, begin); + ptrdiff_t end_idx = GUF_CAT(GUF_CNT_NAME, _iter_to_idx)(dbuf, end); + if (!begin.ptr || !end.ptr || !dbuf->data || begin.ptr == dbuf_end.ptr) { + return dbuf_end; + } else if (!begin.reverse && begin_idx >= end_idx) { + return dbuf_end; + } else if (begin.reverse && begin_idx <= end_idx) { + return dbuf_end; + } + + for (GUF_CAT(GUF_CNT_NAME, _iter) it = begin; it.ptr != end.ptr && it.ptr != dbuf_end.ptr; it = GUF_CAT(GUF_CNT_NAME, _iter_next)(dbuf, it, 1)) { #ifdef GUF_T_EQ if (GUF_T_EQ(it.ptr, needle)) { return it; @@ -862,12 +916,22 @@ GUF_FN_KEYWORDS GUF_CAT(GUF_CNT_NAME, _iter) GUF_CAT(GUF_CNT_NAME, _find_val)(GU return GUF_CAT(GUF_CNT_NAME, _find)(dbuf, begin, end, &needle_val); } -GUF_FN_KEYWORDS GUF_CAT(GUF_CNT_NAME, _iter) GUF_CAT(GUF_CNT_NAME, _find_if)(GUF_CNT_NAME *dbuf, GUF_CAT(GUF_CNT_NAME, _iter) *begin, GUF_CAT(GUF_CNT_NAME, _iter) *end, bool (*predicate)(const GUF_T *)) +GUF_FN_KEYWORDS GUF_CAT(GUF_CNT_NAME, _iter) GUF_CAT(GUF_CNT_NAME, _find_if)(GUF_CNT_NAME *dbuf, GUF_CAT(GUF_CNT_NAME, _iter) begin, GUF_CAT(GUF_CNT_NAME, _iter) end, bool (*predicate)(const GUF_T *)) { GUF_ASSERT_RELEASE(GUF_CAT(GUF_CNT_NAME, _valid)(dbuf)); - GUF_ASSERT_RELEASE(begin && end && predicate); + GUF_ASSERT_RELEASE(predicate); - for (GUF_CAT(GUF_CNT_NAME, _iter) it = *begin; it.ptr != end->ptr; GUF_CAT(GUF_CNT_NAME, _iter_next)(dbuf, it, 1)) { + GUF_CAT(GUF_CNT_NAME, _iter) dbuf_end = GUF_CAT(GUF_CNT_NAME, _end)(dbuf); + dbuf_end.reverse = begin.reverse; + if (!begin.ptr || !end.ptr || !dbuf->data) { + return dbuf_end; + } else if (!begin.reverse && begin.ptr >= end.ptr) { + return dbuf_end; + } else if (begin.reverse && begin.ptr <= end.ptr) { + return dbuf_end; + } + + for (GUF_CAT(GUF_CNT_NAME, _iter) it = begin; it.ptr != end.ptr; GUF_CAT(GUF_CNT_NAME, _iter_next)(dbuf, it, 1)) { if (predicate(it.ptr)) { return it; } diff --git a/src/guf_test.c b/src/guf_test.c index b7d1800..41dca98 100644 --- a/src/guf_test.c +++ b/src/guf_test.c @@ -72,12 +72,16 @@ int main(void) dbuf_heap_cstr_push(&strings, &move_me, GUF_CPY_MOVE); GUF_ASSERT_RELEASE(move_me == NULL); - char *findme = "Baz 3"; + dbuf_heap_cstr_push_val_cpy(&strings, "Boz 4"); - dbuf_heap_cstr_iter fnd_it = dbuf_heap_cstr_find(&strings, dbuf_heap_cstr_begin(&strings), dbuf_heap_cstr_end(&strings), &findme); + char *findme = "Baz 3"; + dbuf_heap_cstr_iter beg = dbuf_heap_cstr_rbegin(&strings); + dbuf_heap_cstr_iter end = dbuf_heap_cstr_rend(&strings); + dbuf_heap_cstr_iter fnd_it = dbuf_heap_cstr_find(&strings, beg, end, &findme); if (fnd_it.ptr != dbuf_heap_cstr_end(&strings).ptr) { - guf_cstr_heap_free(fnd_it.ptr, NULL); - *fnd_it.ptr = strdup("Found!"); + printf("%s found in range [%td, %td) at idx %td\n", findme, dbuf_heap_cstr_iter_to_idx(&strings, beg), dbuf_heap_cstr_iter_to_idx(&strings, end), dbuf_heap_cstr_iter_to_idx(&strings, fnd_it)); + } else { + printf("%s not found in range [%td, %td) at idx %td\n", findme, dbuf_heap_cstr_iter_to_idx(&strings, beg), dbuf_heap_cstr_iter_to_idx(&strings, end), dbuf_heap_cstr_iter_to_idx(&strings, fnd_it)); } GUF_CNT_FOREACH(&strings, dbuf_heap_cstr, it) { @@ -140,7 +144,7 @@ int main(void) } for (dbuf_int_iter it = dbuf_int_rbegin(&integers); it.ptr != dbuf_int_rend(&integers).ptr; it = dbuf_int_iter_next(&integers, it, 2)) { - printf("every other reverse: %d\n", *it.ptr); + printf("every other reverse: %d (idx %td)\n", *it.ptr, dbuf_int_iter_to_idx(&integers, it)); } dbuf_int_free(&integers, NULL);