#include #include #include String::String() { m_inline = true; m_length = 0; memset(m_inline_storage, 0, sizeof(m_inline_storage)); } String::String(String&& other) { m_inline = other.m_inline; m_string = other.m_string; m_length = other.m_length; if (m_inline) memcpy(m_inline_storage, other.m_inline_storage, sizeof(m_inline_storage)); other.m_string = nullptr; } String::String(char* c_str) { check(c_str); m_string = c_str; m_inline = false; m_length = strlen(m_string); } String::String(char* c_str, usize length) { check(c_str); m_string = c_str; m_inline = false; m_length = length; } String::~String() { if (!m_inline) free_impl(m_string); } Result String::clone() const { return from_string_literal(chars()); } Result String::substring(usize begin, usize size) const { if (begin + size >= size) return err(EINVAL); char* const dup = strndup(chars() + begin, size); if (!dup) return err(ENOMEM); return String { dup, size }; } const char& String::operator[](usize index) const { expect(index < m_length, "index out of range"); return chars()[index]; } Result String::from_string_literal(const char* str) { usize len = strlen(str); if (len < sizeof(m_inline_storage)) { String result; result.m_inline = true; result.m_length = len; strncpy(result.m_inline_storage, str, sizeof(m_inline_storage)); return result; } char* const dup = strdup(str); if (!dup) return err(ENOMEM); return String { dup }; }