161640fa [nostalgia] Cleanup e42126c9 [nostalgia/core] Improve TileSheet validation, add repair 36942cca [nostalgia,olympic] Replace SpanView with Span<const T> b14f1d50 [ox] Replace SpanView with Span<const T> 1bf4f246 [applib] Make run take args as a SpanView edda8e01 [ox/clargs] Add constructor that takes a SpanView 3308b4dd [ox/std] Add missing + and += operators to Span 27f4703a [teagba] Suppress warnings for unsafe buffers 6af00d9a [nostalgia] Enable warnings for unsafe buffers 86b9f931 [olympic] Enable warnings for unsafe buffers a0ed1b3f [ox/std] Fix Span raw array constructor 8dad624b [studio/applib] Cleanup dc6605fd [keel] Add missing error checking to pack c78d3cf6 [ox] Add more unsafe buffer exceptions cee4f65d [ox/std] Replace an unsafe buffer cd3eeeef [ox/fs] Suppress unsafe buffer warnings 287d42f2 [ox/clargs] Cleanup dbbaaa46 [ox/clargs] Enable unsafe buffer warnings 9b8a8c4e [ox/std] Enable unsafe buffer warnings e44fa288 [cityhash] Add pragmas to ignore unsafe buffer warnings e13c6e81 [ox/std] Remove raw char* CharBufferWriter constructor cb55b31a [ox/std] Cleanup ab3f9e16 [ox/std] Make Span access check message consistent with other messages 8f25ef96 [ox/std] Make CharBufferWriter constructor take a Span e13eebaf [ox/std] Cleanup an unsafe buffer 114f5c66 [ox/std] Add overflow checking to SpanIterator df44fe23 [keel] Cleanup 72f4db3d [nostalgia/core/studio] Fix paste command to never paste beyond target dimensions 8a9ff971 [nostalgia/core] Fix resizeSubsheet to work for both growing and shrinking 5a8da59d [keel] Fix readAsset to actually return asset afa3a13d [keel] Cleanup 6522cf8a [keel] Add ensureValid call to readAsset f772e48b [ox] Add Vector/Array/Span overflow checking 13bfe881 [nostalgia/core] Fix resizeSubsheet array overflow 50254754 Merge commit '9e11019b87ba27d1dac9e097dc212a126e404218' bfe890ae [ox] Fix typo in docs ab5bc1ad [ox/std] Remove oxRequireT and oxRequireMT abf7548a [nostalgia/core] Add missing include e2682b5e [studio/modlib] Add missing include 792ad414 [nostalgia] Remove .vs dir git-subtree-dir: deps/nostalgia git-subtree-split: 161640fa11986677dc2e1da6ffd4575e38ab31ad
223 lines
5.4 KiB
C++
223 lines
5.4 KiB
C++
/*
|
|
* Copyright 2015 - 2024 gary@drinkingtea.net
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "bit.hpp"
|
|
#include "def.hpp"
|
|
#include "cstrops.hpp"
|
|
#include "iterator.hpp"
|
|
|
|
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
|
|
|
namespace ox::detail {
|
|
|
|
class BaseStringView {
|
|
public:
|
|
template<typename RefType = char&, typename PtrType = char*, bool reverse = false>
|
|
struct iterator: public Iterator<std::bidirectional_iterator_tag, char> {
|
|
private:
|
|
PtrType m_t = nullptr;
|
|
std::size_t m_offset = 0;
|
|
std::size_t m_max = 0;
|
|
|
|
public:
|
|
constexpr iterator() noexcept = default;
|
|
|
|
constexpr iterator(PtrType t, std::size_t offset, std::size_t max) noexcept {
|
|
m_t = t;
|
|
m_offset = offset;
|
|
m_max = max;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
constexpr auto offset() const noexcept {
|
|
return m_offset;
|
|
}
|
|
|
|
constexpr iterator operator+(std::size_t s) const noexcept {
|
|
if constexpr(reverse) {
|
|
return iterator(m_t, max<std::size_t>(m_offset - s, 0), m_max);
|
|
} else {
|
|
return iterator(m_t, min<std::size_t>(m_offset + s, m_max), m_max);
|
|
}
|
|
}
|
|
|
|
constexpr auto operator-(const iterator &other) const noexcept {
|
|
if constexpr(reverse) {
|
|
return m_offset + other.m_offset;
|
|
} else {
|
|
return m_offset - other.m_offset;
|
|
}
|
|
}
|
|
|
|
constexpr iterator operator-(std::size_t s) const noexcept {
|
|
if constexpr(reverse) {
|
|
return iterator(m_t, min<std::size_t>(m_offset + s, m_max), m_max);
|
|
} else {
|
|
return iterator(m_t, max<std::size_t>(m_offset - s, 0), m_max);
|
|
}
|
|
}
|
|
|
|
constexpr iterator &operator+=(std::size_t s) noexcept {
|
|
if constexpr(reverse) {
|
|
m_offset = max<std::size_t>(m_offset - s, 0);
|
|
} else {
|
|
m_offset = min(m_offset + s, m_max);
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
constexpr iterator &operator-=(std::size_t s) noexcept {
|
|
if constexpr(reverse) {
|
|
m_offset = min(m_offset + s, m_max);
|
|
} else {
|
|
m_offset = max<std::size_t>(m_offset - s, 0);
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
constexpr iterator &operator++() noexcept {
|
|
return operator+=(1);
|
|
}
|
|
|
|
constexpr iterator &operator--() noexcept {
|
|
return operator-=(1);
|
|
}
|
|
|
|
constexpr RefType operator*() const noexcept {
|
|
return m_t[m_offset];
|
|
}
|
|
|
|
constexpr RefType operator[](std::size_t s) const noexcept {
|
|
return m_t[s];
|
|
}
|
|
|
|
constexpr bool operator<(const iterator &other) const noexcept {
|
|
return m_offset < other.m_offset;
|
|
}
|
|
|
|
constexpr bool operator>(const iterator &other) const noexcept {
|
|
return m_offset > other.m_offset;
|
|
}
|
|
|
|
constexpr bool operator<=(const iterator &other) const noexcept {
|
|
return m_offset <= other.m_offset;
|
|
}
|
|
|
|
constexpr bool operator>=(const iterator &other) const noexcept {
|
|
return m_offset >= other.m_offset;
|
|
}
|
|
|
|
constexpr bool operator==(const iterator &other) const noexcept {
|
|
return m_t == other.m_t && m_offset == other.m_offset && m_max == other.m_max;
|
|
}
|
|
|
|
constexpr bool operator!=(const iterator &other) const noexcept {
|
|
return m_t != other.m_t || m_offset != other.m_offset || m_max != other.m_max;
|
|
}
|
|
|
|
};
|
|
|
|
private:
|
|
const char *m_str = nullptr;
|
|
std::size_t m_len = 0;
|
|
protected:
|
|
constexpr BaseStringView() noexcept = default;
|
|
|
|
constexpr BaseStringView(BaseStringView const&sv) noexcept = default;
|
|
|
|
constexpr explicit BaseStringView(std::nullptr_t) noexcept {}
|
|
|
|
constexpr explicit BaseStringView(const char *str) noexcept: m_str(str), m_len(str ? ox::strlen(str) : 0) {}
|
|
|
|
constexpr explicit BaseStringView(const char *str, std::size_t len) noexcept: m_str(str), m_len(len) {}
|
|
|
|
public:
|
|
[[nodiscard]]
|
|
constexpr iterator<const char&, const char*> begin() const noexcept {
|
|
return {m_str, 0, m_len};
|
|
}
|
|
|
|
[[nodiscard]]
|
|
constexpr iterator<const char&, const char*> end() const noexcept {
|
|
return {m_str, m_len, m_len};
|
|
}
|
|
|
|
[[nodiscard]]
|
|
constexpr iterator<const char&, const char*> cbegin() const noexcept {
|
|
return {m_str, 0, m_len};
|
|
}
|
|
|
|
[[nodiscard]]
|
|
constexpr iterator<const char&, const char*> cend() const noexcept {
|
|
return {m_str, m_len, m_len};
|
|
}
|
|
|
|
[[nodiscard]]
|
|
constexpr iterator<const char&, const char*, true> crbegin() const noexcept {
|
|
return {m_str, m_len - 1, m_len};
|
|
}
|
|
|
|
[[nodiscard]]
|
|
constexpr iterator<const char&, const char*, true> crend() const noexcept {
|
|
return {m_str, MaxValue<std::size_t>, m_len};
|
|
}
|
|
|
|
[[nodiscard]]
|
|
constexpr iterator<const char&, const char*, true> rbegin() const noexcept {
|
|
return {m_str, m_len - 1, m_len};
|
|
}
|
|
|
|
[[nodiscard]]
|
|
constexpr iterator<const char&, const char*, true> rend() const noexcept {
|
|
return {m_str, MaxValue<std::size_t>, m_len};
|
|
}
|
|
|
|
[[nodiscard]]
|
|
constexpr auto bytes() const noexcept {
|
|
return m_len;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
constexpr auto len() const noexcept {
|
|
return m_len;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
constexpr auto *data() const noexcept {
|
|
return &m_str[0];
|
|
}
|
|
|
|
[[nodiscard]]
|
|
constexpr auto &front() const noexcept {
|
|
return m_str[0];
|
|
}
|
|
|
|
[[nodiscard]]
|
|
constexpr auto &back() const noexcept {
|
|
return m_str[m_len - 1];
|
|
}
|
|
|
|
[[nodiscard]]
|
|
constexpr auto &operator[](std::size_t i) const noexcept {
|
|
return m_str[i];
|
|
}
|
|
|
|
protected:
|
|
constexpr void set(const char *str, std::size_t len) noexcept {
|
|
m_str = str;
|
|
m_len = len;
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
OX_CLANG_NOWARN_END
|