nstr: avoid double allocation

String contents are stored immediately after the
struct _neo_nstr in memory now.
This commit is contained in:
anna 2021-07-22 13:42:14 +02:00
parent c797540dbc
commit 3040b09669
Signed by: fef
GPG key ID: EC22E476DC2D3D84
2 changed files with 17 additions and 18 deletions

View file

@ -21,7 +21,7 @@ struct _neo_nstr_init_info {
*
* The string will be initialized before `main` is called.
*
* @param name: Name of the `string *` variable to be declared
* @param name: Name of the `nstr_t *` variable to be declared
* @param content: A `const char *` with the contents of the string
*/
#define NSTR_DEFINE(name, content) \
@ -166,8 +166,8 @@ int nstrcmp(const nstr_t *s1, const nstr_t *s2, error *err);
* If either of the two string are `nil` or acquiring a lock on them fails,
* an error is yeeted.
*
* @param s1: First `string *`
* @param s2: Second `string *`
* @param s1: First `nstr_t *`
* @param s2: Second `nstr_t *`
* @param err: Error pointer
* @returns Whether the two strings are equal, unless an error occurred
*/
@ -190,17 +190,17 @@ nstr_t *leftpad(const nstr_t *s, usize length, nchar fill, error *err);
/**
* Iterate over each character in a string.
*
* @param nstr: `string *` to iterate over
* @param nchr: `nchar *` to store the current character in
* @param cursor: `nchar *` to store the current character in
* @param nstr: `nstr_t *` to iterate over
* @param err: Error pointer; the loop will terminate early if an uncaught
* error occurred
*/
#define nstr_foreach_nchr(nstr, nchr, err) \
#define nstr_foreach(cursor, nstr, err) \
for (const char *__pos = \
(nstr)->_data + utf8_to_nchr(nchr, (nstr)->_data, err); \
*__pos != '\0' && (err) != nil && \
(err)->_number + 1 < 2; \
__pos += utf8_to_nchr(nchr, __pos, err))
(nstr)->_data + utf8_to_nchr(cursor, (nstr)->_data, err); \
/* errput sets the error number to 0xffffffff, thus number + 1 */ \
*__pos != '\0' && (err) != nil && (err)->_number + 1 < 2; \
__pos += utf8_to_nchr(cursor, __pos, err))
/*
* This file is part of libneo.

View file

@ -16,7 +16,6 @@
static void nstr_destroy(nstr_t *str)
{
nfree(str->_data);
nfree(str);
}
@ -27,11 +26,6 @@ static nstr_t *nstr_unsafe(const char *restrict s, usize size_without_nul, error
return nil;
}
nstr_t *str = nalloc(sizeof(*str), err);
catch(err) {
return nil;
}
/*
* neo strings are terminated by four NUL characters rather than just
* one. We do this to make sure nothing bad can happen if some stupid
@ -45,12 +39,17 @@ static nstr_t *nstr_unsafe(const char *restrict s, usize size_without_nul, error
* Yeah, this is definitely never gonna break my legs.
*/
str->_data = nalloc(size_without_nul + 4, err);
nstr_t *str = nalloc(sizeof(*str) + size_without_nul + 4, err);
catch(err) {
nfree(str);
return nil;
}
/*
* To improve locality and lower fragmentation, the actual data is
* stored immediately after the string itself. This also saves us an
* additional memory allocation.
*/
str->_data = (char *)str + sizeof(*str);
str->_len = len;
str->_size = size_without_nul + 4;
nref_init(str, nstr_destroy);