#ifndef KIT_STRING_BUILDER_H #define KIT_STRING_BUILDER_H #include "status.h" #include "string_ref.h" #include "dynamic_array.h" #include #ifdef __cplusplus extern "C" { #endif typedef KIT_DA(char) kit_str_builder_t; #ifdef __GNUC__ # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wunused-function" # pragma GCC diagnostic ignored "-Wunknown-pragmas" # pragma GCC push_options # pragma GCC optimize("O3") #endif static kit_str_builder_t kit_str_build(kit_str_t s, kit_allocator_t *alloc) { assert(s.size >= 0 && (s.size == 0 || s.values != NULL)); kit_str_builder_t builder; memset(&builder, 0, sizeof builder); if (s.size < 0 || (s.size != 0 && s.values == NULL)) return builder; KIT_DA_INIT(builder, s.size, alloc); assert(builder.size == s.size); if (builder.size == s.size) memcpy(builder.values, s.values, s.size); return builder; } static kit_str_builder_t kit_substr_build(kit_str_t s, i64 index, i64 size, kit_allocator_t *alloc) { assert(index + size <= s.size); if (index + size > s.size) { kit_str_builder_t builder; memset(&builder, 0, sizeof builder); return builder; } return kit_str_build(kit_str(size, s.values + index), alloc); } static s32 kit_str_append(kit_str_builder_t *a, kit_str_t b) { assert(a != NULL); if (a == NULL) return KIT_ERROR_INVALID_ARGUMENT; if (b.size <= 0) return KIT_OK; i64 n = a->size; KIT_DA_RESIZE(*a, n + b.size); if (a->size != n + b.size) return KIT_ERROR_BAD_ALLOC; memcpy(a->values + n, b.values, b.size); return KIT_OK; } static s32 kit_str_insert(kit_str_builder_t *a, i64 index, kit_str_t b) { assert(a != NULL && index >= 0 && index <= a->size); if (a == NULL || index < 0 || index > a->size) return KIT_ERROR_INVALID_ARGUMENT; if (b.size <= 0) return KIT_OK; i64 n = a->size; KIT_DA_RESIZE(*a, n + b.size); if (a->size != n + b.size) return KIT_ERROR_BAD_ALLOC; if (index < n) memmove(a->values + (index + b.size), a->values + index, n - index); memcpy(a->values + index, b.values, b.size); return KIT_OK; } static s32 kit_str_erase(kit_str_builder_t *a, i64 index, i64 size) { assert(a != NULL && index >= 0 && size >= 0 && index + size <= a->size); if (a == NULL || index < 0 || size < 0 || index + size > a->size) return KIT_ERROR_INVALID_ARGUMENT; if (size <= 0) return KIT_OK; if (index + size < a->size) memmove(a->values + index, a->values + (index + size), a->size - index - size); KIT_DA_RESIZE(*a, a->size - size); return KIT_OK; } #ifdef __GNUC__ # pragma GCC pop_options # pragma GCC diagnostic pop #endif #ifdef __cplusplus } #endif #define str_builder_t kit_str_builder_t #define str_build kit_str_build #define substr_build kit_substr_build #define str_append kit_str_append #define str_insert kit_str_insert #define str_erase kit_str_erase #endif