ds 0.10.0
A C library to safely yet efficiently work with UTF-8–encoded, growable dynamic strings.
ds_string_t Struct Reference

A growable string. Will be UTF-8–encoded in the future. More...

#include <string.h>

Private Attributes

ds_cstr_mut_t buf
 Points to an internal buffer String uses to store its data. More...
 
ds_usize_t len
 The number of bytes currently stored in the buffer. More...
 
ds_usize_t cap
 The size of the buffer in bytes. More...
 

Detailed Description

A growable string. Will be UTF-8–encoded in the future.

The String type is the most common string type that has ownership over the contents of the string. It has a close relationship with its standard counterpart, the primitive C-string.

Examples

You can create a String from a literal string with ds_string_from:

DS_RESULT_PROPAGATE_ERR (ds_string_from (&hello, "Hello, world!", 13));
#define DS_RESULT_PROPAGATE_ERR(result)
Propagates (instantly, possibly early, returns) evaluated result to the calling function only if it i...
Definition: result.h:140
ds_result_t ds_string_from(ds_string_t *self, ds_cstr_t string, ds_usize_t string_len)
Converts a C-string into a String.
Definition: string.c:342
ds_result_t ds_string_drop(ds_string_t *self)
Disposes of a value.
Definition: string.c:392
A growable string. Will be UTF-8–encoded in the future.
Definition: string.h:163

You can append a char to a String with the ds_string_push method, and append a C-string with the ds_string_push_str method:

DS_RESULT_PROPAGATE_ERR (ds_string_from (&hello, "Hello,", 6));
ds_result_t ds_string_push(ds_string_t *self, ds_char_t chr)
Appends chr to the end of self.
Definition: string.c:176
ds_result_t ds_string_push_str(ds_string_t *self, ds_cstr_t string, ds_usize_t string_len)
Appends string onto the end of self.
Definition: string.c:125

Representation

A String is made up of three components: a pointer to some bytes, a length, and a capacity. The pointer points to an internal buffer String uses to store its data. The length is the number of bytes currently stored in the buffer, and the capacity is the size of the buffer in bytes. As such, the length will always be less than or equal to the capacity.

This buffer is always stored on the heap.

You can look at these with the ds_string_as_ptr, ds_string_len, and ds_string_capacity methods:

DS_RESULT_PROPAGATE_ERR (ds_string_from (&story, "Once upon a time...",
19));
ds_cstr_t const ptr = ds_string_as_ptr (story);
ds_usize_t const len = ds_string_len (story);
ds_usize_t const capacity = ds_string_capacity (story);
// story has nineteen bytes
assert (19 == len);
assert (len <= capacity);
// We can re-build a String out of ptr, len, and capacity. This is all
// unsafe because we are responsible for making sure the components are
// valid:
ds_string_t const s = ds_string_from_raw_parts (ptr, len, capacity);
assert (ds_string_eq (s, story));
ds_char_t const * ds_cstr_t
An immutable C-string type.
Definition: cstr.h:28
ds_cstr_t ds_string_as_ptr(ds_string_t self)
Converts self to a raw pointer.
Definition: string.c:380
bool ds_string_eq(ds_string_t self, ds_string_t other)
This method tests for self and other values to be equal.
Definition: string.c:352
ds_string_t ds_string_from_raw_parts(ds_cstr_mut_t buf, ds_usize_t length, ds_usize_t capacity)
Creates a new String from a length, capacity, and buf pointer.
Definition: string.c:118
ds_usize_t ds_string_capacity(ds_string_t self)
Returns self's capacity, in bytes.
Definition: string.c:135
ds_usize_t ds_string_len(ds_string_t self)
Returns the length of self, in bytes, not graphemes. In other words, it might not be what a human con...
Definition: string.c:281
ds_usize_t len
The number of bytes currently stored in the buffer.
Definition: string.h:175
size_t ds_usize_t
The pointer-sized unsigned integer type.
Definition: usize.h:26

If a String has enough capacity, adding elements to it will not re-allocate. For example, consider this program:

printf ("%" DS_PRI_USIZE "\n", ds_string_capacity (s));
for (ds_usize_t i = DS_USIZE_MIN; i < 5; i++)
{
printf ("%" DS_PRI_USIZE "\n", ds_string_capacity (s));
}
ds_string_t ds_string_new(void)
Creates a new empty String.
Definition: string.c:85
#define DS_USIZE_MIN
The smallest value that can be represented by usize.
Definition: usize.h:49
#define DS_PRI_USIZE
usize notation. Can be used in printf to format and write usize values.
Definition: usize.h:91

This may output the following:

0
8
16
16
32
32

At first, we have no memory allocated at all, but as we append to the string, it increases its capacity appropriately. If we instead use the ds_string_with_capacity method to allocate the correct capacity initially:

printf ("%" DS_PRI_USIZE "\n", ds_string_capacity (s));
for (ds_usize_t i = DS_USIZE_MIN; i < 5; i++)
{
printf ("%" DS_PRI_USIZE "\n", ds_string_capacity (s));
}
ds_result_t ds_string_with_capacity(ds_string_t *self, ds_usize_t capacity)
Creates a new empty String with at least the specified capacity.
Definition: string.c:91

We may end up with a different output:

25
25
25
25
25
25

Here, there's no need to allocate more memory inside the loop.

Definition at line 162 of file string.h.

Field Documentation

◆ buf

ds_cstr_mut_t ds_string_t::buf
private

Points to an internal buffer String uses to store its data.

This buffer is always stored on the heap.

Definition at line 169 of file string.h.

◆ cap

ds_usize_t ds_string_t::cap
private

The size of the buffer in bytes.

The length will always be less than or equal to the capacity.

Definition at line 181 of file string.h.

◆ len

ds_usize_t ds_string_t::len
private

The number of bytes currently stored in the buffer.

The length will always be less than or equal to the capacity.

Definition at line 175 of file string.h.


The documentation for this struct was generated from the following file: