mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 06:53:33 +00:00
321 lines
6.5 KiB
C
321 lines
6.5 KiB
C
|
// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*-
|
||
|
// vi: set et ft=c++ ts=4 sts=4 sw=4 fenc=utf-8 :vi
|
||
|
#ifndef COSMOPOLITAN_CTL_STRING_H_
|
||
|
#define COSMOPOLITAN_CTL_STRING_H_
|
||
|
|
||
|
struct String;
|
||
|
|
||
|
struct StringView
|
||
|
{
|
||
|
const char* p;
|
||
|
size_t n;
|
||
|
|
||
|
static constexpr size_t npos = -1;
|
||
|
|
||
|
constexpr StringView(const char* s) noexcept
|
||
|
: p(s), n(s ? __builtin_strlen(s) : 0)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
constexpr StringView(const char* s, size_t n) noexcept : p(s), n(n)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
inline constexpr ~StringView() noexcept
|
||
|
{
|
||
|
}
|
||
|
|
||
|
int compare(const StringView) const noexcept;
|
||
|
bool operator==(const StringView) const noexcept;
|
||
|
bool operator!=(const StringView) const noexcept;
|
||
|
bool contains(const StringView) const noexcept;
|
||
|
String operator+(const StringView) const noexcept;
|
||
|
bool ends_with(const StringView) const noexcept;
|
||
|
bool starts_with(const StringView) const noexcept;
|
||
|
StringView substr(size_t = 0, size_t = npos) const noexcept;
|
||
|
size_t find(char, size_t = 0) const noexcept;
|
||
|
size_t find(const StringView, size_t = 0) const noexcept;
|
||
|
|
||
|
constexpr StringView& operator=(const StringView& s) noexcept
|
||
|
{
|
||
|
p = s.p;
|
||
|
n = s.n;
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
constexpr bool empty() const noexcept
|
||
|
{
|
||
|
return !n;
|
||
|
}
|
||
|
|
||
|
constexpr const char* data() const noexcept
|
||
|
{
|
||
|
return p;
|
||
|
}
|
||
|
|
||
|
constexpr size_t size() const noexcept
|
||
|
{
|
||
|
return n;
|
||
|
}
|
||
|
|
||
|
constexpr size_t length() const noexcept
|
||
|
{
|
||
|
return n;
|
||
|
}
|
||
|
|
||
|
constexpr const char& operator[](size_t i) const noexcept
|
||
|
{
|
||
|
if (i >= n)
|
||
|
__builtin_trap();
|
||
|
return p[i];
|
||
|
}
|
||
|
|
||
|
constexpr void remove_prefix(size_t count)
|
||
|
{
|
||
|
if (count > n)
|
||
|
__builtin_trap();
|
||
|
p += count;
|
||
|
n -= count;
|
||
|
}
|
||
|
|
||
|
constexpr void remove_suffix(size_t count)
|
||
|
{
|
||
|
if (count > n)
|
||
|
__builtin_trap();
|
||
|
n -= count;
|
||
|
}
|
||
|
|
||
|
bool operator<(const StringView& s) const noexcept
|
||
|
{
|
||
|
return compare(s) < 0;
|
||
|
}
|
||
|
|
||
|
bool operator<=(const StringView& s) const noexcept
|
||
|
{
|
||
|
return compare(s) <= 0;
|
||
|
}
|
||
|
|
||
|
bool operator>(const StringView& s) const noexcept
|
||
|
{
|
||
|
return compare(s) > 0;
|
||
|
}
|
||
|
|
||
|
bool operator>=(const StringView& s) const noexcept
|
||
|
{
|
||
|
return compare(s) >= 0;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
struct String
|
||
|
{
|
||
|
char* p = nullptr;
|
||
|
size_t n = 0;
|
||
|
size_t c = 0;
|
||
|
|
||
|
using iterator = char*;
|
||
|
using const_iterator = const char*;
|
||
|
static constexpr size_t npos = -1;
|
||
|
|
||
|
~String() noexcept;
|
||
|
String() = default;
|
||
|
String(const StringView) noexcept;
|
||
|
String(const char*) noexcept;
|
||
|
String(const String&) noexcept;
|
||
|
String(const char*, size_t) noexcept;
|
||
|
explicit String(size_t, char = 0) noexcept;
|
||
|
String& operator=(String&&) noexcept;
|
||
|
const char* c_str() const noexcept;
|
||
|
|
||
|
void pop_back() noexcept;
|
||
|
void grow(size_t) noexcept;
|
||
|
void reserve(size_t) noexcept;
|
||
|
void resize(size_t, char = 0) noexcept;
|
||
|
void append(char) noexcept;
|
||
|
void append(char, size_t) noexcept;
|
||
|
void append(unsigned long) noexcept;
|
||
|
void append(const void*, size_t) noexcept;
|
||
|
String& insert(size_t, const StringView) noexcept;
|
||
|
String& erase(size_t = 0, size_t = npos) noexcept;
|
||
|
String operator+(const StringView) const noexcept;
|
||
|
String substr(size_t = 0, size_t = npos) const noexcept;
|
||
|
String& replace(size_t, size_t, const StringView&) noexcept;
|
||
|
bool operator==(const StringView) const noexcept;
|
||
|
bool operator!=(const StringView) const noexcept;
|
||
|
bool contains(const StringView) const noexcept;
|
||
|
bool ends_with(const StringView) const noexcept;
|
||
|
bool starts_with(const StringView) const noexcept;
|
||
|
int compare(const StringView) const noexcept;
|
||
|
size_t find(char, size_t = 0) const noexcept;
|
||
|
size_t find(const StringView, size_t = 0) const noexcept;
|
||
|
|
||
|
String(String&& s) noexcept : p(s.p), n(s.n), c(s.c)
|
||
|
{
|
||
|
s.p = nullptr;
|
||
|
s.n = 0;
|
||
|
s.c = 0;
|
||
|
}
|
||
|
|
||
|
void clear() noexcept
|
||
|
{
|
||
|
n = 0;
|
||
|
}
|
||
|
|
||
|
bool empty() const noexcept
|
||
|
{
|
||
|
return !n;
|
||
|
}
|
||
|
|
||
|
char* data() const noexcept
|
||
|
{
|
||
|
return p;
|
||
|
}
|
||
|
|
||
|
size_t size() const noexcept
|
||
|
{
|
||
|
return n;
|
||
|
}
|
||
|
|
||
|
size_t length() const noexcept
|
||
|
{
|
||
|
return n;
|
||
|
}
|
||
|
|
||
|
size_t capacity() const noexcept
|
||
|
{
|
||
|
return c;
|
||
|
}
|
||
|
|
||
|
iterator begin() noexcept
|
||
|
{
|
||
|
return p;
|
||
|
}
|
||
|
|
||
|
iterator end() noexcept
|
||
|
{
|
||
|
return p + n;
|
||
|
}
|
||
|
|
||
|
const_iterator cbegin() const noexcept
|
||
|
{
|
||
|
return p;
|
||
|
}
|
||
|
|
||
|
const_iterator cend() const noexcept
|
||
|
{
|
||
|
return p + n;
|
||
|
}
|
||
|
|
||
|
char& front()
|
||
|
{
|
||
|
if (!n)
|
||
|
__builtin_trap();
|
||
|
return p[0];
|
||
|
}
|
||
|
|
||
|
const char& front() const
|
||
|
{
|
||
|
if (!n)
|
||
|
__builtin_trap();
|
||
|
return p[0];
|
||
|
}
|
||
|
|
||
|
char& back()
|
||
|
{
|
||
|
if (!n)
|
||
|
__builtin_trap();
|
||
|
return p[n - 1];
|
||
|
}
|
||
|
|
||
|
const char& back() const
|
||
|
{
|
||
|
if (!n)
|
||
|
__builtin_trap();
|
||
|
return p[n - 1];
|
||
|
}
|
||
|
|
||
|
char& operator[](size_t i) noexcept
|
||
|
{
|
||
|
if (i >= n)
|
||
|
__builtin_trap();
|
||
|
return p[i];
|
||
|
}
|
||
|
|
||
|
const char& operator[](size_t i) const noexcept
|
||
|
{
|
||
|
if (i >= n)
|
||
|
__builtin_trap();
|
||
|
return p[i];
|
||
|
}
|
||
|
|
||
|
void push_back(char ch) noexcept
|
||
|
{
|
||
|
append(ch);
|
||
|
}
|
||
|
|
||
|
void append(const StringView s) noexcept
|
||
|
{
|
||
|
append(s.p, s.n);
|
||
|
}
|
||
|
|
||
|
inline constexpr operator StringView() const noexcept
|
||
|
{
|
||
|
return StringView(p, n);
|
||
|
}
|
||
|
|
||
|
String& operator=(const char* s) noexcept
|
||
|
{
|
||
|
clear();
|
||
|
append(s);
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
String& operator=(const StringView s) noexcept
|
||
|
{
|
||
|
clear();
|
||
|
append(s);
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
String& operator+=(char x) noexcept
|
||
|
{
|
||
|
append(x);
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
String& operator+=(const StringView s) noexcept
|
||
|
{
|
||
|
append(s);
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
bool operator<(const StringView s) const noexcept
|
||
|
{
|
||
|
return compare(s) < 0;
|
||
|
}
|
||
|
|
||
|
bool operator<=(const StringView s) const noexcept
|
||
|
{
|
||
|
return compare(s) <= 0;
|
||
|
}
|
||
|
|
||
|
bool operator>(const StringView s) const noexcept
|
||
|
{
|
||
|
return compare(s) > 0;
|
||
|
}
|
||
|
|
||
|
bool operator>=(const StringView s) const noexcept
|
||
|
{
|
||
|
return compare(s) >= 0;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
#pragma GCC diagnostic ignored "-Wliteral-suffix"
|
||
|
|
||
|
inline String
|
||
|
operator"" s(const char* s, size_t n)
|
||
|
{
|
||
|
return String(s, n);
|
||
|
}
|
||
|
|
||
|
#endif // COSMOPOLITAN_CTL_STRING_H_
|