ds 0.10.0
A C library to safely yet efficiently work with UTF-8–encoded, growable dynamic strings.
string.h
Go to the documentation of this file.
1#pragma once
2
3#ifndef DS_STRING_H
4#define DS_STRING_H 1
5
6//! @file ds/string.h
7//! @author Avinash Maddikonda (svasssakavi@gmail.com)
8//! @brief Declaration of the @ref ds_string_t "String" type, related constants
9//! and functions.
10//! @since 0.10.0
11//! @date 2023-08-31
12
13#include <stdalign.h>
14#include <stdbool.h>
15
16#include "ds/char.h"
17#include "ds/cstr.h"
18#include "ds/result.h"
19#include "ds/usize.h"
20
21#ifdef __cplusplus
22extern "C"
23{
24#endif /* __cplusplus */
25
26/// @internal
27/// @brief The recommended alignment to efficiently access fields in @ref
28/// ds_string_t "String".
29#define DS_STRING_ALIGNMENT 32
30
31 /// @brief A growable string. Will be UTF-8–encoded in the future.
32 ///
33 /// The @ref ds_string_t "String" type is the most common string type that
34 /// has ownership over the contents of the string. It has a close
35 /// relationship with its standard counterpart, the primitive C-string.
36 ///
37 /// ### Examples
38 ///
39 /// You can create a @ref ds_string_t "String" from a literal string with
40 /// @ref ds_string_from:
41 ///
42 /// ```c
43 /// ds_string_t hello;
44 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&hello, "Hello, world!", 13));
45 ///
46 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&hello));
47 /// ```
48 ///
49 /// You can append a @ref ds_char_t "char" to a @ref ds_string_t "String"
50 /// with the @ref ds_string_push method, and append a C-string with the @ref
51 /// ds_string_push_str method:
52 ///
53 /// ```c
54 /// ds_string_t hello;
55 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&hello, "Hello,", 6));
56 ///
57 /// DS_RESULT_PROPAGATE_ERR (ds_string_push (&hello, ' '));
58 /// DS_RESULT_PROPAGATE_ERR (ds_string_push_str (&hello, "world!", 6));
59 ///
60 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&hello));
61 /// ```
62 ///
63 /// ### Representation
64 ///
65 /// A @ref ds_string_t "String" is made up of three components: a @ref
66 /// ds_string_t::buf "pointer" to some bytes, a @ref ds_string_t::len
67 /// "length", and a @ref ds_string_t::cap "capacity". The pointer points to
68 /// an internal buffer @ref ds_string_t "String" uses to store its data. The
69 /// length is the number of bytes currently stored in the buffer, and the
70 /// capacity is the size of the buffer in bytes. As such, the length will
71 /// always be less than or equal to the capacity.
72 ///
73 /// This buffer is always stored on the heap.
74 ///
75 /// You can look at these with the @ref ds_string_as_ptr, @ref
76 /// ds_string_len, and @ref ds_string_capacity methods:
77 ///
78 /// ```c
79 /// ds_string_t story;
80 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&story, "Once upon a time...",
81 /// 19));
82 ///
83 /// ds_cstr_t const ptr = ds_string_as_ptr (story);
84 /// ds_usize_t const len = ds_string_len (story);
85 /// ds_usize_t const capacity = ds_string_capacity (story);
86 ///
87 /// // story has nineteen bytes
88 /// assert (19 == len);
89 /// assert (len <= capacity);
90 ///
91 /// // We can re-build a String out of ptr, len, and capacity. This is all
92 /// // unsafe because we are responsible for making sure the components are
93 /// // valid:
94 /// ds_string_t const s = ds_string_from_raw_parts (ptr, len, capacity);
95 ///
96 /// assert (ds_string_eq (s, story));
97 ///
98 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&s));
99 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&story));
100 /// ```
101 ///
102 /// If a @ref ds_string_t "String" has enough capacity, adding elements to it
103 /// will not re-allocate. For example, consider this program:
104 ///
105 /// ```c
106 /// ds_string_t s = ds_string_new ();
107 ///
108 /// printf ("%" DS_PRI_USIZE "\n", ds_string_capacity (s));
109 ///
110 /// for (ds_usize_t i = DS_USIZE_MIN; i < 5; i++)
111 /// {
112 /// DS_RESULT_PROPAGATE_ERR (ds_string_push_str (&s, "hello", 5));
113 /// printf ("%" DS_PRI_USIZE "\n", ds_string_capacity (s));
114 /// }
115 ///
116 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&s));
117 /// ```
118 ///
119 /// This may output the following:
120 ///
121 /// ```text
122 /// 0
123 /// 8
124 /// 16
125 /// 16
126 /// 32
127 /// 32
128 /// ```
129 ///
130 /// At first, we have no memory allocated at all, but as we append to the
131 /// string, it increases its capacity appropriately. If we instead use the
132 /// @ref ds_string_with_capacity method to allocate the correct capacity
133 /// initially:
134 ///
135 /// ```c
136 /// ds_string_t s;
137 /// DS_RESULT_PROPAGATE_ERR (ds_string_with_capacity (&s, 25));
138 ///
139 /// printf ("%" DS_PRI_USIZE "\n", ds_string_capacity (s));
140 ///
141 /// for (ds_usize_t i = DS_USIZE_MIN; i < 5; i++)
142 /// {
143 /// DS_RESULT_PROPAGATE_ERR (ds_string_push_str (&s, "hello", 5));
144 /// printf ("%" DS_PRI_USIZE "\n", ds_string_capacity (s));
145 /// }
146 ///
147 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&s));
148 /// ```
149 ///
150 /// We may end up with a different output:
151 ///
152 /// ```text
153 /// 25
154 /// 25
155 /// 25
156 /// 25
157 /// 25
158 /// 25
159 /// ```
160 ///
161 /// Here, there's no need to allocate more memory inside the loop.
163 {
164 /// @private
165 /// @brief Points to an internal buffer @ref ds_string_t "String" uses to
166 /// store its data.
167 ///
168 /// This buffer is always stored on the heap.
169 alignas (DS_STRING_ALIGNMENT) ds_cstr_mut_t buf;
170
171 /// @private
172 /// @brief The number of bytes currently stored in the buffer.
173 ///
174 /// The length will always be less than or equal to the capacity.
176
177 /// @private
178 /// @brief The size of the buffer in bytes.
179 ///
180 /// The length will always be less than or equal to the capacity.
182 };
183
184 typedef struct ds_string_t ds_string_t;
185
186 /// @brief Creates a new empty @ref ds_string_t "String".
187 ///
188 /// Given that the @ref ds_string_t "String" is empty, this will not allocate
189 /// any initial buffer. While that means that this initial operation is very
190 /// inexpensive, it may cause excessive allocation later when you add data.
191 /// If you have an idea of how much data the @ref ds_string_t "String" will
192 /// hold, consider the @ref ds_string_with_capacity method to prevent
193 /// excessive re-allocation.
194 ///
195 /// @return A new empty @ref ds_string_t "String".
196 ///
197 /// ### Examples
198 ///
199 /// Basic usage:
200 ///
201 /// ```c
202 /// ds_string_t const s = ds_string_new ();
203 ///
204 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&s));
205 /// ```
206 extern ds_string_t ds_string_new (void);
207
208 /// @brief Creates a new empty @ref ds_string_t "String" with at least the
209 /// specified @p capacity.
210 ///
211 /// @ref ds_string_t "Strings" have an internal buffer to hold their data.
212 /// The capacity is the length of that buffer, and can be queried with the
213 /// @ref ds_string_capacity method. This method creates an empty @ref
214 /// ds_string_t "String", but one with an initial buffer that can hold at
215 /// least @p capacity bytes. This is useful when you may be appending a bunch
216 /// of data to the @ref ds_string_t "String", reducing the number of
217 /// reallocations it needs to do.
218 ///
219 /// If the given capacity is `0`, no allocation will occur, and this method
220 /// is identical to the @ref ds_string_new method.
221 ///
222 /// @param[out] self Pointer to a new empty @ref ds_string_t "String" with at
223 /// least the specified @p capacity.
224 /// @param capacity The minimum number of bytes to allocate.
225 ///
226 /// @return @ref DS_RESULT_OK "Ok" on success.
227 /// @return @ref DS_RESULT_ERR_PTR_IS_NULL "Err(PtrIsNull)" if @p self is
228 /// `NULL`.
229 /// @return @ref DS_RESULT_ERR_MEM_ALLOC_FAILED "Err(MemAllocFailed)" if a
230 /// memory allocation fails.
231 ///
232 /// ### Examples
233 ///
234 /// Basic usage:
235 ///
236 /// ```c
237 /// ds_string_t s;
238 /// DS_RESULT_PROPAGATE_ERR (ds_string_with_capacity (&s, 10));
239 ///
240 /// // The String contains no chars, even though it has capacity for more
241 /// assert (ds_string_len (s) == 0);
242 ///
243 /// // These are all done without reallocating...
244 /// ds_usize_t const cap = ds_string_capacity (s);
245 /// for (ds_usize_t i = DS_USIZE_MIN; i < 10; i++)
246 /// {
247 /// DS_RESULT_PROPAGATE_ERR (ds_string_push (&s, 'a'));
248 /// }
249 ///
250 /// assert (ds_string_capacity (s) == cap);
251 ///
252 /// // ...but this may make the string reallocate
253 /// DS_RESULT_PROPAGATE_ERR (ds_string_push (&s, 'a'));
254 ///
255 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&s));
256 /// ```
258 ds_usize_t capacity);
259
260 /// @brief Decomposes @p self into its raw components.
261 ///
262 /// Retrieves the raw pointer to the underlying data, the length of the
263 /// string (in bytes), and the allocated capacity of the data (in bytes), and
264 /// stores them in memory locations pointed at by @p buf_ptr, @p len_ptr, and
265 /// @p cap_ptr respectively. These are the same arguments in the same order
266 /// as the arguments to @ref ds_string_from_raw_parts.
267 ///
268 /// After calling this function, the caller is responsible for the memory
269 /// previously managed by @p self. The only way to do this is to convert the
270 /// raw pointer, length, and capacity back into a @ref ds_string_t "String"
271 /// with the @ref ds_string_from_raw_parts function, and calling @ref
272 /// ds_string_drop to perform the cleanup.
273 ///
274 /// @param[out] self Pointer to the @ref ds_string_t "String" to decompose
275 /// into its raw components.
276 /// @param[out] buf_ptr Pointer to the raw pointer to the underlying data.
277 /// @param[out] len_ptr Pointer to the length of the string (in bytes).
278 /// @param[out] cap_ptr Pointer to the allocated capacity of the data (in
279 /// bytes).
280 ///
281 /// @return @ref DS_RESULT_OK "Ok" on success.
282 /// @return @ref DS_RESULT_ERR_PTR_IS_NULL "Err(PtrIsNull)" if @p self, @p
283 /// buf_ptr, @p len_ptr, or @p cap_ptr is `NULL`.
284 ///
285 /// ### Examples
286 ///
287 /// Basic usage:
288 ///
289 /// ```c
290 /// ds_string_t s;
291 /// ds_string_t hello;
292 ///
293 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&s, "hello", 5));
294 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&hello, "hello", 5));
295 ///
296 /// ds_cstr_mut_t ptr;
297 /// ds_usize_t len;
298 /// ds_usize_t cap;
299 /// DS_RESULT_PROPAGATE_ERR (ds_string_into_raw_parts (&s, &ptr, &len,
300 /// &cap));
301 ///
302 /// ds_string_t const rebuilt = ds_string_from_raw_parts (ptr, len, cap);
303 /// assert (ds_string_eq (rebuilt, hello));
304 ///
305 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&rebuilt));
306 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&hello));
307 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&s));
308 /// ```
310 ds_cstr_mut_t *buf_ptr,
311 ds_usize_t *len_ptr,
312 ds_usize_t *cap_ptr);
313
314 /// @brief Creates a new @ref ds_string_t "String" from a @p length, @p
315 /// capacity, and @p buf pointer.
316 ///
317 /// @warning This is highly unsafe, due to the number of invariants that
318 /// aren't checked:
319 ///
320 /// - The memory at @p buf needs to have been previously allocated by the
321 /// same allocator @ref ds_string_t "String" uses, with a required
322 /// alignment of exactly 1.
323 /// - @p length needs to be less than or equal to @p capacity.
324 /// - @p capacity needs to be the correct value.
325 /// - The first @p length bytes at @p buf need to be valid UTF-8.
326 ///
327 /// Violating these may cause problems like corrupting the allocator's
328 /// internal data structures. For example, it is normally **not** safe to
329 /// build a @ref ds_string_t "String" from a pointer to a C `char` array
330 /// containing UTF-8 _unless_ you are certain that array was originally
331 /// allocated by the same allocator @ref ds_string_t "String" uses.
332 ///
333 /// The ownership of @p buf is effectively transferred to the @ref
334 /// ds_string_t "String" which may then deallocate, reallocate or change the
335 /// contents of memory pointed to by the pointer at will. Ensure that nothing
336 /// else uses the pointer after calling this function.
337 ///
338 /// @param buf The pointer to the buffer.
339 /// @param length The length of the string (in bytes).
340 /// @param capacity The allocated capacity of the data (in bytes).
341 ///
342 /// @return A new @ref ds_string_t "String" from a @p length, @p capacity,
343 /// and @p buf pointer.
344 ///
345 /// ### Examples
346 ///
347 /// Basic usage:
348 ///
349 /// ```c
350 /// ds_string_t s;
351 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&s, "hello", 5));
352 ///
353 /// ds_cstr_t const ptr = ds_string_as_ptr (s);
354 /// ds_usize_t const len = ds_string_len (s);
355 /// ds_usize_t const capacity = ds_string_capacity (s);
356 ///
357 /// ds_string_t const hello = ds_string_from_raw_parts (ptr, len, capacity);
358 ///
359 /// assert (ds_string_eq (hello, s));
360 /// ```
362 ds_usize_t length,
363 ds_usize_t capacity);
364
365 /// @brief Appends @p string onto the end of @p self.
366 ///
367 /// @param[out] self Pointer to the @ref ds_string_t "String" to append @p
368 /// string onto the end of.
369 /// @param string A C-string slice to append to @p self.
370 /// @param string_len The length of @p string (in bytes).
371 ///
372 /// @return @ref DS_RESULT_OK "Ok" on success.
373 /// @return @ref DS_RESULT_ERR_PTR_IS_NULL "Err(PtrIsNull)" if @p self is
374 /// `NULL`.
375 /// @return @ref DS_RESULT_ERR_MEM_ALLOC_FAILED "Err(MemAllocFailed)" if a
376 /// memory allocation fails.
377 ///
378 /// ### Examples
379 ///
380 /// Basic usage:
381 ///
382 /// ```c
383 /// ds_string_t s;
384 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&s, "foo", 3));
385 ///
386 /// DS_RESULT_PROPAGATE_ERR (ds_string_push_str (&s, "bar", 3));
387 ///
388 /// ds_string_t foobar;
389 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&s, "foobar", 6));
390 /// assert (ds_string_eq (foobar, s));
391 ///
392 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&foobar));
393 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&s));
394 /// ```
396 ds_usize_t string_len);
397
398 /// @brief Returns @p self's capacity, in bytes.
399 /// @param self The @ref ds_string_t "String" to return the capacity, in
400 /// bytes, of.
401 /// @return @p self's capacity, in bytes.
402 ///
403 /// ### Examples
404 ///
405 /// Basic usage:
406 ///
407 /// ```c
408 /// ds_string_t s;
409 /// DS_RESULT_PROPAGATE_ERR (ds_string_with_capacity (&s, 10));
410 ///
411 /// assert (ds_string_capacity (s) >= 10);
412 ///
413 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&s));
414 /// ```
416
417 /// @brief Reserves capacity for at least @p additional bytes more than @p
418 /// self's current length. The allocator may reserve more space to
419 /// speculatively avoid frequent allocations. After calling @ref
420 /// ds_string_reserve, capacity will be greater than or equal to
421 /// `ds_string_len (self) + additional`. Does nothing if capacity is already
422 /// sufficient.
423 ///
424 /// @param[out] self Pointer to the @ref ds_string_t "String" to reserve
425 /// capacity for at least @p additional bytes more than its current length.
426 /// @param additional The minimum number of bytes more than @p self's current
427 /// length to allocate.
428 ///
429 /// @return @ref DS_RESULT_OK "Ok" on success.
430 /// @return @ref DS_RESULT_ERR_PTR_IS_NULL "Err(PtrIsNull)" if @p self is
431 /// `NULL`.
432 /// @return @ref DS_RESULT_ERR_OUT_OF_RANGE "Err(OutOfRange)" if the new
433 /// capacity overflows @ref ds_usize_t "usize".
434 /// @return @ref DS_RESULT_ERR_MEM_ALLOC_FAILED "Err(MemAllocFailed)" if a
435 /// memory allocation fails.
436 ///
437 /// ### Examples
438 ///
439 /// Basic usage:
440 ///
441 /// ```c
442 /// ds_string_t s = ds_string_new ();
443 ///
444 /// DS_RESULT_PROPAGATE_ERR (ds_string_reserve (&s, 10));
445 ///
446 /// assert (ds_string_capacity (s) >= 10);
447 ///
448 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&s));
449 /// ```
450 ///
451 /// This might not actually increase the capacity:
452 ///
453 /// ```c
454 /// ds_string_t s;
455 /// DS_RESULT_PROPAGATE_ERR (ds_string_with_capacity (&s, 10));
456 /// DS_RESULT_PROPAGATE_ERR (ds_string_push (&s, 'a'));
457 /// DS_RESULT_PROPAGATE_ERR (ds_string_push (&s, 'b'));
458 ///
459 /// // s now has a length of 2 and a capacity of at least 10
460 /// let capacity = ds_string_capacity (s);
461 /// assert (2 == ds_string_len (s));
462 /// assert (capacity >= 10);
463 ///
464 /// // Since we already have at least an extra 8 capacity, calling this...
465 /// DS_RESULT_PROPAGATE_ERR (ds_string_reserve (&s, 8));
466 ///
467 /// // ... doesn't actually increase.
468 /// assert (capacity == ds_string_capacity (s));
469 ///
470 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&s));
471 /// ```
473 ds_usize_t additional);
474
475 /// @brief Reserves the minimum capacity for at least @p additional bytes
476 /// more than @p self's current length. Unlike @ref ds_string_reserve, this
477 /// will not deliberately over-allocate to speculatively avoid frequent
478 /// allocations. After calling @ref ds_string_reserve_exact, capacity will be
479 /// greater than or equal to `ds_string_len (self) + additional`. Does
480 /// nothing if the capacity is already sufficient.
481 ///
482 /// @param[out] self Pointer to the @ref ds_string_t "String" to reserve the
483 /// minimum capacity for at least @p additional bytes more than its current
484 /// length.
485 /// @param additional The minimum number of bytes more than @p self's current
486 /// length to allocate without deliberately over-allocating.
487 ///
488 /// @return @ref DS_RESULT_OK "Ok" on success.
489 /// @return @ref DS_RESULT_ERR_PTR_IS_NULL "Err(PtrIsNull)" if @p self is
490 /// `NULL`.
491 /// @return @ref DS_RESULT_ERR_OUT_OF_RANGE "Err(OutOfRange)" if the new
492 /// capacity overflows @ref ds_usize_t "usize".
493 /// @return @ref DS_RESULT_ERR_MEM_ALLOC_FAILED "Err(MemAllocFailed)" if a
494 /// memory allocation fails.
495 ///
496 /// ### Examples
497 ///
498 /// Basic usage:
499 ///
500 /// ```c
501 /// ds_string_t s = ds_string_new ();
502 ///
503 /// DS_RESULT_PROPAGATE_ERR (ds_string_reserve_exact (&s, 10));
504 ///
505 /// assert (ds_string_capacity (s) >= 10);
506 ///
507 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&s));
508 /// ```
509 ///
510 /// This might not actually increase the capacity:
511 ///
512 /// ```c
513 /// ds_string_t s;
514 /// DS_RESULT_PROPAGATE_ERR (ds_string_with_capacity (&s, 10));
515 /// DS_RESULT_PROPAGATE_ERR (ds_string_push (&s, 'a'));
516 /// DS_RESULT_PROPAGATE_ERR (ds_string_push (&s, 'b'));
517 ///
518 /// // s now has a length of 2 and a capacity of at least 10
519 /// let capacity = ds_string_capacity (s);
520 /// assert (2 == ds_string_len (s));
521 /// assert (capacity >= 10);
522 ///
523 /// // Since we already have at least an extra 8 capacity, calling this...
524 /// DS_RESULT_PROPAGATE_ERR (ds_string_reserve_exact (&s, 8));
525 ///
526 /// // ... doesn't actually increase.
527 /// assert (capacity == ds_string_capacity (s));
528 ///
529 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&s));
530 /// ```
532 ds_usize_t additional);
533
534 /// @brief Shrinks the capacity of @p self to match its length.
535 /// @param[out] self Pointer to the @ref ds_string_t "String" to shrink the
536 /// capacity to match its length.
537 /// @return @ref DS_RESULT_OK "Ok" on success.
538 /// @return @ref DS_RESULT_ERR_PTR_IS_NULL "Err(PtrIsNull)" if @p self is
539 /// `NULL`.
540 ///
541 /// ### Examples
542 ///
543 /// Basic usage:
544 ///
545 /// ```c
546 /// ds_string_t s;
547 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&s, "foo", 3));
548 ///
549 /// DS_RESULT_PROPAGATE_ERR (ds_string_reserve (&s, 100));
550 /// assert (ds_string_capacity (s) >= 100);
551 ///
552 /// DS_RESULT_PROPAGATE_ERR (ds_string_shrink_to_fit (&s));
553 /// assert (3 == ds_string_capacity (s));
554 ///
555 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&s));
556 /// ```
558
559 /// @brief Shrinks the capacity of @p self with a lower bound.
560 ///
561 /// The capacity will remain at least as large as both the length and the
562 /// supplied value.
563 ///
564 /// If the current capacity is less than the lower limit, this is a no-op.
565 ///
566 /// @param[out] self Pointer to the @ref ds_string_t "String" to shrink the
567 /// capacity with a lower bound.
568 /// @param min_capacity The lower bound of the capacity.
569 ///
570 /// @return @ref DS_RESULT_OK "Ok" on success.
571 /// @return @ref DS_RESULT_ERR_PTR_IS_NULL "Err(PtrIsNull)" if @p self is
572 /// `NULL`.
573 ///
574 /// ### Examples
575 ///
576 /// Basic usage:
577 ///
578 /// ```c
579 /// ds_string_t s;
580 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&s, "foo", 3));
581 ///
582 /// DS_RESULT_PROPAGATE_ERR (ds_string_reserve (&s, 100));
583 /// assert (ds_string_capacity (s) >= 100);
584 ///
585 /// DS_RESULT_PROPAGATE_ERR (ds_string_shrink_to (&s, 10));
586 /// assert (ds_string_capacity (s) >= 10);
587 /// DS_RESULT_PROPAGATE_ERR (ds_string_shrink_to (&s, 0));
588 /// assert (ds_string_capacity (s) >= 3);
589 ///
590 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&s));
591 /// ```
593 ds_usize_t min_capacity);
594
595 /// @brief Appends @p chr to the end of @p self.
596 /// @param[out] self Pointer to the @ref ds_string_t "String" to append @p
597 /// chr to the end of.
598 /// @param chr The @ref ds_char_t "char" to append to the end of @p self.
599 /// @return @ref DS_RESULT_OK "Ok" on success.
600 /// @return @ref DS_RESULT_ERR_PTR_IS_NULL "Err(PtrIsNull)" if @p self is
601 /// `NULL`.
602 /// @return @ref DS_RESULT_ERR_MEM_ALLOC_FAILED "Err(MemAllocFailed)" if a
603 /// memory allocation fails.
604 ///
605 /// ### Examples
606 ///
607 /// Basic usage:
608 ///
609 /// ```c
610 /// ds_string_t s;
611 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&s, "abc", 3));
612 ///
613 /// DS_RESULT_PROPAGATE_ERR (ds_string_push (&s, '1'));
614 /// DS_RESULT_PROPAGATE_ERR (ds_string_push (&s, '2'));
615 /// DS_RESULT_PROPAGATE_ERR (ds_string_push (&s, '3'));
616 ///
617 /// ds_string_t abc123;
618 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&abc123, "abc123", 6));
619 /// assert (ds_string_eq (abc123, s));
620 ///
621 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&abc123));
622 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&s));
623 /// ```
625
626 /// @brief Shortens @p self to @p new_len.
627 ///
628 /// If @p new_len is greater than @p self's current length, this has no
629 /// effect.
630 ///
631 /// Note that this method has no effect on the allocated capacity of @p self.
632 ///
633 /// @param[out] self Pointer to the @ref ds_string_t "String" to shorten to
634 /// @p new_len.
635 /// @param new_len The length to shorten @p self to.
636 ///
637 /// @return @ref DS_RESULT_OK "Ok" on success.
638 /// @return @ref DS_RESULT_ERR_PTR_IS_NULL "Err(PtrIsNull)" if @p self is
639 /// `NULL`.
640 ///
641 /// ### Examples
642 ///
643 /// Basic usage:
644 ///
645 /// ```c
646 /// ds_string_t s;
647 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&s, "hello", 5));
648 ///
649 /// DS_RESULT_PROPAGATE_ERR (ds_string_truncate (&s, 2));
650 ///
651 /// ds_string_t he;
652 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&he, "he", 2));
653 /// assert (ds_string_eq (he, s));
654 ///
655 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&he));
656 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&s));
657 /// ```
659 ds_usize_t new_len);
660
661 /// @brief Removes the last character from the string buffer and retrieves
662 /// it.
663 ///
664 /// @param[out] self Pointer to the @ref ds_string_t "String" to remove the
665 /// last character from its string buffer and retrieve it from.
666 /// @param[out] chr_ptr Pointer to the last character removed and retrieved
667 /// from @p self's string buffer.
668 ///
669 /// @return @ref DS_RESULT_OK "Ok" on success.
670 /// @return @ref DS_RESULT_ERR_PTR_IS_NULL "Err(PtrIsNull)" if @p self is
671 /// `NULL`.
672 /// @return @ref DS_RESULT_ERR_OUT_OF_RANGE "Err(OutOfRange)" if @p self is
673 /// empty.
674 ///
675 /// ### Examples
676 ///
677 /// Basic usage:
678 ///
679 /// ```c
680 /// ds_string_t s;
681 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&s, "foo", 3));
682 ///
683 /// ds_char_t chr;
684 ///
685 /// DS_RESULT_PROPAGATE_ERR (ds_string_pop (&s, &chr));
686 /// assert (chr == 'o');
687 /// DS_RESULT_PROPAGATE_ERR (ds_string_pop (&s, &chr));
688 /// assert (chr == 'o');
689 /// DS_RESULT_PROPAGATE_ERR (ds_string_pop (&s, &chr));
690 /// assert (chr == 'f');
691 ///
692 /// assert (ds_string_pop (&s, &chr) == DS_RESULT_ERR_OUT_OF_RANGE);
693 /// assert (chr == 'f');
694 ///
695 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&s));
696 /// ```
697 extern ds_result_t ds_string_pop (ds_string_t *self, ds_char_t *chr_ptr);
698
699 /// @brief Removes a @ref ds_char_t "char" from @p self at a byte position
700 /// and retrieves it.
701 ///
702 /// This is an *O*(*n*) operation, as it requires copying every element in
703 /// the buffer.
704 ///
705 /// @param[out] self Pointer to the @ref ds_string_t "String" to remove a
706 /// @ref ds_char_t "char" and retrieve it at a byte position.
707 /// @param idx The byte position to remove a @ref ds_char_t "char" at.
708 /// @param[out] chr_ptr Pointer to the @ref ds_char_t "char" removed and
709 /// retrieved at a byte position.
710 ///
711 /// @return @ref DS_RESULT_OK "Ok" on success.
712 /// @return @ref DS_RESULT_ERR_PTR_IS_NULL "Err(PtrIsNull)" if @p self is
713 /// `NULL`.
714 /// @return @ref DS_RESULT_ERR_OUT_OF_RANGE "Err(OutOfRange)" if @p idx is
715 /// larger than or equal to @p self's length.
716 ///
717 /// ### Examples
718 ///
719 /// Basic usage:
720 ///
721 /// ```c
722 /// ds_string_t s;
723 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&s, "foo", 3));
724 ///
725 /// ds_char_t chr;
726 ///
727 /// DS_RESULT_PROPAGATE_ERR (ds_string_remove (&s, 0, &chr));
728 /// assert (chr == 'f');
729 /// DS_RESULT_PROPAGATE_ERR (ds_string_remove (&s, 1, &chr));
730 /// assert (chr == 'o');
731 /// DS_RESULT_PROPAGATE_ERR (ds_string_remove (&s, 0, &chr));
732 /// assert (chr == 'o');
733 ///
734 /// assert (ds_string_remove (&s, 0, &chr) == DS_RESULT_ERR_OUT_OF_RANGE);
735 /// assert (chr == 'f');
736 ///
737 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&s));
738 /// ```
740 ds_char_t *chr_ptr);
741
742 /// @brief Retains only the characters specified by the predicate.
743 ///
744 /// In other words, remove all characters `c` such that @p match(c) returns
745 /// `false`. This method operates in place, visiting each character exactly
746 /// once in the original order, and preserves the order of the retained
747 /// characters.
748 ///
749 /// @param[out] self Pointer to the @ref ds_string_t "String" whose
750 /// characters are to be retained based on the predicate.
751 /// @param match The predicate that specifies which characters to retain.
752 ///
753 /// @return @ref DS_RESULT_OK "Ok" on success.
754 /// @return @ref DS_RESULT_ERR_PTR_IS_NULL "Err(PtrIsNull)" if @p self is
755 /// `NULL`.
756 ///
757 /// ### Examples
758 ///
759 /// Basic usage:
760 ///
761 /// ```c
762 /// ds_string_t s;
763 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&s, "f_o_ob_ar", 9));
764 ///
765 /// bool is_not_underscore (char const c)
766 /// {
767 /// return c != '_';
768 /// }
769 ///
770 /// DS_RESULT_PROPAGATE_ERR (ds_string_retain (&s, is_not_underscore));
771 ///
772 /// ds_string_t foobar;
773 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&foobar, "foobar", 6));
774 ///
775 /// assert (ds_string_eq (s, foobar));
776 ///
777 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&foobar));
778 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&s));
779 /// ```
780 ///
781 /// Because the elements are visited exactly once in the original order,
782 /// external state may be used to decide which elements to keep.
783 ///
784 /// ```c
785 /// ds_string_t s;
786 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&s, "abcde", 5));
787 /// bool keep[] = { false, true, true, false, true };
788 /// bool only_keep (char const c)
789 /// {
790 /// static ds_usize_t i = DS_USIZE_MIN;
791 /// return keep[i++];
792 /// }
793 /// DS_RESULT_PROPAGATE_ERR (ds_string_retain (&s, only_keep));
794 /// ds_string_t bce;
795 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&bce, "bce", 3));
796 /// assert (ds_string_eq (s, bce));
797 ///
798 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&bce));
799 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&s));
800 /// ```
802 ds_predicate_char_t match);
803
804 /// @brief Inserts @p chr into @p self at a byte position.
805 ///
806 /// This is an *O*(*n*) operation as it requires copying every element in the
807 /// buffer.
808 ///
809 /// @param[out] self Pointer to the @ref ds_string_t "String" to insert @p
810 /// chr into at the byte position.
811 /// @param idx The byte position to insert @p chr into @p self at.
812 /// @param chr The character to insert into @p self at the byte position.
813 ///
814 /// @return @ref DS_RESULT_OK "Ok" on success.
815 /// @return @ref DS_RESULT_ERR_PTR_IS_NULL "Err(PtrIsNull)" if @p self is
816 /// `NULL`.
817 /// @return @ref DS_RESULT_ERR_OUT_OF_RANGE "Err(OutOfRange)" if @p idx is
818 /// larger than @p self's length.
819 /// @return @ref DS_RESULT_ERR_MEM_ALLOC_FAILED "Err(MemAllocFailed)" if a
820 /// memory allocation fails.
821 ///
822 /// ### Examples
823 ///
824 /// Basic usage:
825 ///
826 /// ```c
827 /// ds_string_t s;
828 /// DS_RESULT_PROPAGATE_ERR (ds_string_with_capacity (&s, 3));
829 ///
830 /// DS_RESULT_PROPAGATE_ERR (ds_string_insert (&s, 0, 'f'));
831 /// DS_RESULT_PROPAGATE_ERR (ds_string_insert (&s, 1, 'o'));
832 /// DS_RESULT_PROPAGATE_ERR (ds_string_insert (&s, 2, 'o'));
833 ///
834 /// ds_string_t foo;
835 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&foo, "foo", 3));
836 /// assert (ds_string_eq (foo, s));
837 ///
838 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&foo));
839 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&s));
840 /// ```
842 ds_char_t chr);
843
844 /// @brief Inserts a @p string slice into @p self at a byte position.
845 ///
846 /// This is an *O*(*n*) operation as it requires copying every element in the
847 /// buffer.
848 ///
849 /// @param[out] self Pointer to the @ref ds_string_t "String" to insert the
850 /// @p string slice into at the byte position.
851 /// @param idx The byte position to insert the @p string slice into @p self
852 /// at.
853 /// @param string The string slice to insert into @p self at the byte
854 /// position.
855 ///
856 /// @return @ref DS_RESULT_OK "Ok" on success.
857 /// @return @ref DS_RESULT_ERR_PTR_IS_NULL "Err(PtrIsNull)" if @p self is
858 /// `NULL`.
859 /// @return @ref DS_RESULT_ERR_OUT_OF_RANGE "Err(OutOfRange)" if @p idx is
860 /// larger than @p self's length.
861 /// @return @ref DS_RESULT_ERR_MEM_ALLOC_FAILED "Err(MemAllocFailed)" if a
862 /// memory allocation fails.
863 ///
864 /// ### Examples
865 ///
866 /// Basic usage:
867 ///
868 /// ```c
869 /// ds_string_t s;
870 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&s, "bar", 3));
871 ///
872 /// DS_RESULT_PROPAGATE_ERR (ds_string_insert_str (&s, 0, "foo", 3));
873 ///
874 /// ds_string_t foobar;
875 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&foobar, "foobar", 6));
876 /// assert (ds_string_eq (foobar, s));
877 ///
878 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&foobar));
879 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&s));
880 /// ```
882 ds_cstr_t string,
883 ds_usize_t string_len);
884
885 /// @brief Returns the length of @p self, in bytes, not graphemes. In other
886 /// words, it might not be what a human considers the length of the string.
887 /// @param self The @ref ds_string_t "String" to return the length of, in
888 /// bytes.
889 /// @return The length of @p self, in bytes.
890 ///
891 /// ### Examples
892 ///
893 /// Basic usage:
894 ///
895 /// ```c
896 /// ds_string_t a;
897 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&a, "foo", 3));
898 /// assert (ds_string_len (a) == 3);
899 ///
900 /// ds_string_t fancy_f;
901 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&fancy_f, "ƒoo", 4));
902 /// assert (ds_string_len (fancy_f), 4);
903 ///
904 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&fancy_f));
905 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&s));
906 /// ```
908
909 /// @brief Returns `true` if @p self has a length of zero, and `false`
910 /// otherwise.
911 /// @param self The @ref ds_string_t "String" to check if has length of zero.
912 /// @return `true` if @p self has a length of zero, and `false` otherwise.
913 ///
914 /// ### Examples
915 ///
916 /// Basic usage:
917 ///
918 /// ```c
919 /// ds_string_t v = ds_string_new ();
920 /// assert (ds_string_is_empty (v));
921 ///
922 /// DS_RESULT_PROPAGATE_ERR (ds_string_push (&v, 'a'));
923 /// assert (!ds_string_is_empty (v));
924 ///
925 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&v));
926 /// ```
927 extern bool ds_string_is_empty (ds_string_t self);
928
929 /// @brief Splits @p self into two at the given byte index.
930 ///
931 /// Retrieves a newly allocated @ref ds_string_t "String". @p self contains
932 /// bytes `[0, idx)`, and the retrieved @p target contains bytes
933 /// `[idx, len)`.
934 ///
935 /// Note that the capacity of @p self does not change.
936 ///
937 /// @param[out] self Pointer to the @ref ds_string_t "String" to split into
938 /// two at the given byte index.
939 /// @param idx The byte index to split @p self into two at.
940 /// @param[out] target Pointer to the newly allocated @ref ds_string_t
941 /// "String" containing bytes `[idx, len)`.
942 ///
943 /// @return @ref DS_RESULT_OK "Ok" on success.
944 /// @return @ref DS_RESULT_ERR_PTR_IS_NULL "Err(PtrIsNull)" if @p self or @p
945 /// target is `NULL`.
946 /// @return @ref DS_RESULT_ERR_OUT_OF_RANGE "Err(OutOfRange)" if @p idx
947 /// is beyond the last code point of the string.
948 /// @return @ref DS_RESULT_ERR_MEM_ALLOC_FAILED "Err(MemAllocFailed)" if a
949 /// memory allocation fails.
950 ///
951 /// ### Examples
952 ///
953 /// ```c
954 /// ds_string_t hello;
955 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&hello, "Hello, World!", 13));
956 /// ds_string_t world;
957 /// DS_RESULT_PROPAGATE_ERR (ds_string_split_off (&hello, 7, &world));
958 /// ds_string_t hello_actual;
959 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&hello_actual, "Hello, ", 7));
960 /// ds_string_t world_actual;
961 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&world_actual, "World!", 6));
962 /// assert (ds_string_eq (hello, hello_actual));
963 /// assert (ds_string_eq (world, world_actual));
964 ///
965 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&world_actual));
966 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&hello_actual));
967 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&world));
968 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&hello));
969 /// ```
971 ds_string_t *target);
972
973 /// @brief Truncates @p self, removing all contents.
974 ///
975 /// While this means @p self will have a length of zero, it does not touch
976 /// its capacity.
977 ///
978 /// @param[out] self Pointer to the @ref ds_string_t "String" to truncate and
979 /// remove all contents.
980 /// @return @ref DS_RESULT_OK "Ok" on success.
981 /// @return @ref DS_RESULT_ERR_PTR_IS_NULL "Err(PtrIsNull)" if @p self is
982 /// `NULL`.
983 ///
984 /// ### Examples
985 ///
986 /// Basic usage:
987 ///
988 /// ```c
989 /// ds_string_t s;
990 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&s, "foo", 3));
991 ///
992 /// DS_RESULT_PROPAGATE_ERR (ds_string_clear (&s));
993 ///
994 /// assert (ds_string_is_empty (s));
995 /// assert (0 == ds_string_len (s));
996 /// assert (3 <= ds_string_capacity (s));
997 ///
998 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&s));
999 /// ```
1001
1002 /// @brief Retrieves a copy of @p self.
1003 /// @param self The value to clone.
1004 /// @param[out] target Pointer to the value to clone into.
1005 /// @return @ref DS_RESULT_OK "Ok" on success.
1006 /// @return @ref DS_RESULT_ERR_PTR_IS_NULL "Err(PtrIsNull)" if @p target is
1007 /// `NULL`.
1008 /// @return @ref DS_RESULT_ERR_MEM_ALLOC_FAILED "Err(MemAllocFailed)" if a
1009 /// memory allocation fails.
1010 extern ds_result_t ds_string_clone (ds_string_t self, ds_string_t *target);
1011
1012 /// @brief Performs copy-assignment from @p source.
1013 /// @param[out] self Pointer to the value to clone into.
1014 /// @param source The value to clone.
1015 /// @return @ref DS_RESULT_OK "Ok" on success.
1016 /// @return @ref DS_RESULT_ERR_PTR_IS_NULL "Err(PtrIsNull)" if @p self is
1017 /// `NULL`.
1018 /// @return @ref DS_RESULT_ERR_MEM_ALLOC_FAILED "Err(MemAllocFailed)" if a
1019 /// memory allocation fails.
1021 ds_string_t source);
1022
1023 /// @brief Creates an empty @ref ds_string_t "String".
1024 /// @return An empty @ref ds_string_t "String".
1025 extern ds_string_t ds_string_default (void);
1026
1027 /// @brief Converts a C-string into a @ref ds_string_t "String".
1028 ///
1029 /// The result is allocated on the heap.
1030 ///
1031 /// @param[out] self Pointer to the @ref ds_string_t "String" to convert @p
1032 /// string into.
1033 /// @param string The C-string to convert into @p self.
1034 /// @param string_len The length of @p string.
1035 ///
1036 /// @return @ref DS_RESULT_OK "Ok" on success.
1037 /// @return @ref DS_RESULT_ERR_PTR_IS_NULL "Err(PtrIsNull)" if @p self is
1038 /// `NULL`.
1039 /// @return @ref DS_RESULT_ERR_MEM_ALLOC_FAILED "Err(MemAllocFailed)" if a
1040 /// memory allocation fails.
1041 extern ds_result_t ds_string_from (ds_string_t *self, ds_cstr_t string,
1042 ds_usize_t string_len);
1043
1044 /// @brief This method tests for @p self and @p other values to be equal.
1045 /// @param self The first value to test.
1046 /// @param other The second value to test.
1047 /// @return `true` if @p self and @p other values are equal, and `false`
1048 /// otherwise.
1049 extern bool ds_string_eq (ds_string_t self, ds_string_t other);
1050
1051 /// @brief This method tests for @p self and @p other values to not be equal.
1052 /// @param self The first value to test.
1053 /// @param other The second value to test.
1054 /// @return `true` if @p self and @p other values are not equal, and `false`
1055 /// otherwise.
1056 extern bool ds_string_ne (ds_string_t self, ds_string_t other);
1057
1058 /// @brief Converts @p self to a raw pointer.
1059 ///
1060 /// As string slices are a slice of bytes, the raw pointer points to a @ref
1061 /// ds_char_t "char". This pointer will be pointing to the first byte of the
1062 /// string slice.
1063 ///
1064 /// The caller must ensure that the returned pointer is never written to. If
1065 /// you need to mutate the contents of the string slice, use @ref
1066 /// ds_string_as_mut_ptr.
1067 ///
1068 /// @param self The @ref ds_string_t "String" to convert to a raw pointer.
1069 /// @return The raw pointer pointing to the first byte of @p self.
1070 ///
1071 /// ### Examples
1072 ///
1073 /// Basic usage:
1074 ///
1075 /// ```c
1076 /// ds_string_t s;
1077 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&s, "Hello", 5));
1078 /// ds_cstr_t ptr = ds_string_as_ptr (s);
1079 ///
1080 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&s));
1081 /// ```
1083
1084 /// @brief Converts @p self to a mutable raw pointer.
1085 ///
1086 /// As string slices are a slice of bytes, the raw pointer points to a @ref
1087 /// ds_char_t "char". This pointer will be pointing to the first byte of the
1088 /// string slice.
1089 ///
1090 /// It is your responsibility to make sure that the string slice only gets
1091 /// modified in a way that it remains valid UTF-8.
1092 ///
1093 /// @param self The @ref ds_string_t "String" to convert to a mutable raw
1094 /// pointer.
1095 /// @return The mutable raw pointer pointing to the first byte of @p self.
1097
1098 /// @brief Disposes of a value.
1099 /// @param[out] self The value to dispose.
1100 /// @return @ref DS_RESULT_OK "Ok" on success.
1101 /// @return @ref DS_RESULT_ERR_PTR_IS_NULL "Err(PtrIsNull)" if @p self is
1102 /// `NULL`.
1103 ///
1104 /// ### Examples
1105 ///
1106 /// Basic usage:
1107 ///
1108 /// ```c
1109 /// ds_string_t s;
1110 /// DS_RESULT_PROPAGATE_ERR (ds_string_from (&s, "abc", 3));
1111 ///
1112 /// // explicitly drop the vector
1113 /// DS_RESULT_PROPAGATE_ERR (ds_string_drop (&s));
1114 /// ```
1115 extern ds_result_t ds_string_drop (ds_string_t *self);
1116
1117/// @brief The size of @ref ds_string_t "String" in bytes.
1118///
1119/// ### Examples
1120///
1121/// Basic usage:
1122///
1123/// ```c
1124/// assert (DS_STRING_BYTES == sizeof (ds_string_t));
1125/// ```
1126#define DS_STRING_BYTES ((ds_usize_t)sizeof (ds_string_t))
1127
1128#ifdef __cplusplus
1129}
1130#endif /* __cplusplus */
1131
1132#endif /* DS_STRING_H */
Declaration of the char type, related constants and functions.
char ds_char_t
A character type.
Definition: char.h:30
bool(* ds_predicate_char_t)(ds_char_t)
A function pointer type for char predicate functions that return true or false depending on the passe...
Definition: char.h:64
Declaration of the C-string types, related constants and functions.
ds_char_t const * ds_cstr_t
An immutable C-string type.
Definition: cstr.h:28
ds_char_t * ds_cstr_mut_t
A mutable C-string type.
Definition: cstr.h:37
Declaration of the Result enumeration type, related constants and functions.
ds_result_t
Result is a type that represents either success (Ok) or failure (a DS_RESULT_ERR_* variant).
Definition: result.h:26
ds_result_t ds_string_retain(ds_string_t *self, ds_predicate_char_t match)
Retains only the characters specified by the predicate.
Definition: string.c:227
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_string_t ds_string_default(void)
Creates an empty String.
Definition: string.c:336
ds_cstr_t ds_string_as_ptr(ds_string_t self)
Converts self to a raw pointer.
Definition: string.c:380
ds_result_t ds_string_clear(ds_string_t *self)
Truncates self, removing all contents.
Definition: string.c:317
ds_result_t ds_string_shrink_to_fit(ds_string_t *self)
Shrinks the capacity of self to match its length.
Definition: string.c:153
ds_result_t ds_string_shrink_to(ds_string_t *self, ds_usize_t min_capacity)
Shrinks the capacity of self with a lower bound.
Definition: string.c:160
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
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_split_off(ds_string_t *self, ds_usize_t idx, ds_string_t *target)
Splits self into two at the given byte index.
Definition: string.c:293
ds_result_t ds_string_pop(ds_string_t *self, ds_char_t *chr_ptr)
Removes the last character from the string buffer and retrieves it.
Definition: string.c:194
ds_result_t ds_string_reserve(ds_string_t *self, ds_usize_t additional)
Reserves capacity for at least additional bytes more than self's current length. The allocator may re...
Definition: string.c:141
ds_result_t ds_string_clone_from(ds_string_t *self, ds_string_t source)
Performs copy-assignment from source.
Definition: string.c:329
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_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
ds_result_t ds_string_reserve_exact(ds_string_t *self, ds_usize_t additional)
Reserves the minimum capacity for at least additional bytes more than self's current length....
Definition: string.c:147
ds_result_t ds_string_clone(ds_string_t self, ds_string_t *target)
Retrieves a copy of self.
Definition: string.c:323
ds_result_t ds_string_truncate(ds_string_t *self, ds_usize_t new_len)
Shortens self to new_len.
Definition: string.c:183
ds_string_t ds_string_new(void)
Creates a new empty String.
Definition: string.c:85
ds_result_t ds_string_insert_str(ds_string_t *self, ds_usize_t idx, ds_cstr_t string, ds_usize_t string_len)
Inserts a string slice into self at a byte position.
Definition: string.c:258
bool ds_string_is_empty(ds_string_t self)
Returns true if self has a length of zero, and false otherwise.
Definition: string.c:287
ds_cstr_mut_t ds_string_as_mut_ptr(ds_string_t self)
Converts self to a mutable raw pointer.
Definition: string.c:386
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_result_t ds_string_into_raw_parts(ds_string_t *self, ds_cstr_mut_t *buf_ptr, ds_usize_t *len_ptr, ds_usize_t *cap_ptr)
Decomposes self into its raw components.
Definition: string.c:100
ds_result_t ds_string_remove(ds_string_t *self, ds_usize_t idx, ds_char_t *chr_ptr)
Removes a char from self at a byte position and retrieves it.
Definition: string.c:201
ds_usize_t ds_string_capacity(ds_string_t self)
Returns self's capacity, in bytes.
Definition: string.c:135
ds_result_t ds_string_insert(ds_string_t *self, ds_usize_t idx, ds_char_t chr)
Inserts chr into self at a byte position.
Definition: string.c:251
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_result_t ds_string_drop(ds_string_t *self)
Disposes of a value.
Definition: string.c:392
bool ds_string_ne(ds_string_t self, ds_string_t other)
This method tests for self and other values to not be equal.
Definition: string.c:374
A growable string. Will be UTF-8–encoded in the future.
Definition: string.h:163
ds_usize_t cap
The size of the buffer in bytes.
Definition: string.h:181
ds_cstr_mut_t buf
Points to an internal buffer String uses to store its data.
Definition: string.h:169
ds_usize_t len
The number of bytes currently stored in the buffer.
Definition: string.h:175
Declaration of the usize type, related constants and functions.
size_t ds_usize_t
The pointer-sized unsigned integer type.
Definition: usize.h:26