/** * @file RefString.h * @author apio (cloudapio.eu) * @brief Reference-counted, trivially-copyable, immutable string type. * * @copyright Copyright (c) 2024, the Luna authors. * */ #pragma once #include #include #include #include #include #include class RefString { typedef const char* ConstIterator; public: /* Constructs an empty String. */ RefString(); RefString(RefString&&); RefString(const RefString&); RefString& operator=(const RefString&); bool operator==(const RefString& other) const { return !compare(this, &other); } ~RefString() = default; /* 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().ref_split(delim); } /* Splits a String into two parts with a delimiter. */ Result> split_once(char delim) const { return view().ref_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); 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 Result from_string(const String& str); static int compare(const RefString* a, const RefString* b); const char* chars() const; usize length() const { return m_string_data ? m_string_data->length : 0; } bool is_empty() const { return length() == 0; } StringView view() const { return { chars(), length() }; } const char& operator[](usize) const; ConstIterator begin() const { return chars(); } ConstIterator end() const { return begin() + length(); } private: struct RefStringData : public Shareable { char* string { nullptr }; usize length { 0 }; RefStringData(char* s, usize l) : Shareable(), string(s), length(l) { } ~RefStringData() { if (string) free_impl(string); } }; SharedPtr m_string_data { nullptr }; static Result adopt(char* c_str); static Result adopt(char* c_str, usize length); }; template <> u64 hash(const RefString& value, u64 salt);