1476 lines
39 KiB
C++
1476 lines
39 KiB
C++
#pragma once
|
|
|
|
/* read-only, utf-8 *byte* view */
|
|
struct AuROString;
|
|
using AuUTF8StringView = AuROString;
|
|
using AuU8View = AuUTF8StringView;
|
|
|
|
// offset in bytes
|
|
using CodepointByteOffset_t = AuUInt;
|
|
|
|
// offset in codepoints
|
|
using CodepointOffset_t = AuUInt;
|
|
|
|
|
|
// AuStringUtils.hpp fwd decl
|
|
static constexpr CodepointByteOffset_t AuCodepointsFindByteOffsetUnsafe(const AuROString &in,
|
|
const AuROString &find,
|
|
CodepointByteOffset_t uStartPosition = {});
|
|
static auline constexpr bool AuEndsWith(AuROString const &value, AuROString const &ending);
|
|
static auline constexpr bool AuStartsWith(AuROString const &value, AuROString const &starting);
|
|
|
|
// TODO: implement AuStringView (does not exist yet) (without std::string_view)
|
|
|
|
#include "auMemoryUtils.hpp"
|
|
|
|
/* read-only, null terminated, utf-8 *byte* view */
|
|
struct AuROString
|
|
{
|
|
// using basic_string_view = AuROString;
|
|
using basic_string_view = std::basic_string_view<char>;
|
|
|
|
using traits_type = typename basic_string_view::traits_type;
|
|
|
|
using value_type = char;
|
|
using pointer = char *;
|
|
using const_pointer = const char *;
|
|
using reference = char &;
|
|
using const_reference = const char &;
|
|
using const_iterator = const char *;
|
|
using iterator = char *;
|
|
using const_reverse_iterator = typename std::reverse_iterator<const char *>;
|
|
using reverse_iterator = typename std::reverse_iterator<char *>;
|
|
using size_type = AuUInt;
|
|
using difference_type = AuSInt;
|
|
|
|
cstatic constexpr size_type npos = size_type(-1);
|
|
|
|
inline constexpr AuROString()
|
|
{
|
|
|
|
}
|
|
|
|
AU_COPY_MOVE(AuROString);
|
|
|
|
inline constexpr AuROString(const AuString &str) :
|
|
pPointer(str.data()),
|
|
uLength(str.length())
|
|
{
|
|
|
|
}
|
|
|
|
inline constexpr AuROString(const std::string &str) :
|
|
pPointer(str.data()),
|
|
uLength(str.length())
|
|
{
|
|
|
|
}
|
|
|
|
inline constexpr AuROString(const char *str) :
|
|
pPointer(str),
|
|
uLength(traits_type::length(str))
|
|
{
|
|
|
|
}
|
|
|
|
inline constexpr AuROString(const char *str,
|
|
AuUInt uLength) :
|
|
pPointer(str),
|
|
uLength(uLength)
|
|
{
|
|
|
|
}
|
|
inline constexpr AuROString(const char *str,
|
|
const char *strEnd) :
|
|
pPointer(str),
|
|
uLength(strEnd - str)
|
|
{
|
|
|
|
}
|
|
|
|
inline constexpr AuROString(basic_string_view strView) :
|
|
pPointer(strView.data()),
|
|
uLength(strView.size())
|
|
{
|
|
|
|
}
|
|
|
|
inline constexpr const_iterator begin() const noexcept
|
|
{
|
|
return this->cbegin();
|
|
}
|
|
|
|
inline constexpr const_iterator cbegin() const noexcept
|
|
{
|
|
return this->pPointer;
|
|
}
|
|
|
|
inline constexpr const_iterator end() const noexcept
|
|
{
|
|
return this->cend();
|
|
}
|
|
|
|
inline constexpr const_iterator cend() const noexcept
|
|
{
|
|
return this->cbegin() + this->length();
|
|
}
|
|
|
|
inline constexpr const_reverse_iterator rbegin() const noexcept
|
|
{
|
|
return this->crbegin();
|
|
}
|
|
|
|
inline constexpr const_reverse_iterator crbegin() const noexcept
|
|
{
|
|
return const_reverse_iterator(this->cend());
|
|
}
|
|
|
|
inline constexpr const_reverse_iterator rend() const noexcept
|
|
{
|
|
return this->crend();
|
|
}
|
|
|
|
inline constexpr const_reverse_iterator crend() const noexcept
|
|
{
|
|
return const_reverse_iterator(this->cbegin());
|
|
}
|
|
|
|
inline constexpr AuROString substr(size_type pos1, size_type count1 = npos) const noexcept
|
|
{
|
|
if (pos1 >= this->uLength)
|
|
{
|
|
return {};
|
|
}
|
|
|
|
if (count1 == npos)
|
|
{
|
|
return this->pPointer + pos1;
|
|
}
|
|
|
|
if (pos1 + count1 > this->uLength)
|
|
{
|
|
return {};
|
|
}
|
|
|
|
return AuROString { this->pPointer + pos1, count1 };
|
|
}
|
|
|
|
inline constexpr AuROString remove_suffix(size_type n)
|
|
{
|
|
if (this->uLength < n)
|
|
{
|
|
return {};
|
|
}
|
|
|
|
return AuROString { this->pPointer, this->uLength - n };
|
|
}
|
|
|
|
inline constexpr AuROString remove_prefix(size_type n)
|
|
{
|
|
if (this->uLength < n)
|
|
{
|
|
return {};
|
|
}
|
|
|
|
return AuROString { this->pPointer + n, this->uLength - n };
|
|
}
|
|
|
|
inline constexpr AuROString RemoveSuffix(size_type n)
|
|
{
|
|
return remove_suffix(n);
|
|
}
|
|
|
|
inline constexpr AuROString RemovePrefix(size_type n)
|
|
{
|
|
return remove_prefix(n);
|
|
}
|
|
|
|
inline constexpr int compare(basic_string_view v) const noexcept
|
|
{
|
|
if (size() < v.size())
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
int iRet = AuMemcmp(data(), v.data(), v.size());
|
|
|
|
if (size() > v.size() &&
|
|
iRet == 0)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
return iRet;
|
|
}
|
|
|
|
inline constexpr int compare(const AuROString &v) const noexcept
|
|
{
|
|
if (size() < v.size())
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
int iRet = AuMemcmp(data(), v.data(), v.size());
|
|
|
|
if (size() > v.size() &&
|
|
iRet == 0)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
return iRet;
|
|
}
|
|
|
|
inline constexpr int compare(size_type pos1, size_type count1,
|
|
AuROString v) const
|
|
{
|
|
return this->substr(pos1, count1).compare(v);
|
|
}
|
|
|
|
inline constexpr int compare(size_type pos1, size_type count1, AuROString v,
|
|
size_type pos2, size_type count2) const
|
|
{
|
|
return this->substr(pos1, count1).compare(v.substr(pos2, count2));
|
|
}
|
|
|
|
inline constexpr int compare(const char *s) const
|
|
{
|
|
return this->compare(AuROString(s));
|
|
}
|
|
|
|
inline constexpr int compare(size_type pos1, size_type count1,
|
|
const char *s) const
|
|
{
|
|
return this->substr(pos1, count1).compare(AuROString(s));
|
|
}
|
|
|
|
inline constexpr int compare(size_type pos1, size_type count1,
|
|
const char *s, size_type count2) const
|
|
{
|
|
return this->substr(pos1, count1).compare(AuROString(s, count2));
|
|
}
|
|
|
|
inline constexpr bool starts_with(AuROString sv) const noexcept
|
|
{
|
|
return AuStartsWith(*this, sv);
|
|
}
|
|
|
|
inline constexpr bool starts_with(char ch) const noexcept
|
|
{
|
|
return AuStartsWith(*this, AuROString(&ch, 1));
|
|
}
|
|
|
|
inline constexpr bool starts_with(const char *s) const
|
|
{
|
|
return AuStartsWith(*this, s);
|
|
}
|
|
|
|
inline constexpr bool ends_with(AuROString sv) const noexcept
|
|
{
|
|
return AuEndsWith(*this, sv);
|
|
}
|
|
|
|
inline constexpr bool ends_with(char ch) const noexcept
|
|
{
|
|
return AuEndsWith(*this, AuROString(&ch, 1));
|
|
}
|
|
|
|
inline constexpr bool ends_with(const char *s) const
|
|
{
|
|
return AuEndsWith(*this, s);
|
|
}
|
|
|
|
inline constexpr bool contains(AuROString sv) const noexcept
|
|
{
|
|
#if 0
|
|
return AuCodepointsContains(*this, sv);
|
|
#else
|
|
return AuCodepointsFindByteOffsetUnsafe(*this, sv, 0) != AuROString::npos;
|
|
#endif
|
|
}
|
|
|
|
inline constexpr bool contains(char c) const noexcept
|
|
{
|
|
return this->contains(AuROString(&c, 1));
|
|
}
|
|
|
|
inline constexpr bool contains(const char *s) const
|
|
{
|
|
return this->contains(AuROString(s));
|
|
}
|
|
|
|
inline constexpr const_reference operator[](size_type pos) const
|
|
{
|
|
return *(this->begin() + pos);
|
|
}
|
|
|
|
inline constexpr const_reference at(size_type pos) const
|
|
{
|
|
return this->pPointer[pos];
|
|
}
|
|
|
|
inline constexpr const_reference front() const
|
|
{
|
|
return this->operator[](0);
|
|
}
|
|
|
|
inline constexpr const_reference back() const
|
|
{
|
|
return this->operator[](size() - 1);
|
|
}
|
|
|
|
inline constexpr const_pointer data() const noexcept
|
|
{
|
|
return &this->operator[](0);
|
|
}
|
|
|
|
inline constexpr const_pointer c_str() const noexcept
|
|
{
|
|
return this->data();
|
|
}
|
|
|
|
inline constexpr size_type max_size() const noexcept
|
|
{
|
|
return SIZE_MAX;
|
|
//return AuNumericLimits<AuSInt>().max();
|
|
}
|
|
|
|
inline constexpr size_type size() const noexcept
|
|
{
|
|
return this->uLength;
|
|
}
|
|
|
|
inline constexpr size_type length() const noexcept
|
|
{
|
|
return this->size();
|
|
}
|
|
|
|
inline constexpr bool empty() const noexcept
|
|
{
|
|
return this->size() == 0 || !this->pPointer;
|
|
}
|
|
|
|
inline constexpr size_type find(AuROString v, size_type pos = 0) const noexcept
|
|
{
|
|
return AuCodepointsFindByteOffsetUnsafe(*this, v, pos);
|
|
}
|
|
|
|
inline constexpr size_type find(char ch, size_type pos = 0) const noexcept
|
|
{
|
|
return this->find(AuROString(&ch, 1), pos);
|
|
}
|
|
|
|
inline constexpr size_type find(const char *s, size_type pos, size_type count) const
|
|
{
|
|
return this->find(AuROString(s, count), pos);
|
|
}
|
|
|
|
inline constexpr size_type find(const char *s, size_type pos = 0) const
|
|
{
|
|
return this->find(AuROString(s), pos);
|
|
}
|
|
|
|
inline constexpr size_type rfind(AuROString v, size_type pos = npos) const noexcept
|
|
{
|
|
return basic_string_view(*this).rfind(basic_string_view { v }, pos);
|
|
}
|
|
|
|
inline constexpr size_type rfind(char ch, size_type pos = npos) const noexcept
|
|
{
|
|
return this->find(AuROString(&ch, 1), pos);
|
|
}
|
|
|
|
inline constexpr size_type rfind(const char *s, size_type pos, size_type count) const
|
|
{
|
|
return this->rfind(AuROString(s, count), pos);
|
|
}
|
|
|
|
inline constexpr size_type rfind(const char *s, size_type pos = npos) const
|
|
{
|
|
return this->rfind(AuROString(s), pos);
|
|
}
|
|
|
|
inline constexpr size_type find_first_not_of(const AuROString right, const size_type offset = 0) const noexcept
|
|
{
|
|
return basic_string_view(*this).find_first_not_of(basic_string_view { right }, offset);
|
|
}
|
|
|
|
inline constexpr size_type find_last_not_of(const AuROString right, const size_type offset = npos) const noexcept
|
|
{
|
|
return basic_string_view(*this).find_last_not_of(basic_string_view { right }, offset);
|
|
}
|
|
|
|
inline constexpr size_type find_last_of(const AuROString right, const size_type offset = npos) const noexcept
|
|
{
|
|
return basic_string_view(*this).find_last_of(basic_string_view { right }, offset);
|
|
}
|
|
|
|
inline constexpr size_type find_first_of(const AuROString right, const size_type offset = 0) const noexcept
|
|
{
|
|
if (right.size() == 0)
|
|
{
|
|
return npos;
|
|
}
|
|
|
|
return this->find(right, offset);
|
|
}
|
|
|
|
inline constexpr size_type find_first_of(const char c, const size_type offset = 0) const noexcept
|
|
{
|
|
return this->find_first_of(AuROString(&c, 1), offset);
|
|
}
|
|
|
|
inline constexpr size_type find_first_of(const char *const s, const size_type offset, const size_type count) const
|
|
{
|
|
return this->find_first_of(AuROString(s, count), offset);
|
|
}
|
|
|
|
inline constexpr size_type find_first_of(const char *const s, const size_type offset = 0) const
|
|
{
|
|
return this->find_first_of(AuROString(s), offset);
|
|
}
|
|
|
|
inline constexpr size_type find_last_of(const char c, const size_type offset = npos) const noexcept
|
|
{
|
|
return this->find_last_of(AuROString(&c, 1), offset);
|
|
}
|
|
|
|
inline constexpr size_type find_last_of(const char *const s, const size_type offset, const size_type count) const
|
|
{
|
|
return this->find_last_of(AuROString(s, count), offset);
|
|
}
|
|
|
|
inline constexpr size_type find_last_of(const char *const s, const size_type offset = npos) const
|
|
{
|
|
return this->find_last_of(AuROString(s), offset);
|
|
}
|
|
|
|
inline constexpr size_type find_first_not_of(const char c, const size_type offset = 0) const noexcept
|
|
{
|
|
return this->find_first_not_of(AuROString(&c, 1), offset);
|
|
}
|
|
|
|
inline constexpr size_type find_first_not_of(const char *const s, const size_type offset, const size_type count) const
|
|
{
|
|
return this->find_first_not_of(AuROString(s, count), offset);
|
|
}
|
|
|
|
inline constexpr size_type find_first_not_of(const char *const s, const size_type offset = 0) const
|
|
{
|
|
return this->find_first_not_of(AuROString(s), offset);
|
|
}
|
|
|
|
inline constexpr size_type find_last_not_of(const char c, const size_type offset = npos) const noexcept
|
|
{
|
|
return this->find_last_not_of(AuROString(&c, 1), offset);
|
|
}
|
|
|
|
inline constexpr size_type find_last_not_of(const char *const s, const size_type offset, const size_type count) const
|
|
{
|
|
return this->find_last_not_of(AuROString(s, count), offset);
|
|
}
|
|
|
|
inline constexpr size_type find_last_not_of(const char *const s, const size_type offset = npos) const
|
|
{
|
|
return this->find_last_not_of(AuROString(s), offset);
|
|
}
|
|
|
|
inline constexpr operator std::string_view() const
|
|
{
|
|
return std::string_view { pPointer, uLength };
|
|
}
|
|
|
|
inline constexpr const_iterator Begin() const noexcept
|
|
{
|
|
return this->begin();
|
|
}
|
|
|
|
inline constexpr const_iterator CBegin() const noexcept
|
|
{
|
|
return this->cbegin();
|
|
}
|
|
|
|
inline constexpr const_iterator End() const noexcept
|
|
{
|
|
return this->end();
|
|
}
|
|
|
|
inline constexpr const_iterator CEnd() const noexcept
|
|
{
|
|
return this->cend();
|
|
}
|
|
|
|
inline constexpr const_reverse_iterator RBegin() const noexcept
|
|
{
|
|
return this->rbegin();
|
|
}
|
|
|
|
inline constexpr const_reverse_iterator CRBegin() const noexcept
|
|
{
|
|
return this->crbegin();
|
|
}
|
|
|
|
inline constexpr const_reverse_iterator REnd() const noexcept
|
|
{
|
|
return this->rend();
|
|
}
|
|
|
|
inline constexpr const_reverse_iterator CREnd() const noexcept
|
|
{
|
|
return this->crend();
|
|
}
|
|
|
|
inline constexpr AuROString Substr(size_type pos1, size_type count1 = npos) const noexcept
|
|
{
|
|
return this->substr(pos1, count1);
|
|
}
|
|
|
|
inline constexpr int Compare(basic_string_view v) const noexcept
|
|
{
|
|
return this->compare(v);
|
|
}
|
|
|
|
inline constexpr int Compare(const AuROString &v) const noexcept
|
|
{
|
|
return this->compare(v);
|
|
}
|
|
|
|
inline constexpr int Compare(size_type pos1, size_type count1,
|
|
AuROString v) const
|
|
{
|
|
return this->compare(pos1, count1, v);
|
|
}
|
|
|
|
inline constexpr int Compare(size_type pos1, size_type count1, AuROString v,
|
|
size_type pos2, size_type count2) const
|
|
{
|
|
return this->compare(pos1, count1, v, pos2, count2);
|
|
}
|
|
|
|
inline constexpr int Compare(const char *s) const
|
|
{
|
|
return this->compare(s);
|
|
}
|
|
|
|
inline constexpr int Compare(size_type pos1, size_type count1,
|
|
const char *s) const
|
|
{
|
|
return this->compare(pos1, count1, s);
|
|
}
|
|
|
|
inline constexpr int Compare(size_type pos1, size_type count1,
|
|
const char *s, size_type count2) const
|
|
{
|
|
return this->compare(pos1, count1, s, count2);
|
|
}
|
|
|
|
inline constexpr bool StartsWith(AuROString sv) const noexcept
|
|
{
|
|
return this->starts_with(sv);
|
|
}
|
|
|
|
inline constexpr bool StartsWith(char ch) const noexcept
|
|
{
|
|
return this->starts_with(ch);
|
|
}
|
|
|
|
inline constexpr bool StartsWith(const char *s) const
|
|
{
|
|
return this->starts_with(s);
|
|
}
|
|
|
|
inline constexpr bool EndsWith(AuROString sv) const noexcept
|
|
{
|
|
return this->ends_with(sv);
|
|
}
|
|
|
|
inline constexpr bool EndsWith(char ch) const noexcept
|
|
{
|
|
return this->ends_with(ch);
|
|
}
|
|
|
|
inline constexpr bool EndsWith(const char *s) const
|
|
{
|
|
return this->ends_with(s);
|
|
}
|
|
|
|
inline constexpr bool Contains(AuROString sv) const noexcept
|
|
{
|
|
return this->contains(sv);
|
|
}
|
|
|
|
inline constexpr bool Contains(char C) const noexcept
|
|
{
|
|
return this->contains(C);
|
|
}
|
|
|
|
inline constexpr bool Contains(const char *s) const
|
|
{
|
|
return this->contains(s);
|
|
}
|
|
|
|
inline constexpr const_reference At(size_type pos) const
|
|
{
|
|
return this->at(pos);
|
|
}
|
|
|
|
inline constexpr const_reference Front() const
|
|
{
|
|
return this->front();
|
|
}
|
|
|
|
inline constexpr const_reference Back() const
|
|
{
|
|
return this->back();
|
|
}
|
|
|
|
inline constexpr const_pointer Data() const noexcept
|
|
{
|
|
return this->data();
|
|
}
|
|
|
|
inline constexpr const_pointer CStr() const noexcept
|
|
{
|
|
return this->c_str();
|
|
}
|
|
|
|
inline constexpr size_type MaxSize() const noexcept
|
|
{
|
|
return this->max_size();
|
|
}
|
|
|
|
inline constexpr size_type Size() const noexcept
|
|
{
|
|
return this->size();
|
|
}
|
|
|
|
inline constexpr size_type Length() const noexcept
|
|
{
|
|
return this->length();
|
|
}
|
|
|
|
inline constexpr bool Empty() const noexcept
|
|
{
|
|
return this->empty();
|
|
}
|
|
|
|
inline constexpr size_type Find(AuROString v, size_type pos = 0) const noexcept
|
|
{
|
|
return this->find(v, pos);
|
|
}
|
|
|
|
inline constexpr size_type Find(char ch, size_type pos = 0) const noexcept
|
|
{
|
|
return this->find(ch, pos);
|
|
}
|
|
|
|
inline constexpr size_type Find(const char *s, size_type pos, size_type count) const
|
|
{
|
|
return this->find(s, pos, count);
|
|
}
|
|
|
|
inline constexpr size_type Find(const char *s, size_type pos = 0) const
|
|
{
|
|
return this->find(s, pos);
|
|
}
|
|
|
|
inline constexpr size_type RFind(AuROString v, size_type pos = npos) const noexcept
|
|
{
|
|
return this->rfind(v, pos);
|
|
}
|
|
|
|
inline constexpr size_type RFind(char ch, size_type pos = npos) const noexcept
|
|
{
|
|
return this->rfind(ch, pos);
|
|
}
|
|
|
|
inline constexpr size_type Rfind(const char *s, size_type pos, size_type count) const
|
|
{
|
|
return this->rfind(s, pos, count);
|
|
}
|
|
|
|
inline constexpr size_type Rfind(const char *s, size_type pos = npos) const
|
|
{
|
|
return this->rfind(s, pos);
|
|
}
|
|
|
|
inline constexpr size_type FindFirstNotOf(const AuROString right, const size_type offset = 0) const noexcept
|
|
{
|
|
return this->find_first_not_of(right, offset);
|
|
}
|
|
|
|
inline constexpr size_type FindLastNotOf(const AuROString right, const size_type offset = npos) const noexcept
|
|
{
|
|
return this->find_last_not_of(right, offset);
|
|
}
|
|
|
|
inline constexpr size_type FindLastOf(const AuROString right, const size_type offset = npos) const noexcept
|
|
{
|
|
return this->find_last_of(right, offset);
|
|
}
|
|
|
|
inline constexpr size_type FindFirstOf(const AuROString right, const size_type offset = 0) const noexcept
|
|
{
|
|
return this->find_first_of(right, offset);
|
|
}
|
|
|
|
inline constexpr size_type Find_first_of(const char c, const size_type offset = 0) const noexcept
|
|
{
|
|
return this->find_first_of(c, offset);
|
|
}
|
|
|
|
inline constexpr size_type FindFirstOf(const char *const s, const size_type offset, const size_type count) const
|
|
{
|
|
return this->find_first_of(s, offset, count);
|
|
}
|
|
|
|
inline constexpr size_type FindFirstOf(const char *const s, const size_type offset = 0) const
|
|
{
|
|
return this->find_first_of(s, offset);
|
|
}
|
|
|
|
inline constexpr size_type FindLastOf(const char c, const size_type offset = npos) const noexcept
|
|
{
|
|
return this->find_last_of(c, offset);
|
|
}
|
|
|
|
inline constexpr size_type FindLastOf(const char *const s, const size_type offset, const size_type count) const
|
|
{
|
|
return this->find_last_of(s, offset, count);
|
|
}
|
|
|
|
inline constexpr size_type FindLastOf(const char *const s, const size_type offset = npos) const
|
|
{
|
|
return this->find_last_of(s, offset);
|
|
}
|
|
|
|
inline constexpr size_type FindFirstNotOf(const char c, const size_type offset = 0) const noexcept
|
|
{
|
|
return this->find_first_not_of(c, offset);
|
|
}
|
|
|
|
inline constexpr size_type FindFirstNotOf(const char *const s, const size_type offset, const size_type count) const
|
|
{
|
|
return this->find_first_not_of(s, offset, count);
|
|
}
|
|
|
|
inline constexpr size_type FindFirstNotOf(const char *const s, const size_type offset = 0) const
|
|
{
|
|
return this->find_first_not_of(s, offset);
|
|
}
|
|
|
|
inline constexpr size_type FindLastNotOf(const char c, const size_type offset = npos) const noexcept
|
|
{
|
|
return this->find_last_not_of(c, offset);
|
|
}
|
|
|
|
inline constexpr size_type FindLastNotOf(const char *const s, const size_type offset, const size_type count) const
|
|
{
|
|
return this->find_last_not_of(s, offset, count);
|
|
}
|
|
|
|
inline constexpr size_type FindLastNotOf(const char *const s, const size_type offset = npos) const
|
|
{
|
|
return this->find_last_not_of(s, offset);
|
|
}
|
|
|
|
inline operator bool() const
|
|
{
|
|
return this->pPointer &&
|
|
this->uLength;
|
|
}
|
|
|
|
private:
|
|
const char *pPointer {};
|
|
AuUInt uLength {};
|
|
};
|
|
|
|
/* read-only, null terminated, utf-8 *byte* view */
|
|
struct AuRONString
|
|
{
|
|
using traits_type = typename AuROString::traits_type;
|
|
using value_type = typename AuROString::value_type;
|
|
using pointer = typename AuROString::pointer;
|
|
using const_pointer = typename AuROString::const_pointer;
|
|
using reference = typename AuROString::reference;
|
|
using const_reference = typename AuROString::const_reference;
|
|
using const_iterator = typename AuROString::const_iterator;
|
|
using iterator = const_iterator;
|
|
using const_reverse_iterator = typename AuROString::const_reverse_iterator;
|
|
using reverse_iterator = const_reverse_iterator;
|
|
using size_type = typename AuROString::size_type;
|
|
using difference_type = typename AuROString::difference_type;
|
|
|
|
// using basic_string_view = AuROString;
|
|
using basic_string_view = std::basic_string_view<char>;
|
|
|
|
cstatic constexpr size_type npos = size_type(-1);
|
|
|
|
|
|
inline AuRONString(const AuString &str) :
|
|
view(str)
|
|
{
|
|
|
|
}
|
|
|
|
inline AuRONString(const std::string &str) :
|
|
view(str)
|
|
{
|
|
|
|
}
|
|
|
|
inline AuRONString(const char *str) :
|
|
view(str)
|
|
{
|
|
|
|
}
|
|
|
|
inline constexpr const_iterator begin() const noexcept
|
|
{
|
|
return this->cbegin();
|
|
}
|
|
|
|
inline constexpr const_iterator cbegin() const noexcept
|
|
{
|
|
return this->view.cbegin();
|
|
}
|
|
|
|
inline constexpr const_iterator end() const noexcept
|
|
{
|
|
return this->cend();
|
|
}
|
|
|
|
inline constexpr const_iterator cend() const noexcept
|
|
{
|
|
return this->cbegin() + this->length();
|
|
}
|
|
|
|
inline constexpr const_reverse_iterator rbegin() const noexcept
|
|
{
|
|
return this->crbegin();
|
|
}
|
|
|
|
inline constexpr const_reverse_iterator crbegin() const noexcept
|
|
{
|
|
return const_reverse_iterator(this->cend());
|
|
}
|
|
|
|
inline constexpr const_reverse_iterator rend() const noexcept
|
|
{
|
|
return this->crend();
|
|
}
|
|
|
|
inline constexpr const_reverse_iterator crend() const noexcept
|
|
{
|
|
return const_reverse_iterator(this->cbegin());
|
|
}
|
|
|
|
inline constexpr int compare(AuROString v) const noexcept
|
|
{
|
|
if (size() < v.size())
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
int iRet = AuMemcmp(data(), v.data(), v.size());
|
|
|
|
if (size() > v.size() &&
|
|
iRet == 0)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
return iRet;
|
|
}
|
|
|
|
inline constexpr int compare(size_type pos1, size_type count1,
|
|
AuROString v) const
|
|
{
|
|
return this->view.substr(pos1, count1).compare(v);
|
|
}
|
|
|
|
inline constexpr int compare(size_type pos1, size_type count1, AuROString v,
|
|
size_type pos2, size_type count2) const
|
|
{
|
|
return this->view.substr(pos1, count1).compare(v.substr(pos2, count2));
|
|
}
|
|
|
|
inline constexpr int compare(const char *s) const
|
|
{
|
|
return this->compare(AuROString(s));
|
|
}
|
|
|
|
inline constexpr int compare(size_type pos1, size_type count1,
|
|
const char *s) const
|
|
{
|
|
return this->view.substr(pos1, count1).compare(AuROString(s));
|
|
}
|
|
|
|
inline constexpr int compare(size_type pos1, size_type count1,
|
|
const char *s, size_type count2) const
|
|
{
|
|
return this->view.substr(pos1, count1).compare(AuROString(s, count2));
|
|
}
|
|
|
|
inline constexpr bool starts_with(AuROString sv) const noexcept
|
|
{
|
|
return AuStartsWith(*this, sv);
|
|
}
|
|
|
|
inline constexpr bool starts_with(char ch) const noexcept
|
|
{
|
|
return AuStartsWith(*this, AuROString(&ch, 1));
|
|
}
|
|
|
|
inline constexpr bool starts_with(const char *s) const
|
|
{
|
|
return AuStartsWith(*this, s);
|
|
}
|
|
|
|
inline constexpr bool ends_with(AuROString sv) const noexcept
|
|
{
|
|
return AuEndsWith(*this, sv);
|
|
}
|
|
|
|
inline constexpr bool ends_with(char ch) const noexcept
|
|
{
|
|
return AuEndsWith(*this, AuROString(&ch, 1));
|
|
}
|
|
|
|
inline constexpr bool ends_with(const char *s) const
|
|
{
|
|
return AuEndsWith(*this, s);
|
|
}
|
|
|
|
inline constexpr bool contains(AuROString sv) const noexcept
|
|
{
|
|
#if 0
|
|
return AuCodepointsContains(*this, sv);
|
|
#else
|
|
return AuCodepointsFindByteOffsetUnsafe(*this, sv, 0) != AuROString::npos;
|
|
#endif
|
|
}
|
|
|
|
inline constexpr bool contains(char c) const noexcept
|
|
{
|
|
return this->contains(AuROString(&c, 1));
|
|
}
|
|
|
|
inline constexpr bool contains(const char *s) const
|
|
{
|
|
return this->contains(AuROString(s));
|
|
}
|
|
|
|
inline constexpr const_reference operator[](size_type pos) const
|
|
{
|
|
return *(this->begin() + pos);
|
|
}
|
|
|
|
inline constexpr const_reference at(size_type pos) const
|
|
{
|
|
return this->view.at(pos);
|
|
}
|
|
|
|
inline constexpr const_reference front() const
|
|
{
|
|
return this->operator[](0);
|
|
}
|
|
|
|
inline constexpr const_reference back() const
|
|
{
|
|
return this->operator[](size() - 1);
|
|
}
|
|
|
|
inline constexpr const_pointer data() const noexcept
|
|
{
|
|
return &this->operator[](0);
|
|
}
|
|
|
|
inline constexpr const_pointer c_str() const noexcept
|
|
{
|
|
return this->data();
|
|
}
|
|
|
|
inline constexpr size_type max_size() const noexcept
|
|
{
|
|
return this->view.max_size();
|
|
}
|
|
|
|
inline constexpr size_type size() const noexcept
|
|
{
|
|
return this->view.size();
|
|
}
|
|
|
|
inline constexpr size_type length() const noexcept
|
|
{
|
|
return this->size();
|
|
}
|
|
|
|
inline constexpr bool empty() const noexcept
|
|
{
|
|
return this->size() == 0 || !this->view.data();
|
|
}
|
|
|
|
inline constexpr AuROString substr(size_type pos1, size_type count1 = npos) const noexcept
|
|
{
|
|
if (pos1 >= this->size())
|
|
{
|
|
return {};
|
|
}
|
|
|
|
if (count1 == npos)
|
|
{
|
|
return this->data() + pos1;
|
|
}
|
|
|
|
if (pos1 + count1 > this->size())
|
|
{
|
|
return {};
|
|
}
|
|
|
|
return AuROString { this->data() + pos1, count1 };
|
|
}
|
|
|
|
inline constexpr size_type find(AuROString v, size_type pos = 0) const noexcept
|
|
{
|
|
return AuCodepointsFindByteOffsetUnsafe(*this, v, pos);
|
|
}
|
|
|
|
inline constexpr size_type find(char ch, size_type pos = 0) const noexcept
|
|
{
|
|
return this->find(AuROString(&ch, 1), pos);
|
|
}
|
|
|
|
inline constexpr size_type find(const char *s, size_type pos, size_type count) const
|
|
{
|
|
return this->find(AuROString(s, count), pos);
|
|
}
|
|
|
|
inline constexpr size_type find(const char *s, size_type pos = 0) const
|
|
{
|
|
return this->find(AuROString(s), pos);
|
|
}
|
|
|
|
inline constexpr size_type rfind(AuROString v, size_type pos = npos) const noexcept
|
|
{
|
|
return this->view.rfind(v, pos);
|
|
}
|
|
|
|
inline constexpr size_type rfind(char ch, size_type pos = npos) const noexcept
|
|
{
|
|
return this->find(AuROString(&ch, 1), pos);
|
|
}
|
|
|
|
inline constexpr size_type rfind(const char *s, size_type pos, size_type count) const
|
|
{
|
|
return this->rfind(AuROString(s, count), pos);
|
|
}
|
|
|
|
inline constexpr size_type rfind(const char *s, size_type pos = npos) const
|
|
{
|
|
return this->rfind(AuROString(s), pos);
|
|
}
|
|
|
|
inline constexpr size_type find_first_not_of(AuROString right, const size_type offset = 0) const noexcept
|
|
{
|
|
return this->view.find_first_not_of(right, offset);
|
|
}
|
|
|
|
inline constexpr size_type find_last_not_of(AuROString right, const size_type offset = npos) const noexcept
|
|
{
|
|
return this->view.find_last_not_of(right, offset);
|
|
}
|
|
|
|
inline constexpr size_type find_last_of(AuROString right, const size_type offset = npos) const noexcept
|
|
{
|
|
return this->view.find_last_of(right, offset);
|
|
}
|
|
|
|
inline constexpr size_type find_first_of(AuROString right, const size_type offset = 0) const noexcept
|
|
{
|
|
if (right.size() == 0)
|
|
{
|
|
return npos;
|
|
}
|
|
|
|
return this->find(right, offset);
|
|
}
|
|
|
|
inline constexpr size_type find_first_of(const char c, const size_type offset = 0) const noexcept
|
|
{
|
|
return this->find_first_of(AuROString(&c, 1), offset);
|
|
}
|
|
|
|
inline constexpr size_type find_first_of(const char *const s, const size_type offset, const size_type count) const
|
|
{
|
|
return this->find_first_of(AuROString(s, count), offset);
|
|
}
|
|
|
|
inline constexpr size_type find_first_of(const char *const s, const size_type offset = 0) const
|
|
{
|
|
return this->find_first_of(AuROString(s), offset);
|
|
}
|
|
|
|
inline constexpr size_type find_last_of(const char c, const size_type offset = npos) const noexcept
|
|
{
|
|
return this->find_last_of(AuROString(&c, 1), offset);
|
|
}
|
|
|
|
inline constexpr size_type find_last_of(const char *const s, const size_type offset, const size_type count) const
|
|
{
|
|
return this->find_last_of(AuROString(s, count), offset);
|
|
}
|
|
|
|
inline constexpr size_type find_last_of(const char *const s, const size_type offset = npos) const
|
|
{
|
|
return this->find_last_of(AuROString(s), offset);
|
|
}
|
|
|
|
inline constexpr size_type find_first_not_of(const char c, const size_type offset = 0) const noexcept
|
|
{
|
|
return this->find_first_not_of(AuROString(&c, 1), offset);
|
|
}
|
|
|
|
inline constexpr size_type find_first_not_of(const char *const s, const size_type offset, const size_type count) const
|
|
{
|
|
return this->find_first_not_of(AuROString(s, count), offset);
|
|
}
|
|
|
|
inline constexpr size_type find_first_not_of(const char *const s, const size_type offset = 0) const
|
|
{
|
|
return this->find_first_not_of(AuROString(s), offset);
|
|
}
|
|
|
|
inline constexpr size_type find_last_not_of(const char c, const size_type offset = npos) const noexcept
|
|
{
|
|
return this->find_last_not_of(AuROString(&c, 1), offset);
|
|
}
|
|
|
|
inline constexpr size_type find_last_not_of(const char *const s, const size_type offset, const size_type count) const
|
|
{
|
|
return this->find_last_not_of(AuROString(s, count), offset);
|
|
}
|
|
|
|
inline constexpr size_type find_last_not_of(const char *const s, const size_type offset = npos) const
|
|
{
|
|
return this->find_last_not_of(AuROString(s), offset);
|
|
}
|
|
|
|
inline constexpr operator AuROString() const
|
|
{
|
|
return this->view;
|
|
}
|
|
|
|
inline operator bool() const
|
|
{
|
|
return this->view;
|
|
}
|
|
|
|
inline constexpr const_iterator Begin() const noexcept
|
|
{
|
|
return this->begin();
|
|
}
|
|
|
|
inline constexpr const_iterator CBegin() const noexcept
|
|
{
|
|
return this->cbegin();
|
|
}
|
|
|
|
inline constexpr const_iterator End() const noexcept
|
|
{
|
|
return this->end();
|
|
}
|
|
|
|
inline constexpr const_iterator CEnd() const noexcept
|
|
{
|
|
return this->cend();
|
|
}
|
|
|
|
inline constexpr const_reverse_iterator RBegin() const noexcept
|
|
{
|
|
return this->rbegin();
|
|
}
|
|
|
|
inline constexpr const_reverse_iterator CRBegin() const noexcept
|
|
{
|
|
return this->crbegin();
|
|
}
|
|
|
|
inline constexpr const_reverse_iterator REnd() const noexcept
|
|
{
|
|
return this->rend();
|
|
}
|
|
|
|
inline constexpr const_reverse_iterator CREnd() const noexcept
|
|
{
|
|
return this->crend();
|
|
}
|
|
|
|
inline constexpr AuROString Substr(size_type pos1, size_type count1 = npos) const noexcept
|
|
{
|
|
return this->substr(pos1, count1);
|
|
}
|
|
|
|
inline constexpr int Compare(AuROString v) const noexcept
|
|
{
|
|
return this->compare(v);
|
|
}
|
|
|
|
inline constexpr int Compare(const AuROString &v) const noexcept
|
|
{
|
|
return this->compare(v);
|
|
}
|
|
|
|
inline constexpr int Compare(size_type pos1, size_type count1,
|
|
AuROString v) const
|
|
{
|
|
return this->compare(pos1, count1, v);
|
|
}
|
|
|
|
inline constexpr int Compare(size_type pos1, size_type count1, AuROString v,
|
|
size_type pos2, size_type count2) const
|
|
{
|
|
return this->compare(pos1, count1, v, pos2, count2);
|
|
}
|
|
|
|
inline constexpr int Compare(const char *s) const
|
|
{
|
|
return this->compare(s);
|
|
}
|
|
|
|
inline constexpr int Compare(size_type pos1, size_type count1,
|
|
const char *s) const
|
|
{
|
|
return this->compare(pos1, count1, s);
|
|
}
|
|
|
|
inline constexpr int Compare(size_type pos1, size_type count1,
|
|
const char *s, size_type count2) const
|
|
{
|
|
return this->compare(pos1, count1, s, count2);
|
|
}
|
|
|
|
inline constexpr bool StartsWith(AuROString sv) const noexcept
|
|
{
|
|
return this->starts_with(sv);
|
|
}
|
|
|
|
inline constexpr bool StartsWith(char ch) const noexcept
|
|
{
|
|
return this->starts_with(ch);
|
|
}
|
|
|
|
inline constexpr bool StartsWith(const char *s) const
|
|
{
|
|
return this->starts_with(s);
|
|
}
|
|
|
|
inline constexpr bool EndsWith(AuROString sv) const noexcept
|
|
{
|
|
return this->ends_with(sv);
|
|
}
|
|
|
|
inline constexpr bool EndsWith(char ch) const noexcept
|
|
{
|
|
return this->ends_with(ch);
|
|
}
|
|
|
|
inline constexpr bool EndsWith(const char *s) const
|
|
{
|
|
return this->ends_with(s);
|
|
}
|
|
|
|
inline constexpr bool Contains(AuROString sv) const noexcept
|
|
{
|
|
return this->contains(sv);
|
|
}
|
|
|
|
inline constexpr bool Contains(char C) const noexcept
|
|
{
|
|
return this->contains(C);
|
|
}
|
|
|
|
inline constexpr bool Contains(const char *s) const
|
|
{
|
|
return this->contains(s);
|
|
}
|
|
|
|
inline constexpr const_reference At(size_type pos) const
|
|
{
|
|
return this->at(pos);
|
|
}
|
|
|
|
inline constexpr const_reference Front() const
|
|
{
|
|
return this->front();
|
|
}
|
|
|
|
inline constexpr const_reference Back() const
|
|
{
|
|
return this->back();
|
|
}
|
|
|
|
inline constexpr const_pointer Data() const noexcept
|
|
{
|
|
return this->data();
|
|
}
|
|
|
|
inline constexpr const_pointer CStr() const noexcept
|
|
{
|
|
return this->c_str();
|
|
}
|
|
|
|
inline constexpr size_type MaxSize() const noexcept
|
|
{
|
|
return this->max_size();
|
|
}
|
|
|
|
inline constexpr size_type Size() const noexcept
|
|
{
|
|
return this->size();
|
|
}
|
|
|
|
inline constexpr size_type Length() const noexcept
|
|
{
|
|
return this->length();
|
|
}
|
|
|
|
inline constexpr bool Empty() const noexcept
|
|
{
|
|
return this->empty();
|
|
}
|
|
|
|
inline constexpr size_type Find(AuROString v, size_type pos = 0) const noexcept
|
|
{
|
|
return this->find(v, pos);
|
|
}
|
|
|
|
inline constexpr size_type Find(char ch, size_type pos = 0) const noexcept
|
|
{
|
|
return this->find(ch, pos);
|
|
}
|
|
|
|
inline constexpr size_type Find(const char *s, size_type pos, size_type count) const
|
|
{
|
|
return this->find(s, pos, count);
|
|
}
|
|
|
|
inline constexpr size_type Find(const char *s, size_type pos = 0) const
|
|
{
|
|
return this->find(s, pos);
|
|
}
|
|
|
|
inline constexpr size_type RFind(AuROString v, size_type pos = npos) const noexcept
|
|
{
|
|
return this->rfind(v, pos);
|
|
}
|
|
|
|
inline constexpr size_type RFind(char ch, size_type pos = npos) const noexcept
|
|
{
|
|
return this->rfind(ch, pos);
|
|
}
|
|
|
|
inline constexpr size_type Rfind(const char *s, size_type pos, size_type count) const
|
|
{
|
|
return this->rfind(s, pos, count);
|
|
}
|
|
|
|
inline constexpr size_type Rfind(const char *s, size_type pos = npos) const
|
|
{
|
|
return this->rfind(s, pos);
|
|
}
|
|
|
|
inline constexpr size_type FindFirstNotOf(const AuROString right, const size_type offset = 0) const noexcept
|
|
{
|
|
return this->find_first_not_of(right, offset);
|
|
}
|
|
|
|
inline constexpr size_type FindLastNotOf(const AuROString right, const size_type offset = npos) const noexcept
|
|
{
|
|
return this->find_last_not_of(right, offset);
|
|
}
|
|
|
|
inline constexpr size_type FindLastOf(const AuROString right, const size_type offset = npos) const noexcept
|
|
{
|
|
return this->find_last_of(right, offset);
|
|
}
|
|
|
|
inline constexpr size_type FindFirstOf(const AuROString right, const size_type offset = 0) const noexcept
|
|
{
|
|
return this->find_first_of(right, offset);
|
|
}
|
|
|
|
inline constexpr size_type Find_first_of(const char c, const size_type offset = 0) const noexcept
|
|
{
|
|
return this->find_first_of(c, offset);
|
|
}
|
|
|
|
inline constexpr size_type FindFirstOf(const char *const s, const size_type offset, const size_type count) const
|
|
{
|
|
return this->find_first_of(s, offset, count);
|
|
}
|
|
|
|
inline constexpr size_type FindFirstOf(const char *const s, const size_type offset = 0) const
|
|
{
|
|
return this->find_first_of(s, offset);
|
|
}
|
|
|
|
inline constexpr size_type FindLastOf(const char c, const size_type offset = npos) const noexcept
|
|
{
|
|
return this->find_last_of(c, offset);
|
|
}
|
|
|
|
inline constexpr size_type FindLastOf(const char *const s, const size_type offset, const size_type count) const
|
|
{
|
|
return this->find_last_of(s, offset, count);
|
|
}
|
|
|
|
inline constexpr size_type FindLastOf(const char *const s, const size_type offset = npos) const
|
|
{
|
|
return this->find_last_of(s, offset);
|
|
}
|
|
|
|
inline constexpr size_type FindFirstNotOf(const char c, const size_type offset = 0) const noexcept
|
|
{
|
|
return this->find_first_not_of(c, offset);
|
|
}
|
|
|
|
inline constexpr size_type FindFirstNotOf(const char *const s, const size_type offset, const size_type count) const
|
|
{
|
|
return this->find_first_not_of(s, offset, count);
|
|
}
|
|
|
|
inline constexpr size_type FindFirstNotOf(const char *const s, const size_type offset = 0) const
|
|
{
|
|
return this->find_first_not_of(s, offset);
|
|
}
|
|
|
|
inline constexpr size_type FindLastNotOf(const char c, const size_type offset = npos) const noexcept
|
|
{
|
|
return this->find_last_not_of(c, offset);
|
|
}
|
|
|
|
inline constexpr size_type FindLastNotOf(const char *const s, const size_type offset, const size_type count) const
|
|
{
|
|
return this->find_last_not_of(s, offset, count);
|
|
}
|
|
|
|
inline constexpr size_type FindLastNotOf(const char *const s, const size_type offset = npos) const
|
|
{
|
|
return this->find_last_not_of(s, offset);
|
|
}
|
|
private:
|
|
AuROString view;
|
|
};
|
|
|
|
inline constexpr bool operator==(const AuROString &lhs,
|
|
const AuROString &rhs) noexcept
|
|
{
|
|
return lhs.compare(rhs) == 0;
|
|
}
|
|
|
|
inline constexpr bool operator==(const AuRONString &lhs,
|
|
const AuRONString &rhs) noexcept
|
|
{
|
|
return AuROString(lhs) == AuROString(rhs);
|
|
} |