Luna/libluna/include/luna/RefString.h

121 lines
2.9 KiB
C
Raw Normal View History

/**
* @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 <luna/Hash.h>
#include <luna/Result.h>
#include <luna/SharedPtr.h>
#include <luna/String.h>
#include <luna/StringView.h>
#include <stdarg.h>
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<RefString> substring(usize begin, usize size) const;
/* Splits a String with a delimiter. */
Result<Vector<RefString>> split(StringView delim) const
{
return view().ref_split(delim);
}
/* Splits a String into two parts with a delimiter. */
Result<Vector<RefString>> 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<RefString> join(const Vector<RefString>& vec, StringView delim);
/* Creates a single String consisting of a list of strings separated by a delimiter. */
static Result<RefString> join(const Vector<StringView>& vec, StringView delim);
static Result<RefString> format(StringView fmt, ...);
static Result<RefString> vformat(StringView fmt, va_list ap);
static Result<RefString> from_cstring(const char* str);
static Result<RefString> from_string_view(StringView str);
static Result<RefString> 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<RefStringData> m_string_data { nullptr };
static Result<RefString> adopt(char* c_str);
static Result<RefString> adopt(char* c_str, usize length);
};
template <> u64 hash(const RefString& value, u64 salt);