#pragma once #include #include namespace BAN { class String { public: using size_type = size_t; public: String(); String(const String&); String(String&&); String(StringView); ~String(); template static String formatted(const char* format, const Args&... args); String& operator=(const String&); String& operator=(String&&); String& operator=(StringView); ErrorOr push_back(char); ErrorOr insert(char, size_type); ErrorOr insert(StringView, size_type); ErrorOr append(StringView); ErrorOr append(const String&); void pop_back(); void remove(size_type); void erase(size_type, size_type); void clear(); char operator[](size_type) const; char& operator[](size_type); bool operator==(const String&) const; bool operator==(StringView) const; bool operator==(const char*) const; ErrorOr resize(size_type, char = '\0'); ErrorOr reserve(size_type); ErrorOr shrink_to_fit(); StringView sv() const; bool empty() const; size_type size() const; size_type capacity() const; const char* data() const; private: ErrorOr ensure_capacity(size_type); ErrorOr copy_impl(StringView); void move_impl(String&&); private: char* m_data = nullptr; size_type m_capacity = 0; size_type m_size = 0; }; template String String::formatted(const char* format, const Args&... args) { String result; BAN::Formatter::print([&](char c){ result.push_back(c); }, format, args...); return result; } } namespace BAN::Formatter { template void print_argument(F putc, const String& string, const ValueFormat&) { for (String::size_type i = 0; i < string.size(); i++) putc(string[i]); } }