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