aboutsummaryrefslogtreecommitdiff
path: root/pw_string
diff options
context:
space:
mode:
authorChad Norvell <chadnorvell@google.com>2023-03-11 00:00:35 +0000
committerCQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-03-11 00:00:35 +0000
commit85cbe67e0f3d474498a648d99b041b80e00edce4 (patch)
tree28abef1a8a2baadef6938d19f1853fbe077d04e4 /pw_string
parent2d3495c8c24f014d8e51d7878d2d1ab97373b6e2 (diff)
downloadpigweed-85cbe67e0f3d474498a648d99b041b80e00edce4.tar.gz
pw_string: Improve API and design docs
Change-Id: Id441cba35e23539bf00e2e00bac6b39fa5128d53 Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/133611 Reviewed-by: Keir Mierle <keir@google.com> Commit-Queue: Chad Norvell <chadnorvell@google.com>
Diffstat (limited to 'pw_string')
-rw-r--r--pw_string/api.rst45
-rw-r--r--pw_string/design.rst92
-rw-r--r--pw_string/public/pw_string/string.h36
-rw-r--r--pw_string/public/pw_string/string_builder.h4
4 files changed, 96 insertions, 81 deletions
diff --git a/pw_string/api.rst b/pw_string/api.rst
index cead6428f..a526023eb 100644
--- a/pw_string/api.rst
+++ b/pw_string/api.rst
@@ -1,22 +1,41 @@
.. _module-pw_string-api:
-=======================
-pw_string API reference
-=======================
+=============
+API Reference
+=============
--------
Overview
--------
+This module provides two types of strings, and utility functions for working
+with strings.
+
+**pw::StringBuilder**
+
+.. doxygenfile:: pw_string/string_builder.h
+ :sections: briefdescription
+
+**pw::InlineString**
+
.. doxygenfile:: pw_string/string.h
:sections: briefdescription
+
+**String utility functions**
+
.. doxygenfile:: pw_string/util.h
:sections: briefdescription
+
+-----------------
+pw::StringBuilder
+-----------------
.. doxygenfile:: pw_string/string_builder.h
:sections: briefdescription
+.. doxygenclass:: pw::StringBuilder
+ :members:
----------------------
-pw::InlineBasicString
----------------------
+----------------
+pw::InlineString
+----------------
.. doxygenfile:: pw_string/string.h
:sections: detaileddescription
@@ -25,9 +44,9 @@ pw::InlineBasicString
.. doxygentypedef:: pw::InlineString
-----------
-pw::string
-----------
+------------------------
+String utility functions
+------------------------
pw::string::Assign()
--------------------
@@ -70,11 +89,3 @@ pw::string::NullTerminatedLength()
pw::string::PrintableCopy()
---------------------------
.. doxygenfunction:: pw::string::PrintableCopy(const std::string_view& source, span<char> dest)
-
------------------
-pw::StringBuilder
------------------
-.. doxygenfile:: pw_string/string_builder.h
- :sections: briefdescription
-.. doxygenclass:: pw::StringBuilder
- :members:
diff --git a/pw_string/design.rst b/pw_string/design.rst
index 817171e16..91202e185 100644
--- a/pw_string/design.rst
+++ b/pw_string/design.rst
@@ -3,44 +3,65 @@
================
pw_string design
================
-``pw_string`` is designed to prioritize safety and static allocation. It matches
-the ``std::string`` API as closely as possible, but isn't intended to provide
-complete API compatibility.
-
-:cpp:type:`pw::InlineString` / :cpp:class:`pw::InlineBasicString` follows the
-``std::string`` / ``std::basic_string<T>`` API, with a few variations:
-
-- :cpp:type:`pw::InlineString` provides overloads specific to character arrays.
- These perform compile-time capacity checks and are used for class template
- argument deduction. Like ``std::string``, character arrays are treated as
- null-terminated strings.
-- :cpp:type:`pw::InlineString` allows implicit conversions from
- ``std::string_view``. Specifying the capacity parameter is cumbersome, so
- implicit conversions are helpful. Also, implicitly creating a
- :cpp:type:`pw::InlineString` is less costly than creating a ``std::string``.
- As with ``std::string``, explicit conversions are required from types that
- convert to ``std::string_view``.
-- Functions related to dynamic memory allocation are not present (``reserve()``,
- ``shrink_to_fit()``, ``get_allocator()``).
-- ``resize_and_overwrite()`` only takes the ``Operation`` argument, since the
- underlying string buffer cannot be resized.
-
-See the `std::string documentation
-<https://en.cppreference.com/w/cpp/string/basic_string>`_ for full details.
-
-Key differences from ``std::string``
-------------------------------------
-- **Fixed capacity** -- Operations that add characters to the string beyond its
+``pw_string`` provides string classes and utility functions designed to
+prioritize safety and static allocation. The APIs are broadly similar to those
+of the string classes in the C++ standard library, so familiarity with those
+classes will provide some context around ``pw_string`` design decisions.
+
+------------
+InlineString
+------------
+:cpp:type:`pw::InlineString` / :cpp:class:`pw::InlineBasicString` are designed
+to match the ``std::string`` / ``std::basic_string<T>`` API as closely as
+possible, but with key differences to improve performance on embedded systems:
+
+- **Fixed capacity:** Operations that add characters to the string beyond its
capacity are an error. These trigger a ``PW_ASSERT`` at runtime. When
detectable, these situations trigger a ``static_assert`` at compile time.
-- **Minimal overhead** -- :cpp:type:`pw::InlineString` operations never
+- **Minimal overhead:** :cpp:type:`pw::InlineString` operations never
allocate. Reading the contents of the string is a direct memory access within
the string object, without pointer indirection.
-- **Constexpr support** -- :cpp:type:`pw::InlineString` works in ``constexpr``
+- **Constexpr support:** :cpp:type:`pw::InlineString` works in ``constexpr``
contexts, which is not supported by ``std::string`` until C++20.
-Safe Length Checking
---------------------
+We don't aim to provide complete API compatibility with
+``std::string`` / ``std::basic_string<T>``. Some areas of deviation include:
+
+- **Compile-time capacity checks:** :cpp:type:`InlineString` provides overloads
+ specific to character arrays. These perform compile-time capacity checks and
+ are used for class template argument deduction.
+- **Implicit conversions from** ``std::string_view`` **:** Specifying the
+ capacity parameter is cumbersome, so implicit conversions are helpful. Also,
+ implicitly creating a :cpp:type:`InlineString` is less costly than creating a
+ ``std::string``. As with ``std::string``, explicit conversions are required
+ from types that convert to ``std::string_view``.
+- **No dynamic allocation functions:** Functions that allocate memory, like
+ ``reserve()``, ``shrink_to_fit()``, and ``get_allocator()``, are simply not
+ present.
+
+Capacity
+========
+:cpp:type:`InlineBasicString` has a template parameter for the capacity, but the
+capacity does not need to be known by the user to use the string safely. The
+:cpp:type:`InlineBasicString` template inherits from a
+:cpp:type:`InlineBasicString` specialization with capacity of the reserved value
+``pw::InlineString<>::npos``. The actual capacity is stored in a single word
+alongside the size. This allows code to work with strings of any capacity
+through a ``InlineString<>`` or ``InlineBasicString<T>`` reference.
+
+Exceeding the capacity
+----------------------
+Any :cpp:type:`pw::InlineString` operations that exceed the string's capacity
+fail an assertion, resulting in a crash. Helpers are provided in
+``pw_string/util.h`` that return ``pw::Status::ResourceExhausted()`` instead of
+failing an assert when the capacity would be exceeded.
+
+------------------------
+String utility functions
+------------------------
+
+Safe length checking
+====================
This module provides two safer alternatives to ``std::strlen`` in case the
string is extremely long and/or potentially not null-terminated.
@@ -52,10 +73,3 @@ null-termination.
Second, a constexpr specialized form is offered where null termination is
required through :cpp:func:`pw::string::NullTerminatedLength`. This will only
return a length if the string is null-terminated.
-
-Exceeding the capacity
-----------------------
-Any :cpp:type:`pw::InlineString` operations that exceed the string's capacity
-fail an assertion, resulting in a crash. Helpers are provided in
-``pw_string/util.h`` that return ``pw::Status::ResourceExhausted()`` instead of
-failing an assert when the capacity would be exceeded.
diff --git a/pw_string/public/pw_string/string.h b/pw_string/public/pw_string/string.h
index daaa9a900..a6041f52a 100644
--- a/pw_string/public/pw_string/string.h
+++ b/pw_string/public/pw_string/string.h
@@ -42,19 +42,20 @@
namespace pw {
/// @brief `pw::InlineBasicString` is a fixed-capacity version of
-/// `std::basic_string`.
+/// `std::basic_string`. In brief:
///
-/// It is C++14-compatible and null-terminated. It stores the string contents
-/// inline and uses no dynamic memory. It implements mostly the same API as
-/// `std::basic_string`, but the capacity of the string is fixed at construction
-/// and cannot grow. Attempting to increase the size beyond the capacity
-/// triggers an assert. `pw::InlineBasicString` has a template parameter for the
-/// capacity, but the capacity does not have to be known to use the string. The
-/// `pw::InlineBasicString` template inherits from a `pw::InlineBasicString`
-/// specialization with capacity of the reserved value
-/// `pw::InlineString<>::npos`. The actual capacity is stored in a single word
-/// alongside the size. This allows code to work with strings of any capacity
-/// through a `pw::InlineString<>` or `pw::InlineBasicString<T>` reference.
+/// - It is C++14-compatible and null-terminated.
+/// - It stores the string contents inline and uses no dynamic memory.
+/// - It implements mostly the same API as `std::basic_string`, but the capacity
+/// of the string is fixed at construction and cannot grow. Attempting to
+/// increase the size beyond the capacity triggers an assert.
+///
+/// `pw::InlineBasicString` is efficient and compact. The current size and
+/// capacity are stored in a single word. Accessing its contents is a simple
+/// array access within the object, with no pointer indirection, even when
+/// working from a generic reference `pw::InlineBasicString<T>` where the
+/// capacity is not specified as a template argument. A string object can be
+/// used safely without the need to know its capacity.
///
/// See also `pw::InlineString`, which is an alias of
/// `pw::InlineBasicString<char>` and is equivalent to `std::string`.
@@ -576,17 +577,6 @@ constexpr bool operator>=(const T* lhs,
/// @brief `pw::InlineString` is an alias of `pw::InlineBasicString<char>` and
/// is equivalent to `std::string`.
-///
-/// `pw::InlineString` takes the fixed capacity as a template argument, but may
-/// be used generically without specifying the capacity. The capacity value is
-/// stored in a member variable, which the generic `pw::InlineString<>` /
-/// `pw::InlineBasicString<T>` specialization uses in place of the template
-/// parameter.
-///
-/// `pw::InlineString` is efficient and compact. The current size and capacity
-/// are stored in a single word. Accessing the contents of a `pw::InlineString`
-/// is a simple array access within the object, with no pointer indirection,
-/// even when working from a generic `pw::InlineString<>` reference.
template <string_impl::size_type kCapacity = string_impl::kGeneric>
using InlineString = InlineBasicString<char, kCapacity>;
diff --git a/pw_string/public/pw_string/string_builder.h b/pw_string/public/pw_string/string_builder.h
index 322546485..c3c9d1760 100644
--- a/pw_string/public/pw_string/string_builder.h
+++ b/pw_string/public/pw_string/string_builder.h
@@ -15,8 +15,8 @@
/// @file pw_string/string_builder.h
///
/// @brief `pw::StringBuilder` facilitates creating formatted strings in a
-/// fixed-sized buffer or `pw::InlineString`. It is designed to give the
-/// flexibility of `std::ostringstream`, but with a small footprint.
+/// fixed-sized buffer or in a `pw::InlineString`. It is designed to give the
+/// flexibility of std::ostringstream, but with a small footprint.
#include <algorithm>
#include <cstdarg>