Add iter index functions
This commit is contained in:
parent
67b5759e03
commit
df9d1c9c10
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user