diff --git a/ev_str.h b/ev_str.h index 70d798a..29a557c 100644 --- a/ev_str.h +++ b/ev_str.h @@ -40,7 +40,14 @@ /*! * \brief Rate at which an evstring grows whenever a resize is needed */ -#define EV_STR_GROWTH_FACTOR 2 +#define EV_STR_GROWTH_FACTOR 3 / 2 +#endif + +#ifndef EV_STR_MIN_CAPACITY +/*! + * \brief Rate at which an evstring grows whenever a resize is needed + */ +#define EV_STR_MIN_CAPACITY 4 #endif typedef char *evstring; @@ -120,6 +127,11 @@ evstring_cmp( const evstring s1, const evstring s2); +EV_STR_API i32 +evstring_view_cmp( + const evstring_view v1, + const evstring_view v2); + EV_STR_API evstring_error_t evstring_pushChar( evstring *s, @@ -213,6 +225,15 @@ TYPEDATA_GEN(evstring, FREE(Default) ); +DEFINE_EQUAL_FUNCTION(evstring_view, Default) +{ + return evstring_view_cmp(*self, *other) == 0; +} + +TYPEDATA_GEN(evstring_view, + EQUAL(Default), +); + #if defined(EV_STR_IMPLEMENTATION) @@ -380,7 +401,8 @@ evstring_grow( evstring *s) { evstr_asserttype(*s); - return evstring_setCapacity(s, META(*s)->capacity * EV_STR_GROWTH_FACTOR); + u64 new_cap = max(EV_STR_MIN_CAPACITY, META(*s)->capacity * EV_STR_GROWTH_FACTOR); + return evstring_setCapacity(s, new_cap); } evstring_error_t @@ -431,6 +453,19 @@ evstring_cmp( return memcmp(s1, s2, len1); } +i32 +evstring_view_cmp( + const evstring_view v1, + const evstring_view v2) +{ + evstr_asserttype(v1.data); + evstr_asserttype(v2.data); + if(v1.len != v2.len) { + return 1; + } + return memcmp(v1.data+v1.offset, v2.data+v2.offset, v1.len); +} + evstring_error_t evstring_push_impl( @@ -538,8 +573,6 @@ __evstring_findFirst_impl( evstring_view text, evstring_view query) { - u64 found_progress = 0; - evstring_view result = { .data = text.data, .len = 0, @@ -549,17 +582,17 @@ __evstring_findFirst_impl( if(query.len == 0) return result; - for(u64 i = text.offset; i < text.offset + text.len; i++) { - if(text.data[i] == query.data[query.offset + found_progress]) - found_progress++; - else - found_progress = 0; - if(found_progress == query.len) { - result.offset = (i+1) - query.len; - result.len = query.len; - break; - } + for(u64 l = text.offset; l <= text.offset + text.len - query.len; l++) + { + evstring_view curr_view = { + .data = text.data, + .len = query.len, + .offset = l + }; + if(EV_EQUAL(evstring_view)(&curr_view, &query)) + return curr_view; } + return result; } diff --git a/ev_vec.h b/ev_vec.h index 0f750c2..376fcde 100644 --- a/ev_vec.h +++ b/ev_vec.h @@ -34,6 +34,14 @@ #define EV_VEC_GROWTH_RATE 3 / 2 #endif + +#ifndef EV_VEC_MIN_CAPACITY +/*! + * \brief Minimum capacity used by vector when growing + */ +#define EV_VEC_MIN_CAPACITY 4 +#endif + #if EV_CC_MSVC # define __EV_VEC_EMPTY_ARRAY { 0 } #else @@ -304,6 +312,10 @@ ev_vec_dup( * vector, then this function is used. Otherwise, memcpy is used with a length * of `vec_meta.elemsize` * + * \warning Having a free_fn defined for the elemtype but no copy_fn could have some + * unwanted side effects as the free function will be called on the popped element + * after copying it to `out` + * * \param vec_p Reference to the vector object * \param out A pointer to the memory block at which the popped element will be * copied. If NULL is passed, then the element is destructed. Otherwise, the @@ -719,6 +731,9 @@ ev_vec_setlen( ev_vec_t* v = (ev_vec_t*)vec_p; __ev_vec_getmeta(*v) + while(metadata->length > len) + ev_vec_pop(vec_p, NULL); + while(len > metadata->capacity) { ev_vec_error_t grow_err = ev_vec_grow(v); if(grow_err) { @@ -747,6 +762,10 @@ ev_vec_setcapacity( return EV_VEC_ERR_NONE; } + if(metadata->length > cap) { + ev_vec_setlen(vec_p, cap); + } + void *buf = ((char *)(*v) - sizeof(struct ev_vec_meta_t)); void *tmp = realloc(buf, sizeof(struct ev_vec_meta_t) + (cap * metadata->typeData.size)); @@ -770,7 +789,8 @@ ev_vec_grow( { ev_vec_t* v = (ev_vec_t*)vec_p; __ev_vec_getmeta(*v) - return ev_vec_setcapacity(v, metadata->capacity * EV_VEC_GROWTH_RATE); + u64 new_cap = max(EV_VEC_MIN_CAPACITY, metadata->capacity * EV_VEC_GROWTH_RATE); + return ev_vec_setcapacity(v, new_cap); } #endif diff --git a/tests/ev_vec/reducecap_updatelen.c b/tests/ev_vec/reducecap_updatelen.c index f18808b..c280522 100644 --- a/tests/ev_vec/reducecap_updatelen.c +++ b/tests/ev_vec/reducecap_updatelen.c @@ -5,8 +5,6 @@ int main(void) { - assert(EV_VEC_GROWTH_RATE > 1); - ev_vec(i32) v = ev_vec_init(i32); assert(v != NULL);