#pragma once #include #include #include class String { typedef char* Iterator; typedef const char* ConstIterator; public: /* Constructs a String, which will take ownership of the given c-string. To create a String that makes its own * internal copy of the passed string, use String::from_cstring(). */ String(char* c_str); /* Constructs a String with precalculated length, which will take ownership of the given c-string. To create a * String that makes its own internal copy of the passed string, use String::from_cstring(). */ String(char* c_str, usize length); /* Constructs an empty String. */ String(); String(String&&); /* Implicit copying is disabled for Strings, as copy constructors cannot use value-based error handling. To copy a * string, please use the clone() method. */ String(const String&) = delete; String& operator=(String&&); /* Implicit copying is disabled for Strings, as copy constructors cannot use value-based error handling. To copy a * string, please use the clone() method. */ String& operator=(const String&) = delete; ~String(); /* Creates a copy of this String and returns it. */ Result clone() const; /* Creates a copy of a specific segment of this String and returns it. */ Result substring(usize begin, usize size) const; /* Splits a String with a delimiter. */ Result> split(StringView delim) const { return view().split(delim); } /* Splits a String into two parts with a delimiter. */ Result> split_once(char delim) const { return view().split_once(delim); } /* Creates a single String consisting of a list of strings separated by a delimiter. */ static Result join(const Vector& vec, StringView delim); /* Creates a single String consisting of a list of strings separated by a delimiter. */ static Result join(const Vector& vec, StringView delim); /* Removes all trailing characters contained in delim. */ void trim(StringView delim); static Result format(const String& fmt, ...); static Result format(StringView fmt, ...); static Result vformat(StringView fmt, va_list ap); static Result from_cstring(const char* str); static Result from_string_view(StringView str); static int compare(const String* a, const String* b); const char* chars() const { return m_inline ? m_inline_storage : m_string; } char* mutable_data() { return m_inline ? m_inline_storage : m_string; } usize length() const { return m_length; } bool is_empty() const { return m_length == 0; } StringView view() const { return { chars(), m_length }; } const char& operator[](usize) const; Iterator begin() { return m_inline ? m_inline_storage : m_string; } ConstIterator begin() const { return chars(); } Iterator end() { return begin() + m_length; } ConstIterator end() const { return begin() + m_length; } private: union { char* m_string { nullptr }; char m_inline_storage[sizeof(char*)]; }; bool m_inline { true }; usize m_length { 0 }; void empty(); };