Squashed 'deps/nostalgia/' changes from 3c7652ef..161640fa

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
This commit is contained in:
2024-12-04 19:55:17 -06:00
parent 9e11019b87
commit 4ccdfc3a6e
101 changed files with 842 additions and 731 deletions

View File

@@ -1,3 +1,9 @@
if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
# enable warnings
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunsafe-buffer-usage")
endif()
if(OX_USE_STDLIB AND OX_ENABLE_TRACEHOOK)
add_library(
OxTraceHook SHARED

View File

@@ -8,6 +8,10 @@
#pragma once
#include "def.hpp"
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
namespace ox {
template<typename It, typename T>
@@ -40,4 +44,6 @@ constexpr OutIt copy_n(It in, Size cnt, OutIt out) {
return out;
}
}
}
OX_CLANG_NOWARN_END

View File

@@ -9,6 +9,7 @@
#pragma once
#include "bit.hpp"
#include "def.hpp"
#include "error.hpp"
#include "initializerlist.hpp"
#include "iterator.hpp"
@@ -17,6 +18,8 @@
#include "types.hpp"
#include "utility.hpp"
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
namespace ox {
template<typename T, std::size_t ArraySize>
@@ -35,6 +38,10 @@ class Array {
public:
constexpr Array() noexcept = default;
template<typename ...Args>
constexpr Array(Args ...list) noexcept: m_items{std::move(list)...} {
}
constexpr Array(std::initializer_list<T> list) noexcept;
constexpr Array(const Array &other);
@@ -174,11 +181,13 @@ constexpr Array<T, ArraySize> &Array<T, ArraySize>::operator=(Array &&other) noe
template<typename T, std::size_t ArraySize>
constexpr T &Array<T, ArraySize>::operator[](std::size_t i) noexcept {
ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Array access overflow");
return m_items[i];
}
template<typename T, std::size_t ArraySize>
constexpr const T &Array<T, ArraySize>::operator[](std::size_t i) const noexcept {
ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Array access overflow");
return m_items[i];
}
@@ -198,3 +207,5 @@ constexpr bool Array<T, ArraySize>::contains(const T &v) const {
}
}
OX_CLANG_NOWARN_END

View File

@@ -6,6 +6,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include "fmt.hpp"
#include "stacktrace.hpp"
#include "trace.hpp"
@@ -13,7 +14,7 @@
namespace ox {
void panic(const char *file, int line, const char *panicMsg, const Error &err) noexcept {
void panic(StringViewCR file, int line, StringViewCR panicMsg, const Error &err) noexcept {
oxErrf("\033[31;1;1mPANIC:\033[0m [{}:{}]: {}\n", file, line, panicMsg);
if (err.msg) {
oxErrf("\tError Message:\t{}\n", err.msg);
@@ -31,4 +32,40 @@ void panic(const char *file, int line, const char *panicMsg, const Error &err) n
#endif
}
void panic(const char *file, int line, const char *panicMsg, const Error &err) noexcept {
panic(StringView{file}, line, StringView{panicMsg}, err);
}
void assertFailFuncRuntime(StringViewCR file, int line, StringViewCR assertTxt, StringViewCR msg) noexcept {
#ifdef OX_USE_STDLIB
auto output = sfmt("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, msg);
output += genStackTrace(2);
oxTracef("assert", "Failed assert: {} ({}) [{}:{}]", msg, assertTxt, file, line);
std::abort();
#else
oxErrf("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, msg);
oxTracef("assert", "Failed assert: {} ({}) [{}:{}]", msg, assertTxt, file, line);
constexprPanic(file, line, msg);
#endif
}
void assertFailFuncRuntime(StringViewCR file, int line, [[maybe_unused]] const Error &err, StringViewCR, StringViewCR assertMsg) noexcept {
#if defined(OX_USE_STDLIB)
auto msg = sfmt("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, assertMsg);
if (err.msg) {
msg += sfmt("\tError Message:\t{}\n", err.msg);
}
msg += sfmt("\tError Code:\t{}\n", static_cast<ErrorCode>(err));
if (err.file != nullptr) {
msg += sfmt("\tError Location:\t{}:{}\n", err.file, err.line);
}
msg += genStackTrace(2);
oxErr(msg);
oxTracef("assert", "Failed assert: {} [{}:{}]", assertMsg, file, line);
std::abort();
#else
constexprPanic(file, line, assertMsg);
#endif
}
}

View File

@@ -32,19 +32,13 @@ constexpr void constexprPanic(StringViewCR file, int line, StringViewCR panicMsg
}
}
void assertFailFuncRuntime(StringViewCR file, int line, StringViewCR assertTxt, StringViewCR msg) noexcept;
void assertFailFuncRuntime(StringViewCR file, int line, const Error &err, StringViewCR, StringViewCR assertMsg) noexcept;
constexpr void assertFunc(StringViewCR file, int line, bool pass, [[maybe_unused]]StringViewCR assertTxt, [[maybe_unused]]StringViewCR msg) noexcept {
if (!pass) {
if (!std::is_constant_evaluated()) {
#ifdef OX_USE_STDLIB
auto output = sfmt("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, msg);
output += genStackTrace(2);
oxTracef("assert", "Failed assert: {} ({}) [{}:{}]", msg, assertTxt, file, line);
std::abort();
#else
oxErrf("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, msg);
oxTracef("assert", "Failed assert: {} ({}) [{}:{}]", msg, assertTxt, file, line);
constexprPanic(file, line, msg);
#endif
assertFailFuncRuntime(file, line, assertTxt, msg);
} else {
while (true);
}
@@ -54,22 +48,7 @@ constexpr void assertFunc(StringViewCR file, int line, bool pass, [[maybe_unused
constexpr void assertFunc(StringViewCR file, int line, const Error &err, StringViewCR, StringViewCR assertMsg) noexcept {
if (err) {
if (!std::is_constant_evaluated()) {
#if defined(OX_USE_STDLIB)
auto msg = sfmt("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, assertMsg);
if (err.msg) {
msg += sfmt("\tError Message:\t{}\n", err.msg);
}
msg += sfmt("\tError Code:\t{}\n", static_cast<ErrorCode>(err));
if (err.file != nullptr) {
msg += sfmt("\tError Location:\t{}:{}\n", err.file, err.line);
}
msg += genStackTrace(2);
oxErr(msg);
oxTracef("assert", "Failed assert: {} [{}:{}]", assertMsg, file, line);
std::abort();
#else
constexprPanic(file, line, assertMsg);
#endif
assertFailFuncRuntime(file, line, err, {}, assertMsg);
} else {
while (true);
}

View File

@@ -9,9 +9,12 @@
#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 {
@@ -202,7 +205,7 @@ class BaseStringView {
}
[[nodiscard]]
constexpr auto operator[](std::size_t i) const noexcept {
constexpr auto &operator[](std::size_t i) const noexcept {
return m_str[i];
}
@@ -215,3 +218,5 @@ class BaseStringView {
};
}
OX_CLANG_NOWARN_END

View File

@@ -14,12 +14,14 @@
#include "vector.hpp"
#include "writer.hpp"
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
namespace ox {
extern template class Vector<char>;
using Buffer = Vector<char>;
using BufferView = SpanView<char>;
using BufferView = Span<const char>;
class BufferWriter {
private:
@@ -100,15 +102,11 @@ class CharBuffWriter {
char *m_buff = nullptr;
public:
template<std::size_t sz>
explicit constexpr CharBuffWriter(ox::Array<char, sz> &buff) noexcept:
explicit constexpr CharBuffWriter(ox::Span<char> buff) noexcept:
m_cap(buff.size()),
m_buff(buff.data()) {
}
explicit constexpr CharBuffWriter(char *buff, std::size_t size) noexcept: m_cap(size), m_buff(buff) {
}
constexpr ox::Error seekp(std::size_t p) noexcept {
m_it = p;
return {};
@@ -237,3 +235,5 @@ extern template class WriterT<BufferWriter>;
extern template class WriterT<CharBuffWriter>;
}
OX_CLANG_NOWARN_END

View File

@@ -8,9 +8,12 @@
#pragma once
#include "def.hpp"
#include "types.hpp"
#include "typetraits.hpp"
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
namespace ox {
template<typename T1, typename T2>
@@ -113,3 +116,5 @@ constexpr int lastIndexOf(const auto &str, int character, std::size_t maxLen = 0
}
}
OX_CLANG_NOWARN_END

View File

@@ -44,10 +44,6 @@
// oxRequire Mutable
#define oxRequireM(out, x) auto [out, oxConcat(oxRequire_err_, __LINE__)] = x; oxReturnError(oxConcat(oxRequire_err_, __LINE__))
#define oxRequire(out, x) const oxRequireM(out, x)
// oxRequire Mutable Throw
#define oxRequireMT(out, x) auto [out, oxConcat(oxRequire_err_, __LINE__)] = x; oxThrowError(oxConcat(oxRequire_err_, __LINE__))
// oxRequire Throw
#define oxRequireT(out, x) const oxRequireMT(out, x)
// Asserts
@@ -75,6 +71,21 @@ constexpr void oxAssert(const ox::Error&, const char*) noexcept {}
#define ox_alloca(size) __builtin_alloca(size)
#endif
#define OX_PRAGMA(x) _Pragma(#x)
#ifdef __clang__
#define OX_CLANG_NOWARN_BEGIN(warnoption) \
OX_PRAGMA(clang diagnostic push) \
OX_PRAGMA(clang diagnostic ignored #warnoption)
#define OX_CLANG_NOWARN_END OX_PRAGMA(clang diagnostic pop)
#define OX_ALLOW_UNSAFE_BUFFERS_BEGIN OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
#define OX_ALLOW_UNSAFE_BUFFERS_END OX_CLANG_NOWARN_END
#else
#define OX_CLANG_NOWARN_BEGIN(warnoption)
#define OX_CLANG_NOWARN_END
#define OX_ALLOW_UNSAFE_BUFFERS_BEGIN
#define OX_ALLOW_UNSAFE_BUFFERS_END
#endif
/**
* @return an ox::MallocaPtr of the given type pointing to the requested size memory allocation
*/

View File

@@ -24,6 +24,7 @@ class exception {
}
#endif
#include "defines.hpp"
#include "def.hpp"
#include "typetraits.hpp"
#include "utility.hpp"
@@ -332,4 +333,12 @@ constexpr Error toError(const Result<T> &r) noexcept {
}
constexpr void primitiveAssert(const char *file, int line, bool pass, const char *msg) noexcept {
if constexpr(ox::defines::Debug) {
if (!pass) [[unlikely]] {
panic(file, line, msg, OxError(1));
}
}
}
}

View File

@@ -25,6 +25,8 @@
#include "types.hpp"
#include "typetraits.hpp"
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
namespace ox {
namespace detail {
@@ -81,16 +83,16 @@ class FmtArg {
private:
static constexpr auto DataSz = 23;
char dataStr[DataSz] = {};
ox::Array<char, DataSz> dataStr{};
template<typename T>
constexpr StringView sv(const T &v, char *dataStr) noexcept {
constexpr StringView sv(const T &v, ox::Span<char> dataStr) noexcept {
if constexpr(is_bool_v<T>) {
return v ? "true" : "false";
} else if constexpr(is_integer_v<T>) {
ox::CharBuffWriter w(dataStr, DataSz);
ox::CharBuffWriter w{dataStr};
std::ignore = ox::writeItoa(v, w);
return dataStr;
return dataStr.data();
} else {
return toStringView(v);
}
@@ -225,3 +227,5 @@ constexpr Result<T> join(auto const&d, auto const&list) {
}
}
OX_CLANG_NOWARN_END

View File

@@ -8,8 +8,11 @@
#include "assert.hpp"
#include "bit.hpp"
#include "def.hpp"
#include "heapmgr.hpp"
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
namespace ox::heapmgr {
static struct HeapSegment *volatile g_heapBegin = nullptr;
@@ -142,3 +145,5 @@ void operator delete[](void *ptr, unsigned long int) noexcept {
}
#endif
OX_CLANG_NOWARN_END

View File

@@ -10,6 +10,7 @@
#include "array.hpp"
#include "concepts.hpp"
#include "def.hpp"
#include "cstrops.hpp"
#include "memops.hpp"
#include "error.hpp"
@@ -175,7 +176,9 @@ constexpr Error IString<StrCap>::append(const char *str, std::size_t strLen) noe
strLen = cap() - currentLen;
err = OxError(1, "Insufficient space for full string");
}
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
ox::strncpy(m_buff.data() + currentLen, str, strLen);
OX_CLANG_NOWARN_END
// make sure last element is a null terminator
m_buff[currentLen + strLen] = 0;
m_size += strLen;
@@ -263,7 +266,7 @@ constexpr auto itoa(Integer v) noexcept {
}();
ox::IString<Cap> out;
std::ignore = out.resize(out.cap());
ox::CharBuffWriter w(out.data(), out.cap());
ox::CharBuffWriter w{{out.data(), out.cap()}};
std::ignore = writeItoa(v, w);
std::ignore = out.resize(w.tellp());
return out;

View File

@@ -8,6 +8,8 @@
#pragma once
#include "def.hpp"
#include "error.hpp"
#include "math.hpp"
#if !__has_include(<iterator>)
@@ -38,6 +40,8 @@ struct contiguous_iterator_tag: public random_access_iterator_tag {
#include <iterator>
#endif
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
namespace ox {
template<typename Category, typename T, typename DiffType = std::ptrdiff_t,
@@ -129,14 +133,17 @@ struct SpanIterator {
}
constexpr PtrType operator->() const noexcept {
ox::primitiveAssert(__FILE__, __LINE__, m_offset < m_max, "SpanIterator access overflow");
return &m_t[m_offset];
}
constexpr RefType operator*() const noexcept {
ox::primitiveAssert(__FILE__, __LINE__, m_offset < m_max, "SpanIterator access overflow");
return m_t[m_offset];
}
constexpr RefType operator[](std::size_t s) const noexcept {
ox::primitiveAssert(__FILE__, __LINE__, s < m_max, "SpanIterator access overflow");
return m_t[s];
}
@@ -167,3 +174,5 @@ struct SpanIterator {
};
}
OX_CLANG_NOWARN_END

View File

@@ -10,6 +10,8 @@
#include "types.hpp"
#include "memops.hpp"
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
#ifndef OX_USE_STDLIB
#define ox_inhibit_loop_to_libcall __attribute__((__optimize__("-fno-tree-loop-distribute-patterns")))
@@ -96,3 +98,5 @@ int memcmp(const void *ptr1, const void *ptr2, std::size_t size) noexcept {
}
}
OX_CLANG_NOWARN_END

View File

@@ -8,6 +8,7 @@
#pragma once
#include "def.hpp"
#include "types.hpp"
#include "typetraits.hpp"
@@ -27,6 +28,8 @@ int memcmp(const void *ptr1, const void *ptr2, std::size_t size) noexcept;
}
#endif
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
namespace ox {
template<typename T1, typename T2>
@@ -56,3 +59,5 @@ void *memsetElements(T *ptr, T val, std::size_t elements) noexcept {
}
}
OX_CLANG_NOWARN_END

View File

@@ -8,11 +8,7 @@
#pragma once
#include "bit.hpp"
#include "initializerlist.hpp"
#include "iterator.hpp"
#include "memory.hpp"
#include "new.hpp"
#include "types.hpp"
#include "utility.hpp"

View File

@@ -9,9 +9,12 @@
#pragma once
#include "bit.hpp"
#include "def.hpp"
#include "stddef.hpp"
#include "types.hpp"
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
namespace ox {
using RandomSeed = uint64_t[2];
@@ -51,3 +54,5 @@ constexpr uint64_t Random::gen() noexcept {
}
}
OX_CLANG_NOWARN_END

View File

@@ -10,135 +10,21 @@
#include "array.hpp"
#include "bit.hpp"
#include "def.hpp"
#include "iterator.hpp"
#include "vector.hpp"
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
namespace ox {
template<typename T>
class SpanView {
private:
T const*m_items{};
std::size_t m_size{};
public:
using value_type = T;
using size_type = std::size_t;
template<typename RefType = T const&, typename PtrType = T const*, bool reverse = false>
using iterator = SpanIterator<T, RefType, PtrType, reverse>;
constexpr SpanView() noexcept {}
template<std::size_t sz>
constexpr SpanView(ox::Array<T, sz> const&a) noexcept:
m_items(a.data()),
m_size(a.size()) {
}
template<std::size_t sz, typename Allocator>
constexpr SpanView(ox::Vector<T, sz, Allocator> const&v) noexcept:
m_items(v.data()),
m_size(v.size()) {
}
template<std::size_t sz>
constexpr SpanView(const T a[sz]) noexcept:
m_items(a),
m_size(sz) {
}
constexpr SpanView(const T *a, std::size_t sz) noexcept:
m_items(a),
m_size(sz) {
}
constexpr iterator<> begin() noexcept {
return iterator<>(m_items, 0, m_size);
}
constexpr iterator<> end() noexcept {
return iterator<>(m_items, m_size, m_size);
}
[[nodiscard]]
constexpr iterator<const T&, const T*> begin() const noexcept {
return iterator<const T&, const T*>(m_items, 0, m_size);
}
[[nodiscard]]
constexpr iterator<const T&, const T*> end() const noexcept {
return iterator<const T&, const T*>(m_items, m_size, m_size);
}
[[nodiscard]]
constexpr iterator<const T&, const T*> cbegin() const noexcept {
return iterator<const T&, const T*>(m_items, 0, m_size);
}
[[nodiscard]]
constexpr iterator<const T&, const T*> cend() const noexcept {
return iterator<const T&, const T*>(m_items, m_size, m_size);
}
[[nodiscard]]
constexpr iterator<const T&, const T*, true> crbegin() const noexcept {
return iterator<const T&, const T*, true>(m_items, m_size - 1, m_size);
}
[[nodiscard]]
constexpr iterator<const T&, const T*, true> crend() const noexcept {
return iterator<const T&, const T*, true>(m_items, MaxValue<size_type>, m_size);
}
[[nodiscard]]
constexpr iterator<const T&, const T*, true> rbegin() const noexcept {
return iterator<const T&, const T*, true>(m_items, m_size - 1, m_size);
}
[[nodiscard]]
constexpr iterator<const T&, const T*, true> rend() const noexcept {
return iterator<const T&, const T*, true>(m_items, MaxValue<size_type>, m_size);
}
constexpr const T &operator[](std::size_t i) const noexcept {
return m_items[i];
}
constexpr SpanView operator+(size_t i) const noexcept {
return {m_items + i, m_size - i};
}
constexpr SpanView operator+=(size_t i) noexcept {
m_items += i;
m_size -= i;
return *this;
}
[[nodiscard]]
constexpr T const*data() const noexcept {
return m_items;
}
[[nodiscard]]
constexpr std::size_t size() const noexcept {
return m_size;
}
[[nodiscard]]
constexpr bool empty() const noexcept {
return m_size == 0;
}
};
template<typename T>
class Span {
private:
T *m_items{};
const std::size_t m_size{};
std::size_t m_size{};
public:
using value_type = T;
@@ -147,20 +33,34 @@ class Span {
template<typename RefType = T&, typename PtrType = T*, bool reverse = false>
using iterator = SpanIterator<T, RefType, PtrType, reverse>;
constexpr Span() noexcept = default;
template<std::size_t sz>
constexpr Span(ox::Array<T, sz> &a) noexcept:
m_items(a.data()),
m_size(a.size()) {
}
template<std::size_t sz>
constexpr Span(ox::Array<ox::remove_const_t<T>, sz> const&a) noexcept:
m_items(a.data()),
m_size(a.size()) {
}
template<std::size_t sz, typename Allocator>
constexpr Span(ox::Vector<T, sz, Allocator> &v) noexcept:
m_items(v.data()),
m_size(v.size()) {
}
template<std::size_t sz, typename Allocator>
constexpr Span(ox::Vector<ox::remove_const_t<T>, sz, Allocator> const&v) noexcept:
m_items(v.data()),
m_size(v.size()) {
}
template<std::size_t sz>
constexpr Span(T a[sz]) noexcept:
constexpr Span(T (&a)[sz]) noexcept:
m_items(a),
m_size(sz) {
}
@@ -229,13 +129,27 @@ class Span {
}
constexpr T &operator[](std::size_t i) noexcept {
ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Span access overflow");
return m_items[i];
}
constexpr const T &operator[](std::size_t i) const noexcept {
ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Span access overflow");
return m_items[i];
}
constexpr Span operator+(size_t i) const noexcept {
ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Span access overflow");
return {m_items + i, m_size - i};
}
constexpr Span operator+=(size_t i) noexcept {
ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Span access overflow");
m_items += i;
m_size -= i;
return *this;
}
[[nodiscard]]
constexpr auto data() const noexcept {
return m_items;
@@ -253,4 +167,9 @@ class Span {
};
template<typename T>
using SpanView = Span<const T>;
}
OX_CLANG_NOWARN_END

View File

@@ -18,11 +18,14 @@
#endif
#endif
#include "def.hpp"
#include "defines.hpp"
#include "string.hpp"
#include "trace.hpp"
#include "vector.hpp"
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
namespace ox {
#if defined(OX_USE_STDLIB) && __has_include(<unistd.h>)
@@ -100,3 +103,5 @@ void printStackTrace([[maybe_unused]]unsigned shave) noexcept {
}
}
OX_CLANG_NOWARN_END

View File

@@ -13,6 +13,7 @@
#endif
#include "algorithm.hpp"
#include "def.hpp"
#include "ignore.hpp"
#include "memops.hpp"
#include "serialize.hpp"
@@ -22,6 +23,8 @@
#include "strops.hpp"
#include "vector.hpp"
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
namespace ox {
template<typename Integer>
@@ -496,12 +499,12 @@ constexpr char &BasicString<SmallStringSize_v>::operator[](std::size_t i) noexce
template<std::size_t SmallStringSize_v>
constexpr BasicString<SmallStringSize_v> BasicString<SmallStringSize_v>::substr(std::size_t pos) const noexcept {
return BasicString(m_buff.data() + pos, m_buff.size() - pos - 1);
return BasicString(&m_buff[pos], m_buff.size() - pos - 1);
}
template<std::size_t SmallStringSize_v>
constexpr BasicString<SmallStringSize_v> BasicString<SmallStringSize_v>::substr(std::size_t begin, std::size_t end) const noexcept {
const auto src = m_buff.data() + begin;
const auto src = &m_buff[begin];
const auto size = end - begin;
BasicString<SmallStringSize_v> out(size);
const auto buff = out.data();
@@ -568,3 +571,5 @@ struct MaybeView<ox::BasicString<sz>> {
};
}
OX_CLANG_NOWARN_END

View File

@@ -17,6 +17,8 @@
#include "maybeview.hpp"
#include "writer.hpp"
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
namespace ox {
template<std::size_t buffLen>
@@ -116,3 +118,4 @@ constexpr ox::Result<int> atoi(ox::StringViewCR str) noexcept {
}
OX_CLANG_NOWARN_END

View File

@@ -6,6 +6,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include "def.hpp"
#include "strops.hpp"
static_assert(ox::strcmp("asdf", "hijk") < 0, "asdf < hijk");
@@ -17,7 +18,9 @@ static_assert(ox::strcmp("", "") == 0, "\"\" == \"\"");
static_assert([] {
auto testStr = "asdf";
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
return ox::strchr(testStr, 0, 4) == &testStr[4];
OX_CLANG_NOWARN_END
}(), "ox::strchr 0");
static_assert([] {

View File

@@ -9,18 +9,21 @@
#pragma once
#include "cstrops.hpp"
#include "def.hpp"
#include "error.hpp"
#include "math.hpp"
#include "stringview.hpp"
#include "types.hpp"
#include "vector.hpp"
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
namespace ox {
[[nodiscard]]
constexpr ox::StringView substr(ox::StringView const&str, std::size_t pos) noexcept {
if (str.len() >= pos) {
return {str.data() + pos, str.len() - pos};
return {&str[pos], str.len() - pos};
}
return {};
}
@@ -28,7 +31,7 @@ constexpr ox::StringView substr(ox::StringView const&str, std::size_t pos) noexc
[[nodiscard]]
constexpr ox::StringView substr(ox::StringView const&str, std::size_t start, std::size_t end) noexcept {
if (str.len() >= start && end >= start) {
return {str.data() + start, end - start};
return {&str[start], end - start};
}
return {};
}
@@ -113,3 +116,5 @@ constexpr ox::Result<std::size_t> lastIndexOf(ox::StringViewCR str, int characte
}
}
OX_CLANG_NOWARN_END

View File

@@ -121,7 +121,9 @@ static std::map<ox::StringView, ox::Error(*)()> tests = {
auto a1 = static_cast<char*>(ox::heapmgr::malloc(5));
auto a2 = static_cast<char*>(ox::heapmgr::malloc(5));
oxAssert(a1 >= buff.front().unwrap() && a1 < buff.back().unwrap(), "malloc is broken");
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
oxAssert(a2 >= buff.front().unwrap() && a2 < buff.back().unwrap() && a2 > a1 + 5, "malloc is broken");
OX_CLANG_NOWARN_END
ox::heapmgr::free(a1);
ox::heapmgr::free(a2);
return OxError(0);
@@ -470,10 +472,12 @@ static std::map<ox::StringView, ox::Error(*)()> tests = {
},
};
int main(int argc, const char **args) {
int main(int argc, const char **argv) {
if (argc < 2) {
oxError("Must specify test to run");
return -1;
}
auto const args = ox::Span{argv, static_cast<size_t>(argc)};
auto const testName = args[1];
auto const func = tests.find(testName);
if (func != tests.end()) {

View File

@@ -10,6 +10,17 @@
namespace ox::trace {
static class: public Logger {
public:
ox::Error send(const TraceMsg&) noexcept final {
return {};
}
ox::Error sendInit(const InitTraceMsg&) noexcept final {
return {};
}
} defaultLogger;
static Logger *logger = &defaultLogger;
void init() {
oxTraceInitHook();
}
@@ -19,19 +30,6 @@ void init(Logger *logger) {
setLogger(logger);
}
class NullLogger: public Logger {
public:
ox::Error send(const TraceMsg&) noexcept final {
return {};
}
ox::Error sendInit(const InitTraceMsg&) noexcept final {
return {};
}
};
static NullLogger defaultLogger;
static Logger *logger = &defaultLogger;
void setLogger(Logger *logger) noexcept {
trace::logger = logger;
}

View File

@@ -173,7 +173,7 @@ class OutStream {
return *this;
}
constexpr OutStream &operator<<(const char *v) noexcept {
constexpr OutStream &operator<<(StringViewCR v) noexcept {
if (m_msg.msg.len()) {
m_msg.msg += m_delimiter;
}
@@ -181,6 +181,10 @@ class OutStream {
return *this;
}
constexpr OutStream &operator<<(const char *v) noexcept {
return operator<<(StringView{v});
}
template<std::size_t sz>
constexpr OutStream &operator<<(const IString<sz> &v) noexcept {
return operator<<(v.c_str());

View File

@@ -269,6 +269,41 @@ template<class T>
constexpr bool is_move_constructible_v = detail::is_move_constructible<T>(0);
template<typename T>
struct remove_cv {
using type = T;
};
template<typename T>
struct remove_cv<const T> {
using type = T;
};
template<typename T>
struct remove_cv<volatile T> {
using type = T;
};
template<typename T>
struct remove_cv<const volatile T> {
using type = T;
};
template<typename T>
struct remove_const {
using type = T;
};
template<typename T>
struct remove_const<const T> {
using type = T;
};
template<typename T>
using remove_const_t = typename remove_const<T>::type;
// is String?
template<std::size_t SmallStringSize>

View File

@@ -9,6 +9,7 @@
#pragma once
#include "bit.hpp"
#include "def.hpp"
#include "ignore.hpp"
#include "istring.hpp"
#include "buffer.hpp"
@@ -18,6 +19,8 @@
#include "stringview.hpp"
#include "strops.hpp"
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
namespace ox {
using UUIDStr = ox::IString<36>;
@@ -107,12 +110,12 @@ class UUID {
static ox::Result<UUID> generate() noexcept;
[[nodiscard]]
constexpr auto const&value() const noexcept {
constexpr ox::Array<uint8_t, 16> const&value() const noexcept {
return m_value;
}
[[nodiscard]]
constexpr auto isNull() const noexcept {
constexpr bool isNull() const noexcept {
if (std::is_constant_evaluated()) {
if (ox::all_of(m_value.begin(), m_value.end(), [](auto v) { return v == 0; })) {
return true;
@@ -187,7 +190,7 @@ class UUID {
constexpr UUIDStr toString() const noexcept {
UUIDStr out;
std::ignore = out.resize(UUIDStr::cap());
ox::CharBuffWriter bw(out.data(), UUIDStr::cap());
ox::CharBuffWriter bw{{out.data(), UUIDStr::cap()}};
std::ignore = toString(bw);
out[UUIDStr::cap()] = 0;
return out;
@@ -220,3 +223,5 @@ constexpr Error model(T *io, ox::CommonPtrWith<UUID> auto *obj) noexcept {
}
}
OX_CLANG_NOWARN_END

View File

@@ -14,7 +14,7 @@ namespace ox {
static_assert([] {
Vec2 v(1, 2);
return v.x == 1 && v.y == 2 && v[0] == 1 && v[1] == 2 && v.size() == 2;
return v.x == 1 && v.y == 2 && v.size() == 2;
}());
}

View File

@@ -34,112 +34,6 @@ class Vec2 {
float x = 0;
float y = 0;
template<typename RefType = value_type&, typename PtrType = value_type*, bool reverse = false>
struct iterator: public ox::Iterator<std::bidirectional_iterator_tag, value_type> {
private:
PtrType m_t = nullptr;
size_type m_offset = 0;
size_type m_max = 0;
public:
constexpr iterator() noexcept = default;
constexpr iterator(PtrType t, size_type offset, size_type max) noexcept {
m_t = t;
m_offset = offset;
m_max = max;
}
[[nodiscard]]
constexpr auto offset() const noexcept {
return m_offset;
}
constexpr iterator operator+(size_type s) const noexcept {
if constexpr(reverse) {
return iterator(m_t, ox::max<size_type>(m_offset - s, 0), m_max);
} else {
return iterator(m_t, ox::min<size_type>(m_offset + s, m_max), m_max);
}
}
constexpr typename ox::Iterator<std::bidirectional_iterator_tag, value_type>::difference_type
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-(size_type s) const noexcept {
if constexpr(reverse) {
return iterator(m_t, ox::min<size_type>(m_offset + s, m_max), m_max);
} else {
return iterator(m_t, ox::max<size_type>(m_offset - s, 0), m_max);
}
}
constexpr iterator &operator+=(size_type s) noexcept {
if constexpr(reverse) {
m_offset = ox::max<size_type>(m_offset - s, 0);
} else {
m_offset = ox::min(m_offset + s, m_max);
}
return *this;
}
constexpr iterator &operator-=(size_type s) noexcept {
if constexpr(reverse) {
m_offset = ox::min(m_offset + s, m_max);
} else {
m_offset = ox::max<size_type>(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[](size_type 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;
}
};
constexpr Vec2() noexcept = default;
explicit constexpr Vec2(class Point const&pt) noexcept;
@@ -159,85 +53,8 @@ class Vec2 {
}
#endif
[[nodiscard]]
constexpr iterator<> begin() noexcept {
return {start(), 0, size()};
}
[[nodiscard]]
constexpr iterator<> end() noexcept {
return {start(), size(), size()};
}
[[nodiscard]]
constexpr iterator<const value_type&, const value_type*> begin() const noexcept {
return {start(), 0, size()};
}
[[nodiscard]]
constexpr iterator<const value_type&, const value_type*> end() const noexcept {
return {start(), size(), size()};
}
[[nodiscard]]
constexpr iterator<value_type&, value_type*, true> rbegin() noexcept {
return {start(), size() - 1, size()};
}
[[nodiscard]]
constexpr iterator<value_type&, value_type*, true> rend() noexcept {
return {start(), ox::MaxValue<size_type>, size()};
}
[[nodiscard]]
constexpr iterator<const value_type&, const value_type*, true> rbegin() const noexcept {
return {start(), size() - 1, size()};
}
[[nodiscard]]
constexpr iterator<const value_type&, const value_type*, true> rend() const noexcept {
return {start(), ox::MaxValue<size_type>, size()};
}
constexpr auto &operator[](std::size_t i) noexcept {
if (std::is_constant_evaluated()) {
switch (i) {
case 0:
return x;
case 1:
return y;
default:
oxAssert(false, "Read past end of Vec2");
return y;
}
} else {
return start()[i];
}
}
constexpr const auto &operator[](std::size_t i) const noexcept {
if (std::is_constant_evaluated()) {
switch (i) {
case 0:
return x;
case 1:
return y;
default:
oxAssert(false, "Read past end of Vec2");
return y;
}
} else {
return start()[i];
}
}
constexpr auto operator==(const Vec2 &v) const noexcept {
for (auto i = 0u; i < v.size(); ++i) {
if ((*this)[i] != v[i]) {
return false;
}
}
return true;
return x == v.x && y == v.y;
}
constexpr auto operator!=(const Vec2 &v) const noexcept {
@@ -292,17 +109,6 @@ class Vec2 {
y /= i;
return *this;
}
protected:
[[nodiscard]]
constexpr float *start() noexcept {
return&x;
}
[[nodiscard]]
constexpr const float *start() const noexcept {
return &x;
}
};
template<typename T>

View File

@@ -20,6 +20,8 @@
#include "types.hpp"
#include "utility.hpp"
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
namespace ox {
namespace detail {
@@ -422,11 +424,13 @@ constexpr Vector<T, SmallVectorSize, Allocator> &Vector<T, SmallVectorSize, Allo
template<typename T, std::size_t SmallVectorSize, typename Allocator>
constexpr T &Vector<T, SmallVectorSize, Allocator>::operator[](std::size_t i) noexcept {
ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Vector access overflow");
return m_items[i];
}
template<typename T, std::size_t SmallVectorSize, typename Allocator>
constexpr const T &Vector<T, SmallVectorSize, Allocator>::operator[](std::size_t i) const noexcept {
ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Vector access overflow");
return m_items[i];
}
@@ -707,3 +711,5 @@ constexpr auto alignOf(const Vector<T>&) noexcept {
}
}
OX_ALLOW_UNSAFE_BUFFERS_END