diff options
author | Keir Mierle <keir@google.com> | 2023-10-28 00:16:50 +0000 |
---|---|---|
committer | CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2023-10-28 00:16:50 +0000 |
commit | 87ce3c98de71f1d2f6a29eb048c08800985d361d (patch) | |
tree | 3f529d688428ff1d59e6cf55c58d3c424efa3a88 /pw_string | |
parent | 1863631ae76c219f94b4df465370e861af53c33d (diff) | |
download | pigweed-87ce3c98de71f1d2f6a29eb048c08800985d361d.tar.gz |
pw_string: Docs tweaks
- Make titles consistent
- Add Bazel and CMake to Get Started build section
- Add module name to sub-pages for less confusing navigation
- Add sub-page callout cards to bottom of pw_string landing page
- Move size report to a new "Code Size Analysis" page
- Fix inconsistent use of pw:: prefix for symbols in titles
- Switch headings to active imperative
- Rename "Guide" to "Get Started & Guide" and move relevant content
- Rename "Design" to "Design & Roadmap" and move relevant content
Change-Id: Ib41527a0cab4b37f2a678baba497d0a31f7a96ef
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/177883
Reviewed-by: Kayce Basques <kayce@google.com>
Pigweed-Auto-Submit: Keir Mierle <keir@google.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed-service-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'pw_string')
-rw-r--r-- | pw_string/BUILD.gn | 1 | ||||
-rw-r--r-- | pw_string/api.rst | 5 | ||||
-rw-r--r-- | pw_string/code_size.rst | 40 | ||||
-rw-r--r-- | pw_string/design.rst | 23 | ||||
-rw-r--r-- | pw_string/docs.rst | 63 | ||||
-rw-r--r-- | pw_string/guide.rst | 157 |
6 files changed, 189 insertions, 100 deletions
diff --git a/pw_string/BUILD.gn b/pw_string/BUILD.gn index 8c267eeec..ef3fda62c 100644 --- a/pw_string/BUILD.gn +++ b/pw_string/BUILD.gn @@ -205,6 +205,7 @@ pw_test("util_test") { pw_doc_group("docs") { sources = [ "api.rst", + "code_size.rst", "design.rst", "docs.rst", "guide.rst", diff --git a/pw_string/api.rst b/pw_string/api.rst index 7915ccc75..f90918591 100644 --- a/pw_string/api.rst +++ b/pw_string/api.rst @@ -5,12 +5,12 @@ API Reference ============= .. pigweed-module-subpage:: :name: pw_string - :tagline: Efficient, easy, and safe string manipulation + :tagline: pw_string: Efficient, easy, and safe string manipulation -------- Overview -------- -This module provides two types of strings, and utility functions for working +This module provides two types of strings and utility functions for working with strings. **pw::StringBuilder** @@ -89,7 +89,6 @@ pw::string::Format() .. doxygenfunction:: pw::string::FormatOverwrite(InlineString<>& string, const char* format, ...) .. doxygenfunction:: pw::string::FormatOverwriteVaList(InlineString<>& string, const char* format, va_list args) - pw::string::NullTerminatedLength() ---------------------------------- .. doxygenfunction:: pw::string::NullTerminatedLength(const char* str, size_t max_len) diff --git a/pw_string/code_size.rst b/pw_string/code_size.rst new file mode 100644 index 000000000..575c1cfe9 --- /dev/null +++ b/pw_string/code_size.rst @@ -0,0 +1,40 @@ +.. _module-pw_string-size-reports: + +================== +Code Size Analysis +================== +.. pigweed-module-subpage:: + :name: pw_string + :tagline: pw_string: Efficient, easy, and safe string manipulation + +Save code space by replacing ``snprintf`` +========================================= +The C standard library function ``snprintf`` is commonly used for string +formatting. However, it isn't optimized for embedded systems, and using it will +bring in a lot of other standard library code that will inflate your binary +size. + +Size comparison: snprintf versus pw::StringBuilder +-------------------------------------------------- +The fixed code size cost of :cpp:type:`pw::StringBuilder` is smaller than +that of ``std::snprintf``. Using only :cpp:type:`pw::StringBuilder`'s ``<<`` and +``append`` methods instead of ``snprintf`` leads to significant code size +reductions. + +However, there are cases when the incremental code size cost of +:cpp:type:`pw::StringBuilder` is similar to that of ``snprintf``. For example, +each argument to :cpp:type:`pw::StringBuilder`'s ``<<`` method expands to a +function call, but one or two :cpp:type:`pw::StringBuilder` appends may still +have a smaller code size impact than a single ``snprintf`` call. Using +:cpp:type:`pw::StringBuilder` error handling will also impact code size in a +way that is comparable to ``snprintf``. + +.. include:: string_builder_size_report + +Size comparison: snprintf versus pw::string::Format +--------------------------------------------------- +The ``pw::string::Format`` functions have a small, fixed code size +cost. However, relative to equivalent ``std::snprintf`` calls, there is no +incremental code size cost to using ``pw::string::Format``. + +.. include:: format_size_report diff --git a/pw_string/design.rst b/pw_string/design.rst index 43fa4cc35..32c2eb4cf 100644 --- a/pw_string/design.rst +++ b/pw_string/design.rst @@ -1,20 +1,20 @@ .. _module-pw_string-design: ================ -pw_string design +Design & Roadmap ================ .. pigweed-module-subpage:: :name: pw_string - :tagline: Efficient, easy, and safe string manipulation + :tagline: pw_string: Efficient, easy, and safe string manipulation ``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 ------------- +-------------------------- +Design of pw::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: @@ -60,9 +60,9 @@ 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 ------------------------- +---------------------------------- +Design of string utility functions +---------------------------------- Safe length checking ==================== @@ -77,3 +77,10 @@ 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. + +------- +Roadmap +------- +* The fixed size cost of :cpp:type:`pw::StringBuilder` can be dramatically + reduced by limiting support for 64-bit integers. +* ``pw_string`` may be integrated with :ref:`module-pw_tokenizer`. diff --git a/pw_string/docs.rst b/pw_string/docs.rst index 120377054..cbd8906bf 100644 --- a/pw_string/docs.rst +++ b/pw_string/docs.rst @@ -86,48 +86,43 @@ meets your needs. gives you the flexibility to move to smaller platforms later with much less rework. -.. _module-pw_string-get-started: +.. toctree:: + :hidden: + :maxdepth: 1 ---------------- -Getting Started ---------------- + guide + api + design + code_size -.. tab-set:: +.. grid:: 2 - .. tab-item:: GN + .. grid-item-card:: :octicon:`rocket` Get Started & Guides + :link: module-pw_string-get-started + :link-type: ref + :class-item: sales-pitch-cta-primary - Add ``$dir_pw_string`` to the ``deps`` list in your ``pw_executable()`` - build target: + Integrate pw_string into your project and learn common use cases - .. code-block:: + .. grid-item-card:: :octicon:`code-square` API Reference + :link: module-pw_string-api + :link-type: ref + :class-item: sales-pitch-cta-secondary - pw_executable("...") { - # ... - deps = [ - # ... - "$dir_pw_string", - # ... - ] - } + Detailed description of the pw_string's classes and methods - See `//source/BUILD.gn <https://pigweed.googlesource.com/pigweed/sample_project/+/refs/heads/main/source/BUILD.gn>`_ - in the Pigweed Sample Project for an example. +.. grid:: 2 - .. tab-item:: Zephyr + .. grid-item-card:: :octicon:`code-square` Design & Roadmap + :link: module-pw_string-design + :link-type: ref + :class-item: sales-pitch-cta-secondary - Add ``CONFIG_PIGWEED_STRING=y`` to the Zephyr project's configuration. + Learn why pw_string is designed the way it is, and upcoming plans -------- -Roadmap -------- -* The fixed size cost of :cpp:type:`pw::StringBuilder` can be dramatically - reduced by limiting support for 64-bit integers. -* ``pw_string`` may be integrated with :ref:`module-pw_tokenizer`. + .. grid-item-card:: :octicon:`code-square` Code Size Analysis + :link: module-pw_string-size-reports + :link-type: ref + :class-item: sales-pitch-cta-secondary -.. toctree:: - :hidden: - :maxdepth: 1 - - design - guide - api + Understand pw_string's code footprint and savings potential diff --git a/pw_string/guide.rst b/pw_string/guide.rst index a723948b4..2e313dc0c 100644 --- a/pw_string/guide.rst +++ b/pw_string/guide.rst @@ -1,22 +1,103 @@ .. _module-pw_string-guide: -================ -pw_string: Guide -================ +==================== +Get Started & Guides +==================== .. pigweed-module-subpage:: :name: pw_string - :tagline: Efficient, easy, and safe string manipulation + :tagline: pw_string: Efficient, easy, and safe string manipulation -InlineString and StringBuilder? -=============================== -Use :cpp:type:`pw::InlineString` if you need: +.. _module-pw_string-get-started: + +Get Started +=========== +.. tab-set:: + + .. tab-item:: Bazel + + Add ``@pigweed//pw_string`` to the ``deps`` list in your Bazel target: + + .. code-block:: + + cc_library("...") { + # ... + deps = [ + # ... + "@pigweed//pw_string", + # ... + ] + } + + If only one part of the module is needed, depend only on it; for example + ``@pigweed//pw_string:format``. + + This assumes ``@pigweed`` is the name you pulled Pigweed into your Bazel + ``WORKSPACE`` as. + + .. tab-item:: GN + + Add ``$dir_pw_string`` to the ``deps`` list in your ``pw_executable()`` + build target: + + .. code-block:: + + pw_executable("...") { + # ... + deps = [ + # ... + "$dir_pw_string", + # ... + ] + } + + See `//source/BUILD.gn <https://pigweed.googlesource.com/pigweed/sample_project/+/refs/heads/main/source/BUILD.gn>`_ + in the Pigweed Sample Project for an example. + + .. tab-item:: CMake + + Add ``pw_string`` to your ``pw_add_library`` or similar CMake target: + + .. code-block:: + + pw_add_library(my_library STATIC + HEADERS + ... + PRIVATE_DEPS + # ... + pw_string + # ... + ) + + For a narrower dependency, depend on subtargets like + ``pw_string.builder``, etc. + + .. tab-item:: Zephyr + + There are two ways to use ``pw_string`` from a Zephyr project: + + #. Depend on ``pw_string`` in your CMake target (see CMake tab). This is + Pigweed Team's suggested approach since it enables precise CMake + dependency analysis. + + #. Add ``CONFIG_PIGWEED_STRING=y`` to the Zephyr project's configuration, + which causes ``pw_string`` to become a global dependency and have the + includes exposed to all targets. Pigweed team does not recommend this + approach, though it is the typical Zephyr solution. + +Choose between pw::InlineString and pw::StringBuilder +===================================================== +`pw::InlineString` is intended to replace typical null terminated character +arrays in embedded data structures. Use :cpp:type:`pw::InlineString` if you +need: * Compatibility with ``std::string`` * Storage internal to the object * A string object to persist in other data structures * Lower code size overhead -Use :cpp:class:`pw::StringBuilder` if you need: +`pw::StringBuilder` is intended to ease constructing strings in external data; +typically created on the stack and disposed of in the same function. Use +:cpp:class:`pw::StringBuilder` if you need: * Compatibility with ``std::ostringstream``, including custom object support * Storage external to the object @@ -63,8 +144,8 @@ constructing a string for external use. } -Building strings with pw::StringBuilder -======================================= +Build a string with pw::StringBuilder +===================================== The following shows basic use of a :cpp:class:`pw::StringBuilder`. .. code-block:: cpp @@ -93,8 +174,8 @@ The following shows basic use of a :cpp:class:`pw::StringBuilder`. return sb.status(); } -Building strings with pw::InlineString -====================================== +Build a string with pw::InlineString +==================================== :cpp:type:`pw::InlineString` objects must be constructed by specifying a fixed capacity for the string. @@ -130,8 +211,8 @@ capacity for the string. FunctionThatTakesAnInlineString(std::string_view("1234", 4)); -Building strings inside InlineString with a StringBuilder -========================================================= +Build a string inside an pw::InlineString with a pw::StringBuilder +================================================================== :cpp:class:`pw::StringBuilder` can build a string in a :cpp:type:`pw::InlineString`: @@ -146,8 +227,8 @@ Building strings inside InlineString with a StringBuilder // inline_str contains "456" } -Passing InlineStrings as parameters -=================================== +Pass an pw::InlineString object as a parameter +============================================== :cpp:type:`pw::InlineString` objects can be passed to non-templated functions via type erasure. This saves code size in most cases, since it avoids template expansions triggered by string size differences. @@ -196,8 +277,8 @@ Known size strings return string; }(); -Compact initialization of InlineStrings -======================================= +Initialization of pw::InlineString objects +=========================================== :cpp:type:`pw::InlineBasicString` supports class template argument deduction (CTAD) in C++17 and newer. Since :cpp:type:`pw::InlineString` is an alias, CTAD is not supported until C++20. @@ -211,9 +292,9 @@ is not supported until C++20. // In C++20, CTAD may be used with the pw::InlineString alias. pw::InlineString my_other_string("123456789"); -Supporting custom types with StringBuilder -========================================== -As with ``std::ostream``, StringBuilder supports printing custom types by +Custom types with pw::StringBuilder +=================================== +As with ``std::ostream``, pw::StringBuilder supports printing custom types by overriding the ``<<`` operator. This is is done by defining ``operator<<`` in the same namespace as the custom type. For example: @@ -249,37 +330,3 @@ This example shows how to specialize ``pw::ToString``: } } // namespace pw - -.. _module-pw_string-size-reports: - -Saving code space by replacing ``snprintf`` -=========================================== -The C standard library function ``snprintf`` is commonly used for string -formatting. However, it isn't optimized for embedded systems, and using it will -bring in a lot of other standard library code that will inflate your binary -size. - -Size comparison: snprintf versus pw::StringBuilder --------------------------------------------------- -The fixed code size cost of :cpp:type:`pw::StringBuilder` is smaller than -that of ``std::snprintf``. Using only :cpp:type:`pw::StringBuilder`'s ``<<`` and -``append`` methods instead of ``snprintf`` leads to significant code size -reductions. - -However, there are cases when the incremental code size cost of -:cpp:type:`pw::StringBuilder` is similar to that of ``snprintf``. For example, -each argument to :cpp:type:`pw::StringBuilder`'s ``<<`` method expands to a -function call, but one or two :cpp:type:`pw::StringBuilder` appends may still -have a smaller code size impact than a single ``snprintf`` call. Using -:cpp:type:`pw::StringBuilder` error handling will also impact code size in a -way that is comparable to ``snprintf``. - -.. include:: string_builder_size_report - -Size comparison: snprintf versus pw::string::Format ---------------------------------------------------- -The ``pw::string::Format`` functions have a small, fixed code size -cost. However, relative to equivalent ``std::snprintf`` calls, there is no -incremental code size cost to using ``pw::string::Format``. - -.. include:: format_size_report |