blob: b27ead11338eab52290937668697b1145209439c [file] [log] [blame]
Tyler Chatowfcf16f42020-07-26 12:41:36 -07001#ifndef AOS_FAST_STRING_BUILDER_H_
2#define AOS_FAST_STRING_BUILDER_H_
3
4#include <ostream>
5#include <string>
6#include <type_traits>
7
Austin Schuh99f7c6a2024-06-25 22:07:44 -07008#include "absl/log/check.h"
9#include "absl/log/log.h"
Tyler Chatowfcf16f42020-07-26 12:41:36 -070010#include "absl/strings/numbers.h"
11#include "absl/strings/str_format.h"
Tyler Chatowfcf16f42020-07-26 12:41:36 -070012
13namespace aos {
14
15// Simplified string builder which is faster than standard classes
16// (std::string::append(), std::ostringstream). Reduces copies on insertion
17// and retrieval, uses fast number to string conversions, and allows reuse
18// of the internal buffer.
19class FastStringBuilder {
20 public:
21 FastStringBuilder(std::size_t initial_size = 64);
22
23 // Convert bools from integer representation to "true" and "false".
24 // Defaults on.
25 void set_bool_to_str(bool bool_to_str) { bool_to_str_ = bool_to_str; }
26
27 // Clears result, allows for reuse of builder without reallocation.
28 // Invalidates Result()
29 void Reset();
30
31 // Returns a temporary view to the string result. Invalidated on destruction
32 // of builder, after calling Reset(), or after calling MoveResult().
33 std::string_view Result() const;
34
35 // Release the string held by the builder. Resets builder and invalidates
36 // Result().
37 std::string MoveResult();
38
39 // Append integer to result, converted to string representation.
40 template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
Brian J Griglak043e0e22022-08-18 12:51:18 -060041 void AppendInt(T val, bool use_hex = false);
Tyler Chatowfcf16f42020-07-26 12:41:36 -070042
43 void Append(std::string_view);
44
45 void Append(const char *c) { Append(std::string_view(c)); }
46
47 // Append character to result as character.
48 void AppendChar(char);
49
50 // Append float or double to result, converted to string representation
51 void Append(float);
52
53 void Append(double);
54
55 // Append bool to result. set_bool_to_str() toggles between integer and string
56 // representation.
57 void AppendBool(bool);
58
59 // Prints the current result to output
60 friend std::ostream &operator<<(std::ostream &os,
61 const FastStringBuilder &builder);
62
63 private:
64 static const inline std::string kTrue = "true", kFalse = "false";
65
66 // Allocate additional space of at least chars_needed relative to index_.
67 void Resize(std::size_t chars_needed);
68
69 std::string str_;
70 bool bool_to_str_ = true;
71};
72
73template <typename T, typename>
Brian J Griglak043e0e22022-08-18 12:51:18 -060074void FastStringBuilder::AppendInt(T val, bool use_hex) {
75 if (use_hex) {
Philipp Schrader790cb542023-07-05 21:06:52 -070076 // This is not fast like the decimal path, but hex should be used in limited
77 // cases.
Brian J Griglak043e0e22022-08-18 12:51:18 -060078 std::stringstream ss;
79 ss << std::hex << val;
80 str_ += ss.str();
81 } else {
82 std::size_t index = str_.size();
83 Resize(absl::numbers_internal::kFastToBufferSize);
Philipp Schrader790cb542023-07-05 21:06:52 -070084 char *end =
85 absl::numbers_internal::FastIntToBuffer(val, str_.data() + index);
Brian J Griglak043e0e22022-08-18 12:51:18 -060086 str_.resize(end - str_.data());
87 }
Tyler Chatowfcf16f42020-07-26 12:41:36 -070088}
89
90} // namespace aos
91
92#endif // AOS_FAST_STRING_BUIDLER_H_