diff --git a/Include/auROXTL/auHashUtils.hpp b/Include/auROXTL/auHashUtils.hpp index a46e9d2..dd3020d 100644 --- a/Include/auROXTL/auHashUtils.hpp +++ b/Include/auROXTL/auHashUtils.hpp @@ -9,6 +9,8 @@ #include "auFNV1Utils.hpp" #include "auMemoryModel.hpp" +#include "auString.hpp" +#include "auUTF8StringView.hpp" #define _AU_HASH_UTILS_HAS_STD @@ -277,6 +279,17 @@ namespace AuHash } }; + template <> + struct equal + { + using is_transparent = void; + + bool operator()(std::string_view lhs, std::string_view rhs) const + { + return lhs == rhs; + } + }; + template <> struct equal, Aurora::Memory::StringAllocator>> { @@ -408,6 +421,19 @@ namespace AuHash } }; + template <> + struct less + { + bool operator()(AuRONString lhs, AuRONString rhs) const + { + #if 0 + return AuFnv1aRuntime(lhs.data(), lhs.size()) < AuFnv1aRuntime(rhs.data(), rhs.size()); + #else + return hash{}(lhs) < hash{}(rhs); + #endif + } + }; + template <> struct less { diff --git a/Include/auROXTL/auMemoryModel.hpp b/Include/auROXTL/auMemoryModel.hpp index 7dc8435..1af9bd0 100644 --- a/Include/auROXTL/auMemoryModel.hpp +++ b/Include/auROXTL/auMemoryModel.hpp @@ -377,20 +377,8 @@ namespace Aurora::Memory this->deallocate_object(p); } - - inline bool operator==(const BaseAuroraRuntimeAllocator &op) - { - return true; - } - - template - inline bool operator==(const BaseAuroraRuntimeAllocator &op) - { - return true; - } }; - template using PrimitiveArrayAllocator = BaseAuroraRuntimeAllocator; @@ -401,4 +389,11 @@ namespace Aurora::Memory using StringAllocator = BaseAuroraRuntimeAllocator; #endif +} + +template +inline constexpr bool operator==(Aurora::Memory::BaseAuroraRuntimeAllocator lhs, + Aurora::Memory::BaseAuroraRuntimeAllocator rhs) noexcept +{ + return true; } \ No newline at end of file diff --git a/Include/auROXTL/auStringUtils.hpp b/Include/auROXTL/auStringUtils.hpp index 65a24fe..ec9689b 100644 --- a/Include/auROXTL/auStringUtils.hpp +++ b/Include/auROXTL/auStringUtils.hpp @@ -25,23 +25,23 @@ #pragma once // offset in bytes -using CodepointByteOffset_t = decltype(AuROString::npos); +/* using CodepointByteOffset_t = decltype(AuROString::npos); */ // offset in codepoints -using CodepointOffset_t = AuUInt; +/* using CodepointOffset_t = AuUInt; */ -static auline bool AuStringContains(const AuROString &value, const AuROString &subpattern) +static auline constexpr bool AuStringContains(const AuROString &value, const AuROString &subpattern) { return value.find(subpattern) != AuROString::npos; } -static auline bool AuEndsWith(AuROString const &value, AuROString const &ending) +static auline constexpr bool AuEndsWith(AuROString const &value, AuROString const &ending) { if (ending.size() > value.size()) return false; return std::equal(ending.rbegin(), ending.rend(), value.rbegin()); } -static auline bool AuStartsWith(AuROString const &value, AuROString const &starting) +static auline constexpr bool AuStartsWith(AuROString const &value, AuROString const &starting) { #if defined(AU_STRING_IS_TINYUTF_EXPERIMENT) return value.starts_with(starting); @@ -667,9 +667,9 @@ static CodepointByteOffset_t AuCodepointsFindByteOffset(const AuROString &in, return AuROString::npos; } -static CodepointByteOffset_t AuCodepointsFindByteOffsetUnsafe(const AuROString &in, - const AuROString &find, - CodepointByteOffset_t uStartPosition = {}) +static constexpr CodepointByteOffset_t AuCodepointsFindByteOffsetUnsafe(const AuROString &in, + const AuROString &find, + CodepointByteOffset_t uStartPosition) { AuUInt uCounter = 0; auto uLength = in.length(); diff --git a/Include/auROXTL/auUTF8StringView.hpp b/Include/auROXTL/auUTF8StringView.hpp index 7d0c33f..b4d9fe0 100644 --- a/Include/auROXTL/auUTF8StringView.hpp +++ b/Include/auROXTL/auUTF8StringView.hpp @@ -1,8 +1,389 @@ #pragma once -// TODO: - +/* read-only, utf-8 *byte* view */ using AuROString = std::string_view; - using AuUTF8StringView = AuROString; -using AuU8View = AuUTF8StringView; \ No newline at end of file +using AuU8View = AuUTF8StringView; + +// offset in bytes +using CodepointByteOffset_t = decltype(AuROString::npos); + +// 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 AuROString (without std::string_view) +// TODO: implement AuStringView (does not exist yet) (without std::string_view) + +/* 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; + + 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->rbegin(); + } + + 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(basic_string_view v) const noexcept + { + if (size() < v.size()) + { + return -1; + } + + int iRet = traits_type::compare(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, + basic_string_view v) const + { + return this->view.substr(pos1, count1).compare(v); + } + + inline constexpr int compare(size_type pos1, size_type count1, basic_string_view 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(basic_string_view(s)); + } + + inline constexpr int compare(size_type pos1, size_type count1, + const char *s) const + { + return this->view.substr(pos1, count1).compare(basic_string_view(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(basic_string_view(s, count2)); + } + + inline constexpr bool starts_with(basic_string_view 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(basic_string_view 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(basic_string_view 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(basic_string_view(&c, 1)); + } + + inline constexpr bool contains(const char *s) const + { + return this->contains(basic_string_view(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; + } + + inline constexpr size_type find(basic_string_view 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(basic_string_view(&ch, 1), pos); + } + + inline constexpr size_type find(const char *s, size_type pos, size_type count) const + { + return this->find(basic_string_view(s, count), pos); + } + + inline constexpr size_type find(const char *s, size_type pos = 0) const + { + return this->find(basic_string_view(s), pos); + } + + inline constexpr size_type rfind(basic_string_view 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(basic_string_view(&ch, 1), pos); + } + + inline constexpr size_type rfind(const char *s, size_type pos, size_type count) const + { + return this->rfind(basic_string_view(s, count), pos); + } + + inline constexpr size_type rfind(const char *s, size_type pos = npos) const + { + return this->rfind(basic_string_view(s), pos); + } + + inline constexpr size_type find_first_not_of(const basic_string_view 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(const basic_string_view right, const size_type offset = npos) const noexcept + { + return this->view.find_last_not_of(right, offset); + } + + inline constexpr size_type find_last_of(const basic_string_view right, const size_type offset = npos) const noexcept + { + return this->view.find_last_of(right, offset); + } + + inline constexpr size_type find_first_of(const basic_string_view 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(basic_string_view(&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(basic_string_view(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(basic_string_view(s), offset); + } + + inline constexpr size_type find_last_of(const char c, const size_type offset = npos) const noexcept + { + return this->find_last_of(basic_string_view(&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(basic_string_view(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(basic_string_view(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(basic_string_view(&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(basic_string_view(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(basic_string_view(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(basic_string_view(&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(basic_string_view(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(basic_string_view(s), offset); + } + + inline operator basic_string_view() const + { + return this->view; + } + +private: + AuROString view; +}; + +inline bool operator==(const AuRONString &lhs, + const AuRONString &rhs) noexcept +{ + return AuROString(lhs) == AuROString(rhs); +} \ No newline at end of file