29#include "pw_preprocessor/compiler.h"
30#include "pw_span/span.h"
31#include "pw_status/status.h"
32#include "pw_status/status_with_size.h"
34#include "pw_string/to_string.h"
93 : buffer_(buffer), size_(&inline_size_), inline_size_(0) {
99 {
reinterpret_cast<char*
>(buffer.data()), buffer.size_bytes()}) {}
102 : buffer_(string.data(), string.
max_size() + 1),
103 size_(&string.length_),
116 const char* data()
const {
return buffer_.data(); }
117 const char*
c_str()
const {
return data(); }
122 std::string_view
view()
const {
return std::string_view(data(),
size()); }
126 operator std::string_view()
const {
return view(); }
131 return span(
reinterpret_cast<const std::byte*
>(buffer_.data()),
size());
161 size_t size()
const {
return *size_; }
164 size_t max_size()
const {
return buffer_.empty() ? 0u : buffer_.size() - 1; }
171 status_ =
static_cast<unsigned char>(
OkStatus().
code());
172 last_status_ =
static_cast<unsigned char>(
OkStatus().
code());
213 size_t count = std::string_view::npos);
217 template <
typename T>
221 if constexpr (std::is_convertible_v<T, std::string_view>) {
223 }
else if constexpr (std::is_convertible_v<T, span<const std::byte>>) {
226 HandleStatusWithSize(ToString(value, buffer_.subspan(
size())));
233 return append(value ?
"true" :
"false");
242 return append(string::kNullPointerString);
276 size_(&inline_size_),
277 inline_size_(*other.size_),
278 status_(other.status_),
279 last_status_(other.last_status_) {}
285 static constexpr unsigned char StatusCode(
Status status) {
286 return static_cast<unsigned char>(
status.
code());
289 void WriteBytes(span<const std::byte> data);
291 size_t ResizeAndTerminate(
size_t chars_to_append);
293 void HandleStatusWithSize(StatusWithSize written);
295 constexpr void NullTerminate() {
296 if (!buffer_.empty()) {
297 buffer_[
size()] =
'\0';
301 void SetErrorStatus(Status
status);
303 const span<char> buffer_;
305 InlineString<>::size_type* size_;
310 InlineString<>::size_type inline_size_;
311 unsigned char status_ = StatusCode(
OkStatus());
312 unsigned char last_status_ = StatusCode(
OkStatus());
324template <
size_t kSizeBytes>
335 template <
size_t kOtherSizeBytes>
339 "A StringBuffer cannot be copied into a smaller buffer");
343 template <
size_t kOtherSizeBytes>
345 assign<kOtherSizeBytes>(other);
350 assign<kSizeBytes>(other);
354 template <
size_t kOtherSizeBytes>
357 "A StringBuffer cannot be copied into a smaller buffer");
358 CopySizeAndStatus(other);
370 static constexpr size_t max_size() {
return kSizeBytes - 1; }
374 template <
typename... Args>
380 template <
typename T>
381 StringBuffer& operator<<(T&& value) {
382 static_cast<StringBuilder&
>(*this) << std::forward<T>(value);
387 template <
size_t kOtherSize>
388 void CopyContents(
const StringBuffer<kOtherSize>& other) {
389 std::memcpy(buffer_, other.data(), other.size() + 1);
392 static_assert(kSizeBytes >= 1u,
"StringBuffers must be at least 1 byte long");
393 char buffer_[kSizeBytes];
398namespace string_internal {
406inline constexpr size_t kDefaultMinimumStringBufferSize = 24;
411inline constexpr size_t kDefaultArgumentSize = 4;
415constexpr size_t ArgLength() {
416 using Arg = std::remove_reference_t<T>;
419 if constexpr (std::is_array_v<Arg>) {
420 using Element = std::remove_reference_t<decltype(std::declval<Arg>()[0])>;
422 if constexpr (std::is_same_v<Element, const char>) {
423 return std::extent_v<Arg> > 0u ? std::extent_v<Arg> - 1 : size_t(0);
427 return kDefaultArgumentSize;
431template <
typename... Args>
432constexpr size_t DefaultStringBufferSize() {
433 return std::max((
size_t(1) + ... + ArgLength<Args>()),
434 kDefaultMinimumStringBufferSize);
440template <
size_t kBufferSize,
typename... Args>
441auto InitializeStringBuffer(
const Args&... args) {
442 return (StringBuffer<kBufferSize>() << ... << args);
470template <
size_t kBufferSize = 0u,
typename... Args>
471auto MakeString(Args&&... args) {
472 constexpr size_t kSize =
473 kBufferSize == 0u ? string_internal::DefaultStringBufferSize<Args...>()
475 return string_internal::InitializeStringBuffer<kSize>(args...);
constexpr Code code() const
Definition: status.h:341
constexpr bool ok() const
Definition: status.h:346
const char * str() const
Definition: status.h:433
Definition: status_with_size.h:51
Definition: string_builder.h:325
StringBuffer(StringBuffer &&other)=delete
StringBuffers are not movable: the underlying data must be copied.
StringBuffer & operator=(StringBuffer &&other)=delete
StringBuffers are not movable: the underlying data must be copied.
Definition: string_builder.h:89
StringBuilder & Format(const char *format,...)
bool empty() const
True if the string is empty.
Definition: string_builder.h:158
size_t size() const
Returns the current length of the string, excluding the null terminator.
Definition: string_builder.h:161
void push_back(char ch)
Definition: string_builder.h:177
StringBuilder & operator<<(const T &value)
Definition: string_builder.h:218
Status last_status() const
The status from the last operation. May be OK while status() is not OK.
Definition: string_builder.h:152
void clear_status()
Sets the statuses to OkStatus();.
Definition: string_builder.h:170
void resize(size_t new_size)
Status status() const
Definition: string_builder.h:144
span< const std::byte > as_bytes() const
Definition: string_builder.h:130
StringBuilder & append(size_t count, char ch)
Appends the provided character count times.
void clear()
Clears the string and resets its error state.
StatusWithSize status_with_size() const
Returns status() and size() as a StatusWithSize.
Definition: string_builder.h:147
size_t max_size() const
Returns the maximum length of the string, excluding the null terminator.
Definition: string_builder.h:164
StringBuilder & append(std::string_view str, size_t pos, size_t count=std::string_view::npos)
StringBuilder & FormatVaList(const char *format, va_list args)
void pop_back()
Definition: string_builder.h:181
StringBuilder & operator<<(bool value)
Provide a few additional operator<< overloads that reduce code size.
Definition: string_builder.h:232
constexpr StringBuilder(span< char > buffer)
Creates an empty pw::StringBuilder.
Definition: string_builder.h:92
const char * c_str() const
Definition: string_builder.h:117
bool ok() const
True if status() is OkStatus().
Definition: string_builder.h:155
StringBuilder & append(const char *str, size_t count)
StringBuilder(const StringBuilder &)=delete
StringBuilder & append(const char *str)
StringBuilder & append(std::string_view str)
Appends a std::string_view to the end of the StringBuilder.
std::string_view view() const
Definition: string_builder.h:122
Definition: span_impl.h:235
#define PW_PRINTF_FORMAT(format_index, parameter_index)
Definition: compiler.h:89
#define PW_NO_SANITIZE(check)
Definition: compiler.h:158
pw_Status
C API for status codes. In C++, use the pw::Status class instead.
Definition: status.h:40
constexpr Status OkStatus()
Definition: status.h:450
The Pigweed namespace.
Definition: alignment.h:27
pw::InlineBasicString and pw::InlineString are safer alternatives to std::basic_string and std::strin...