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