| 23 | #include <type_traits> |
| 24 | |
| 25 | class StringBuilder { |
| 26 | char* buffer; |
| 27 | char* current; |
| 28 | size_t remaining; |
| 29 | |
| 30 | public: |
| 31 | StringBuilder(char* buf, size_t size); |
| 32 | |
| 33 | template<size_t N> |
| 34 | StringBuilder(char (&buf)[N]) : StringBuilder(buf, N) {} |
| 35 | |
| 36 | StringBuilder& operator<<(const char* str); |
| 37 | |
| 38 | template<typename T, typename = std::enable_if_t<std::is_integral_v<T>>> |
| 39 | StringBuilder& operator<<(T val) { |
| 40 | if (remaining > 1) { |
| 41 | auto result = std::to_chars(current, current + remaining - 1, val); |
| 42 | if (result.ec == std::errc()) { |
| 43 | const size_t written = result.ptr - current; |
| 44 | current = result.ptr; |
| 45 | remaining -= written; |
| 46 | *current = '\0'; |
| 47 | } |
| 48 | // If result.ec != std::errc(), the number is too long, so don't write anything |
| 49 | } |
| 50 | return *this; |
| 51 | } |
| 52 | |
| 53 | const char* get() const { return buffer; } |
| 54 | }; |
| 55 | |
| 56 | #endif // __STRING_BUILDER_HPP__ |
nothing calls this directly
no outgoing calls
no test coverage detected