xref: /aosp_15_r20/external/pigweed/pw_string/design.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1.. _module-pw_string-design:
2
3================
4Design & Roadmap
5================
6.. pigweed-module-subpage::
7   :name: pw_string
8
9``pw_string`` provides string classes and utility functions designed to
10prioritize safety and static allocation. The APIs are broadly similar to those
11of the string classes in the C++ standard library, so familiarity with those
12classes will provide some context around ``pw_string`` design decisions.
13
14.. _module-pw_string-design-inlinestring:
15
16--------------------------
17Design of pw::InlineString
18--------------------------
19:cpp:type:`pw::InlineString` / :cpp:class:`pw::InlineBasicString` are designed
20to match the ``std::string`` / ``std::basic_string<T>`` API as closely as
21possible, but with key differences to improve performance on embedded systems:
22
23- **Fixed capacity:** Operations that add characters to the string beyond its
24  capacity are an error. These trigger a ``PW_ASSERT`` at runtime. When
25  detectable, these situations trigger a ``static_assert`` at compile time.
26- **Minimal overhead:** :cpp:type:`pw::InlineString` operations never
27  allocate. Reading the contents of the string is a direct memory access within
28  the string object, without pointer indirection.
29- **Constexpr support:** :cpp:type:`pw::InlineString` works in ``constexpr``
30  contexts, which is not supported by ``std::string`` until C++20.
31
32We don't aim to provide complete API compatibility with
33``std::string`` / ``std::basic_string<T>``. Some areas of deviation include:
34
35- **Compile-time capacity checks:** :cpp:type:`InlineString` provides overloads
36  specific to character arrays. These perform compile-time capacity checks and
37  are used for class template argument deduction.
38- **Implicit conversions from** ``std::string_view`` **:** Specifying the
39  capacity parameter is cumbersome, so implicit conversions are helpful. Also,
40  implicitly creating a :cpp:type:`InlineString` is less costly than creating a
41  ``std::string``. As with ``std::string``, explicit conversions are required
42  from types that convert to ``std::string_view``.
43- **No dynamic allocation functions:** Functions that allocate memory, like
44  ``reserve()``, ``shrink_to_fit()``, and ``get_allocator()``, are simply not
45  present.
46
47Capacity
48========
49:cpp:type:`InlineBasicString` has a template parameter for the capacity, but the
50capacity does not need to be known by the user to use the string safely. The
51:cpp:type:`InlineBasicString` template inherits from a
52:cpp:type:`InlineBasicString` specialization with capacity of the reserved value
53``pw::InlineString<>::npos``. The actual capacity is stored in a single word
54alongside the size. This allows code to work with strings of any capacity
55through a ``InlineString<>`` or ``InlineBasicString<T>`` reference.
56
57Exceeding the capacity
58----------------------
59Any :cpp:type:`pw::InlineString` operations that exceed the string's capacity
60fail an assertion, resulting in a crash. Helpers are provided in
61``pw_string/util.h`` that return ``pw::Status::ResourceExhausted()`` instead of
62failing an assert when the capacity would be exceeded.
63
64----------------------------------
65Design of string utility functions
66----------------------------------
67
68Safe length checking
69====================
70This module provides two safer alternatives to ``std::strlen`` in case the
71string is extremely long and/or potentially not null-terminated.
72
73First, a constexpr alternative to C11's ``strnlen_s`` is offerred through
74:cpp:func:`pw::string::ClampedCString`. This does not return a length by
75design and instead returns a string_view which does not require
76null-termination.
77
78Second, a constexpr specialized form is offered where null termination is
79required through :cpp:func:`pw::string::NullTerminatedLength`. This will only
80return a length if the string is null-terminated.
81
82.. _module-pw_string-roadmap:
83
84-------
85Roadmap
86-------
87* The fixed size cost of :cpp:type:`pw::StringBuilder` can be dramatically
88  reduced by limiting support for 64-bit integers.
89* ``pw_string`` may be integrated with :ref:`module-pw_tokenizer`.
90