121 lines
2.9 KiB
C
121 lines
2.9 KiB
C
|
/**
|
||
|
* @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);
|