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());
169 size_t size()
const {
return *size_; }
172 size_t max_size()
const {
return buffer_.empty() ? 0u : buffer_.size() - 1; }
179 status_ =
static_cast<unsigned char>(
OkStatus().
code());
180 last_status_ =
static_cast<unsigned char>(
OkStatus().
code());
221 size_t count = std::string_view::npos);
225 template <
typename T>
229 if constexpr (std::is_convertible_v<T, std::string_view>) {
231 }
else if constexpr (std::is_convertible_v<T, span<const std::byte>>) {
234 HandleStatusWithSize(ToString(value, buffer_.subspan(
size())));
241 return append(value ?
"true" :
"false");
250 return append(string::kNullPointerString);
284 size_(&inline_size_),
285 inline_size_(*other.size_),
286 status_(other.status_),
287 last_status_(other.last_status_) {}
293 static constexpr unsigned char StatusCode(
Status status) {
294 return static_cast<unsigned char>(
status.
code());
297 void WriteBytes(span<const std::byte> data);
299 size_t ResizeAndTerminate(
size_t chars_to_append);
301 void HandleStatusWithSize(StatusWithSize written);
303 constexpr void NullTerminate() {
304 if (!buffer_.empty()) {
305 buffer_[
size()] =
'\0';
309 void SetErrorStatus(Status
status);
311 const span<char> buffer_;
313 InlineString<>::size_type* size_;
318 InlineString<>::size_type inline_size_;
319 unsigned char status_ = StatusCode(
OkStatus());
320 unsigned char last_status_ = StatusCode(
OkStatus());
332template <
size_t kSizeBytes>
343 template <
size_t kOtherSizeBytes>
347 "A StringBuffer cannot be copied into a smaller buffer");
351 template <
size_t kOtherSizeBytes>
353 assign<kOtherSizeBytes>(other);
358 assign<kSizeBytes>(other);
362 template <
size_t kOtherSizeBytes>
365 "A StringBuffer cannot be copied into a smaller buffer");
366 CopySizeAndStatus(other);
378 static constexpr size_t max_size() {
return kSizeBytes - 1; }
382 template <
typename... Args>
388 template <
typename T>
389 StringBuffer& operator<<(T&& value) {
390 static_cast<StringBuilder&
>(*this) << std::forward<T>(value);
395 template <
size_t kOtherSize>
396 void CopyContents(
const StringBuffer<kOtherSize>& other) {
397 std::memcpy(buffer_, other.data(), other.size() + 1);
400 static_assert(kSizeBytes >= 1u,
"StringBuffers must be at least 1 byte long");
401 char buffer_[kSizeBytes];
406namespace string_internal {
414inline constexpr size_t kDefaultMinimumStringBufferSize = 24;
419inline constexpr size_t kDefaultArgumentSize = 4;
423constexpr size_t ArgLength() {
424 using Arg = std::remove_reference_t<T>;
427 if constexpr (std::is_array_v<Arg>) {
428 using Element = std::remove_reference_t<decltype(std::declval<Arg>()[0])>;
430 if constexpr (std::is_same_v<Element, const char>) {
431 return std::extent_v<Arg> > 0u ? std::extent_v<Arg> - 1 : size_t(0);
435 return kDefaultArgumentSize;
439template <
typename... Args>
440constexpr size_t DefaultStringBufferSize() {
441 return std::max((
size_t(1) + ... + ArgLength<Args>()),
442 kDefaultMinimumStringBufferSize);
448template <
size_t kBufferSize,
typename... Args>
449auto InitializeStringBuffer(
const Args&... args) {
450 return (StringBuffer<kBufferSize>() << ... << args);
478template <
size_t kBufferSize = 0u,
typename... Args>
479auto MakeString(Args&&... args) {
480 constexpr size_t kSize =
481 kBufferSize == 0u ? string_internal::DefaultStringBufferSize<Args...>()
483 return string_internal::InitializeStringBuffer<kSize>(args...);
constexpr Code code() const
Definition: status.h:209
constexpr bool ok() const
Definition: status.h:214
const char * str() const
Definition: status.h:286
Definition: status_with_size.h:51
Definition: string_builder.h:333
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:166
size_t size() const
Returns the current length of the string, excluding the null terminator.
Definition: string_builder.h:169
void push_back(char ch)
Definition: string_builder.h:185
StringBuilder & operator<<(const T &value)
Definition: string_builder.h:226
Status last_status() const
The status from the last operation. May be OK while status() is not OK.
Definition: string_builder.h:160
void clear_status()
Sets the statuses to OkStatus();.
Definition: string_builder.h:178
void resize(size_t new_size)
Status status() const
Definition: string_builder.h:152
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:155
size_t max_size() const
Returns the maximum length of the string, excluding the null terminator.
Definition: string_builder.h:172
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:189
StringBuilder & operator<<(bool value)
Provide a few additional operator<< overloads that reduce code size.
Definition: string_builder.h:240
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:163
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
Definition: status.h:38
constexpr Status OkStatus()
Definition: status.h:297
The Pigweed namespace.
Definition: alignment.h:27
pw::InlineBasicString and pw::InlineString are safer alternatives to std::basic_string and std::strin...