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:
7
deps/ox/src/ox/clargs/CMakeLists.txt
vendored
7
deps/ox/src/ox/clargs/CMakeLists.txt
vendored
@ -1,4 +1,9 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
|
||||
# enable warnings
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunsafe-buffer-usage")
|
||||
endif()
|
||||
|
||||
|
||||
add_library(
|
||||
OxClArgs
|
||||
|
12
deps/ox/src/ox/clargs/clargs.cpp
vendored
12
deps/ox/src/ox/clargs/clargs.cpp
vendored
@ -11,16 +11,18 @@
|
||||
|
||||
namespace ox {
|
||||
|
||||
ClArgs::ClArgs(int argc, const char **args) noexcept {
|
||||
for (auto i = 0u; i < static_cast<unsigned>(argc); ++i) {
|
||||
auto arg = String(args[i]);
|
||||
ClArgs::ClArgs(int argc, const char **args) noexcept: ClArgs({args, static_cast<size_t>(argc)}) {}
|
||||
|
||||
ClArgs::ClArgs(ox::SpanView<const char*> args) noexcept {
|
||||
for (auto i = 0u; i < args.size(); ++i) {
|
||||
auto arg = StringView(args[i]);
|
||||
if (arg[0] == '-') {
|
||||
while (arg[0] == '-' && arg.len()) {
|
||||
arg = arg.substr(1);
|
||||
arg = substr(arg, 1);
|
||||
}
|
||||
m_bools[arg] = true;
|
||||
// parse additional arguments
|
||||
if (i < static_cast<unsigned>(argc) && args[i + 1]) {
|
||||
if (i < args.size() && args[i + 1]) {
|
||||
auto val = String(args[i + 1]);
|
||||
if (val.len() && val[i] != '-') {
|
||||
if (val == "false") {
|
||||
|
3
deps/ox/src/ox/clargs/clargs.hpp
vendored
3
deps/ox/src/ox/clargs/clargs.hpp
vendored
@ -9,6 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <ox/std/hashmap.hpp>
|
||||
#include <ox/std/span.hpp>
|
||||
#include <ox/std/string.hpp>
|
||||
|
||||
namespace ox {
|
||||
@ -22,6 +23,8 @@ class ClArgs {
|
||||
public:
|
||||
ClArgs(int argc, const char **args) noexcept;
|
||||
|
||||
ClArgs(ox::SpanView<const char*> args) noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
bool getBool(ox::StringViewCR arg, bool defaultValue) const noexcept;
|
||||
|
||||
|
4
deps/ox/src/ox/fs/CMakeLists.txt
vendored
4
deps/ox/src/ox/fs/CMakeLists.txt
vendored
@ -1,3 +1,7 @@
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
|
||||
# enable warnings
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunsafe-buffer-usage")
|
||||
endif()
|
||||
|
||||
add_library(
|
||||
OxFS
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
#include <ox/fs/ptrarith/nodebuffer.hpp>
|
||||
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
|
||||
namespace ox {
|
||||
|
||||
using InodeId_t = uint64_t;
|
||||
@ -771,3 +773,5 @@ using FileStore16 = FileStoreTemplate<uint16_t>;
|
||||
using FileStore32 = FileStoreTemplate<uint32_t>;
|
||||
|
||||
}
|
||||
|
||||
OX_CLANG_NOWARN_END
|
||||
|
4
deps/ox/src/ox/fs/filesystem/directory.hpp
vendored
4
deps/ox/src/ox/fs/filesystem/directory.hpp
vendored
@ -15,6 +15,8 @@
|
||||
|
||||
#include "types.hpp"
|
||||
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
|
||||
namespace ox {
|
||||
|
||||
template<typename InodeId_t>
|
||||
@ -333,3 +335,5 @@ using Directory16 = Directory<FileStore16, uint16_t>;
|
||||
using Directory32 = Directory<FileStore32, uint32_t>;
|
||||
|
||||
}
|
||||
|
||||
OX_CLANG_NOWARN_END
|
||||
|
@ -32,7 +32,9 @@ FileAddress::FileAddress(ox::StringViewCR path) noexcept {
|
||||
auto pathSize = path.bytes();
|
||||
m_data.path = new char[pathSize + 1];
|
||||
memcpy(m_data.path, path.data(), pathSize);
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
m_data.path[pathSize] = 0;
|
||||
OX_CLANG_NOWARN_END
|
||||
m_type = FileAddressType::Path;
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,8 @@
|
||||
#include <ox/model/typenamecatcher.hpp>
|
||||
#include <ox/model/types.hpp>
|
||||
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
|
||||
namespace ox {
|
||||
|
||||
enum class FileAddressType: int8_t {
|
||||
@ -180,3 +182,5 @@ constexpr Error model(T *h, CommonPtrWith<FileAddress> auto *fa) noexcept {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
OX_CLANG_NOWARN_END
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include <ox/std/trace.hpp>
|
||||
#include "pathiterator.hpp"
|
||||
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
|
||||
namespace ox {
|
||||
|
||||
PathIterator::PathIterator(const char *path, std::size_t maxSize, std::size_t iterator) {
|
||||
@ -30,7 +32,7 @@ PathIterator::PathIterator(StringViewCR path): PathIterator(path.data(), path.by
|
||||
*/
|
||||
Error PathIterator::dirPath(char *out, std::size_t outSize) {
|
||||
const auto idx = ox::lastIndexOf(m_path, '/', m_maxSize);
|
||||
const auto size = static_cast<std::size_t>(idx + 1);
|
||||
const auto size = static_cast<std::size_t>(idx) + 1;
|
||||
if (idx >= 0 && size < outSize) {
|
||||
ox::memcpy(out, m_path, size);
|
||||
out[size] = 0;
|
||||
@ -183,3 +185,5 @@ const char *PathIterator::fullPath() const {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
OX_CLANG_NOWARN_END
|
||||
|
4
deps/ox/src/ox/fs/ptrarith/nodebuffer.hpp
vendored
4
deps/ox/src/ox/fs/ptrarith/nodebuffer.hpp
vendored
@ -13,6 +13,8 @@
|
||||
|
||||
#include "ptr.hpp"
|
||||
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
|
||||
namespace ox::ptrarith {
|
||||
|
||||
template<typename size_t, typename Item>
|
||||
@ -449,3 +451,5 @@ struct OX_PACKED Item {
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
OX_CLANG_NOWARN_END
|
||||
|
4
deps/ox/src/ox/fs/ptrarith/ptr.hpp
vendored
4
deps/ox/src/ox/fs/ptrarith/ptr.hpp
vendored
@ -10,6 +10,8 @@
|
||||
|
||||
#include <ox/std/std.hpp>
|
||||
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
|
||||
namespace ox::ptrarith {
|
||||
|
||||
template<typename T, typename size_t, size_t minOffset = 1>
|
||||
@ -256,3 +258,5 @@ constexpr Result<Ptr<T, size_t, minOffset>> Ptr<T, size_t, minOffset>::validate(
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
OX_CLANG_NOWARN_END
|
||||
|
5
deps/ox/src/ox/fs/test/tests.cpp
vendored
5
deps/ox/src/ox/fs/test/tests.cpp
vendored
@ -226,13 +226,14 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> 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)};
|
||||
ox::StringView const testName = args[1];
|
||||
ox::StringView const testArg = args[2] ? args[2] : nullptr;
|
||||
ox::StringView const testArg = argc >= 3 ? args[2] : nullptr;
|
||||
auto const func = tests.find(testName);
|
||||
if (func != tests.end()) {
|
||||
oxAssert(func->second(testArg), "Test returned Error");
|
||||
|
23
deps/ox/src/ox/fs/tool.cpp
vendored
23
deps/ox/src/ox/fs/tool.cpp
vendored
@ -39,25 +39,25 @@ static ox::Result<ox::UniquePtr<ox::FileSystem>> loadFs(const char *path) noexce
|
||||
return {ox::make_unique<ox::FileSystem32>(buff.data, buff.size)};
|
||||
}
|
||||
|
||||
static ox::Error runLs(ox::FileSystem *fs, int argc, const char **argv) noexcept {
|
||||
if (argc < 2) {
|
||||
static ox::Error runLs(ox::FileSystem *fs, ox::Span<const char*> args) noexcept {
|
||||
if (args.size() < 2) {
|
||||
oxErr("Must provide a directory to ls\n");
|
||||
return OxError(1);
|
||||
}
|
||||
oxRequire(files, fs->ls(argv[1]));
|
||||
oxRequire(files, fs->ls(args[1]));
|
||||
for (const auto &file : files) {
|
||||
oxOutf("{}\n", file);
|
||||
}
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
static ox::Error runRead(ox::FileSystem *fs, int argc, const char **argv) noexcept {
|
||||
if (argc < 2) {
|
||||
static ox::Error runRead(ox::FileSystem *fs, ox::Span<const char*> args) noexcept {
|
||||
if (args.size() < 2) {
|
||||
oxErr("Must provide a path to a file to read\n");
|
||||
return OxError(1);
|
||||
}
|
||||
oxRequire(buff, fs->read(ox::StringView(argv[1])));
|
||||
fwrite(buff.data(), sizeof(decltype(buff)::value_type), buff.size(), stdout);
|
||||
oxRequire(buff, fs->read(ox::StringView(args[1])));
|
||||
std::ignore = fwrite(buff.data(), sizeof(decltype(buff)::value_type), buff.size(), stdout);
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
@ -66,13 +66,14 @@ static ox::Error run(int argc, const char **argv) noexcept {
|
||||
oxErr("OxFS file and subcommand arguments are required\n");
|
||||
return OxError(1);
|
||||
}
|
||||
const auto fsPath = argv[1];
|
||||
ox::String subCmd(argv[2]);
|
||||
auto const args = ox::Span{argv, static_cast<size_t>(argc)};
|
||||
auto const fsPath = args[1];
|
||||
ox::String subCmd(args[2]);
|
||||
oxRequire(fs, loadFs(fsPath));
|
||||
if (subCmd == "ls") {
|
||||
return runLs(fs.get(), argc - 2, argv + 2);
|
||||
return runLs(fs.get(), args + 2);
|
||||
} else if (subCmd == "read") {
|
||||
return runRead(fs.get(), argc - 2, argv + 2);
|
||||
return runRead(fs.get(), args + 2);
|
||||
}
|
||||
return OxError(1);
|
||||
}
|
||||
|
4
deps/ox/src/ox/logconn/circularbuff.hpp
vendored
4
deps/ox/src/ox/logconn/circularbuff.hpp
vendored
@ -45,6 +45,7 @@ class CirculerBuffer {
|
||||
if (sz > avail()) {
|
||||
return OxError(1, "Insufficient space in buffer");
|
||||
}
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
// write seg 1
|
||||
const auto seg1Sz = ox::min(sz, m_buff.size() - m_writePt);
|
||||
ox::listcpy(&m_buff[m_writePt], &buff[0], seg1Sz);
|
||||
@ -56,6 +57,7 @@ class CirculerBuffer {
|
||||
ox::listcpy(&m_buff[0], &buff[seg1Sz], seg2Sz);
|
||||
oxAssert(m_buff[0] == buff[seg1Sz], "break");
|
||||
}
|
||||
OX_ALLOW_UNSAFE_BUFFERS_END
|
||||
return {};
|
||||
}
|
||||
|
||||
@ -90,7 +92,9 @@ class CirculerBuffer {
|
||||
m_readPt -= m_buff.size();
|
||||
// read seg 2
|
||||
const auto seg2Sz = bytesRead - seg1Sz;
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
ox::listcpy(&out[seg1Sz], &m_buff[0], seg2Sz);
|
||||
OX_ALLOW_UNSAFE_BUFFERS_END
|
||||
}
|
||||
return bytesRead;
|
||||
}
|
||||
|
28
deps/ox/src/ox/logconn/logconn.cpp
vendored
28
deps/ox/src/ox/logconn/logconn.cpp
vendored
@ -9,8 +9,8 @@
|
||||
#ifdef OX_USE_STDLIB
|
||||
#include <cstdio>
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifndef _WIN32
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
@ -25,15 +25,22 @@
|
||||
|
||||
#include "logconn.hpp"
|
||||
|
||||
#include <ox/std/bit.hpp>
|
||||
|
||||
namespace ox {
|
||||
|
||||
#ifdef _WIN32
|
||||
using Socket = SOCKET;
|
||||
using LenType = int;
|
||||
#else
|
||||
using Socket = int;
|
||||
using LenType = size_t;
|
||||
#endif
|
||||
|
||||
using namespace trace;
|
||||
|
||||
void closeSock(auto s) noexcept {
|
||||
static void closeSock(auto s) noexcept {
|
||||
#ifdef _WIN32
|
||||
closesocket(s);
|
||||
closesocket(static_cast<Socket>(s));
|
||||
#else
|
||||
close(s);
|
||||
#endif
|
||||
@ -56,8 +63,8 @@ ox::Error LoggerConn::initConn(ox::StringViewCR appName) noexcept {
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
addr.sin_port = htons(5590);
|
||||
m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
oxReturnError(OxError(static_cast<ox::ErrorCode>(connect(m_socket, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)))));
|
||||
m_socket = static_cast<int>(socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
|
||||
oxReturnError(OxError(static_cast<ox::ErrorCode>(connect(static_cast<Socket>(m_socket), reinterpret_cast<sockaddr*>(&addr), sizeof(addr)))));
|
||||
return sendInit({.appName = ox::BasicString<128>(appName)});
|
||||
}
|
||||
|
||||
@ -65,9 +72,9 @@ ox::Error LoggerConn::send(const char *buff, std::size_t len) const noexcept {
|
||||
std::size_t totalSent = 0;
|
||||
while (totalSent < len) {
|
||||
//std::fprintf(stdout, "Sending %lu/%lu bytes on socket %d\n", len, totalSent, m_socket);
|
||||
const auto sent = ::send(m_socket, buff, len, 0);
|
||||
const auto sent = ::send(static_cast<Socket>(m_socket), buff, static_cast<LenType>(len), 0);
|
||||
if (sent < 0) {
|
||||
std::fprintf(stderr, "Could not send msg\n");
|
||||
std::ignore = std::fprintf(stderr, "Could not send msg\n");
|
||||
return OxError(1, "Could not send msg");
|
||||
}
|
||||
totalSent += static_cast<std::size_t>(sent);
|
||||
@ -90,13 +97,14 @@ void LoggerConn::msgSend() noexcept {
|
||||
if (!m_running) {
|
||||
break;
|
||||
}
|
||||
std::lock_guard buffLk(m_buffMut);
|
||||
std::lock_guard const buffLk(m_buffMut);
|
||||
while (true) {
|
||||
ox::Array<char, ox::units::KB> tmp;
|
||||
Array<char, units::KB> tmp;
|
||||
const auto read = m_buff.read(tmp.data(), tmp.size());
|
||||
if (!read) {
|
||||
break;
|
||||
}
|
||||
oxAssert(read <= tmp.size(), "logger trying to read too much data");
|
||||
//std::printf("LoggerConn: sending %lu bytes\n", read);
|
||||
std::ignore = send(tmp.data(), read);
|
||||
}
|
||||
|
10
deps/ox/src/ox/mc/intops.hpp
vendored
10
deps/ox/src/ox/mc/intops.hpp
vendored
@ -57,7 +57,7 @@ static_assert(highestBit(uint64_t(1) << 31) == 31);
|
||||
static_assert(highestBit(uint64_t(1) << 63) == 63);
|
||||
|
||||
struct McInt {
|
||||
uint8_t data[9] = {};
|
||||
ox::Array<uint8_t, 9> data{};
|
||||
// length of integer in bytes
|
||||
std::size_t length = 0;
|
||||
};
|
||||
@ -104,7 +104,7 @@ constexpr McInt encodeInteger(I pInput) noexcept {
|
||||
auto intermediate =
|
||||
static_cast<uint64_t>(leVal.raw() | (negBit << (valBits - 1))) << bytes |
|
||||
static_cast<uint64_t>(bytesIndicator);
|
||||
ox::memcpy(out.data, &intermediate, sizeof(intermediate));
|
||||
ox::memcpy(&out.data[0], &intermediate, sizeof(intermediate));
|
||||
}
|
||||
out.length = bytes;
|
||||
}
|
||||
@ -160,7 +160,7 @@ constexpr Result<I> decodeInteger(Reader_c auto&rdr, std::size_t *bytesRead) noe
|
||||
ox::Array<uint32_t, 2> d = {};
|
||||
//d[0] = decoded & 0xffff'ffff;
|
||||
//d[1] = decoded >> 32;
|
||||
ox::memcpy(d.data(), &decoded, sizeof(decoded));
|
||||
ox::memcpy(&d[0], &decoded, sizeof(decoded));
|
||||
auto bit = negBit;
|
||||
for (; bit < ox::min<std::size_t>(Bits<I>, 32); ++bit) {
|
||||
d[0] |= 1 << bit;
|
||||
@ -175,7 +175,7 @@ constexpr Result<I> decodeInteger(Reader_c auto&rdr, std::size_t *bytesRead) noe
|
||||
d[0] = d[1];
|
||||
d[1] = d0Tmp;
|
||||
}
|
||||
ox::memcpy(&out, d.data(), sizeof(out));
|
||||
ox::memcpy(&out, &d[0], sizeof(out));
|
||||
return out;
|
||||
}
|
||||
}
|
||||
@ -185,7 +185,7 @@ constexpr Result<I> decodeInteger(Reader_c auto&rdr, std::size_t *bytesRead) noe
|
||||
template<typename I>
|
||||
Result<I> decodeInteger(McInt m) noexcept {
|
||||
std::size_t bytesRead{};
|
||||
BufferReader br({reinterpret_cast<const char*>(m.data), 9});
|
||||
BufferReader br({reinterpret_cast<const char*>(m.data.data()), 9});
|
||||
return decodeInteger<I>(br, &bytesRead);
|
||||
}
|
||||
|
||||
|
2
deps/ox/src/ox/mc/presenceindicator.hpp
vendored
2
deps/ox/src/ox/mc/presenceindicator.hpp
vendored
@ -147,11 +147,13 @@ constexpr FieldBitmap::FieldBitmap(uint8_t *map, std::size_t maxLen) noexcept:
|
||||
|
||||
constexpr Error FieldBitmap::set(std::size_t i, bool on) noexcept {
|
||||
if (i / 8 < m_mapLen) {
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
if (on) {
|
||||
m_map[i / 8] |= 1 << (i % 8);
|
||||
} else {
|
||||
m_map[i / 8] &= ~static_cast<uint8_t>(1 << (i % 8));
|
||||
}
|
||||
OX_ALLOW_UNSAFE_BUFFERS_END
|
||||
return {};
|
||||
} else {
|
||||
return OxError(McPresenceMapOverflow);
|
||||
|
10
deps/ox/src/ox/mc/read.hpp
vendored
10
deps/ox/src/ox/mc/read.hpp
vendored
@ -214,7 +214,9 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char *name, auto *v
|
||||
auto &handler = *reader.interface();
|
||||
oxReturnError(handler.setTypeInfo("List", 0, {}, static_cast<std::size_t>(len)));
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
oxReturnError(handler.field({}, &val[i]));
|
||||
OX_ALLOW_UNSAFE_BUFFERS_END
|
||||
}
|
||||
} else {
|
||||
oxTracef("ox.mc.read.field(T)", "{}, length: {}", name, valLen);
|
||||
@ -380,9 +382,9 @@ constexpr Error MetalClawReaderTemplate<Reader>::fieldCString(const char*, char
|
||||
// re-allocate in case too small
|
||||
safeDelete(*val);
|
||||
*val = new char[size + 1];
|
||||
auto data = *val;
|
||||
auto data = ox::Span{*val, size + 1};
|
||||
// read the string
|
||||
oxReturnError(m_reader.read(data, size));
|
||||
oxReturnError(m_reader.read(data.data(), size));
|
||||
data[size] = 0;
|
||||
}
|
||||
++m_field;
|
||||
@ -402,9 +404,9 @@ constexpr Error MetalClawReaderTemplate<Reader>::fieldCString(const char*, char
|
||||
*val = new char[size + 1];
|
||||
buffLen = size + 1;
|
||||
}
|
||||
auto data = *val;
|
||||
auto data = ox::Span{*val, size + 1};
|
||||
// read the string
|
||||
oxReturnError(m_reader.read(data, size));
|
||||
oxReturnError(m_reader.read(data.data(), size));
|
||||
data[size] = 0;
|
||||
} else {
|
||||
auto data = *val;
|
||||
|
16
deps/ox/src/ox/mc/write.hpp
vendored
16
deps/ox/src/ox/mc/write.hpp
vendored
@ -117,7 +117,7 @@ class MetalClawWriter {
|
||||
bool fieldSet = false;
|
||||
if (val && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
|
||||
auto mi = mc::encodeInteger(val);
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(mi.data), mi.length));
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(mi.data.data()), mi.length));
|
||||
fieldSet = true;
|
||||
}
|
||||
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
|
||||
@ -194,7 +194,7 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const BasicString<Sm
|
||||
if (val->len() && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
|
||||
// write the length
|
||||
const auto strLen = mc::encodeInteger(val->len());
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLen.data), strLen.length));
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLen.data.data()), strLen.length));
|
||||
// write the string
|
||||
oxReturnError(m_writer.write(val->c_str(), static_cast<std::size_t>(val->len())));
|
||||
fieldSet = true;
|
||||
@ -217,7 +217,7 @@ constexpr Error MetalClawWriter<Writer>::fieldCString(const char*, const char *c
|
||||
const auto strLen = *val ? ox::strlen(*val) : 0;
|
||||
// write the length
|
||||
const auto strLenBuff = mc::encodeInteger(strLen);
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLenBuff.data), strLenBuff.length));
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLenBuff.data.data()), strLenBuff.length));
|
||||
// write the string
|
||||
oxReturnError(m_writer.write(*val, static_cast<std::size_t>(strLen)));
|
||||
fieldSet = true;
|
||||
@ -243,7 +243,7 @@ constexpr Error MetalClawWriter<Writer>::fieldCString(const char*, const char *v
|
||||
if (strLen && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
|
||||
// write the length
|
||||
const auto strLenBuff = mc::encodeInteger(strLen);
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLenBuff.data), strLenBuff.length));
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLenBuff.data.data()), strLenBuff.length));
|
||||
// write the string
|
||||
oxReturnError(m_writer.write(val, static_cast<std::size_t>(strLen)));
|
||||
fieldSet = true;
|
||||
@ -298,14 +298,16 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const T *val, std::s
|
||||
if (len && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
|
||||
// write the length
|
||||
const auto arrLen = mc::encodeInteger(len);
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(arrLen.data), arrLen.length));
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(arrLen.data.data()), arrLen.length));
|
||||
auto const writeIdx = m_writer.tellp();
|
||||
MetalClawWriter<Writer> writer(m_writer);
|
||||
ModelHandlerInterface handler{&writer};
|
||||
oxReturnError(handler.template setTypeInfo<T>("List", 0, {}, static_cast<std::size_t>(len)));
|
||||
// write the array
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
oxReturnError(handler.field("", &val[i]));
|
||||
OX_ALLOW_UNSAFE_BUFFERS_END
|
||||
}
|
||||
oxReturnError(writer.finalize());
|
||||
fieldSet = writeIdx != m_writer.tellp();
|
||||
@ -324,7 +326,7 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const HashMap<String
|
||||
if (len && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
|
||||
// write the length
|
||||
const auto arrLen = mc::encodeInteger(len);
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(arrLen.data), arrLen.length));
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(arrLen.data.data()), arrLen.length));
|
||||
// write map
|
||||
MetalClawWriter<Writer> writer(m_writer);
|
||||
ModelHandlerInterface handler{&writer};
|
||||
@ -395,7 +397,7 @@ Result<Buffer> writeMC(auto const&val, std::size_t buffReserveSz = 2 * units::KB
|
||||
}
|
||||
|
||||
Error writeMC(char *buff, std::size_t buffLen, auto const&val, std::size_t *sizeOut = nullptr) noexcept {
|
||||
CharBuffWriter bw(buff, buffLen);
|
||||
CharBuffWriter bw{{buff, buffLen}};
|
||||
oxReturnError(writeMC(bw, val));
|
||||
if (sizeOut) {
|
||||
*sizeOut = bw.tellp();
|
||||
|
7
deps/ox/src/ox/model/desctypes.hpp
vendored
7
deps/ox/src/ox/model/desctypes.hpp
vendored
@ -90,7 +90,7 @@ constexpr Error model(T *io, CommonPtrWith<Subscript> auto *type) noexcept {
|
||||
}
|
||||
oxReturnError(io->field("length", &type->length));
|
||||
oxReturnError(io->field("smallSzLen", &type->smallSzLen));
|
||||
return OxError(0);
|
||||
return {};
|
||||
}
|
||||
|
||||
using SubscriptStack = Vector<Subscript, 3>;
|
||||
@ -119,6 +119,7 @@ struct DescriptorField {
|
||||
subscriptLevels(pSubscriptLevels),
|
||||
subscriptStack(std::move(pSubscriptType)),
|
||||
typeId(std::move(pTypeId)) {
|
||||
oxAssert(subscriptLevels <= static_cast<int>(subscriptStack.size()), "Subscript level mismatch");
|
||||
}
|
||||
|
||||
constexpr DescriptorField(const DescriptorField &other) noexcept:
|
||||
@ -202,7 +203,7 @@ constexpr Error model(T *io, CommonPtrWith<DescriptorType> auto *type) noexcept
|
||||
oxReturnError(io->field("fieldList", &type->fieldList));
|
||||
oxReturnError(io->field("length", &type->length));
|
||||
oxReturnError(io->field("preloadable", &type->preloadable));
|
||||
return OxError(0);
|
||||
return {};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@ -215,7 +216,7 @@ constexpr Error model(T *io, CommonPtrWith<DescriptorField> auto *field) noexcep
|
||||
// defaultValue is unused now, but leave placeholder for backwards compatibility
|
||||
int defaultValue = 0;
|
||||
oxReturnError(io->field("defaultValue", &defaultValue));
|
||||
return OxError(0);
|
||||
return {};
|
||||
}
|
||||
|
||||
template<typename ReaderBase>
|
||||
|
27
deps/ox/src/ox/model/descwrite.hpp
vendored
27
deps/ox/src/ox/model/descwrite.hpp
vendored
@ -97,8 +97,14 @@ class TypeDescWriter {
|
||||
std::size_t fields = ModelFieldCount_v<T>) noexcept;
|
||||
|
||||
template<typename T>
|
||||
constexpr Error field(StringViewCR name, const T *val, std::size_t valLen,
|
||||
const SubscriptStack &subscriptStack = {}) noexcept;
|
||||
constexpr Error field(
|
||||
StringViewCR name,
|
||||
T const*val,
|
||||
std::size_t valLen,
|
||||
SubscriptStack const&subscriptStack) noexcept;
|
||||
|
||||
template<typename T>
|
||||
constexpr Error field(StringViewCR name, T const*val, std::size_t valLen) noexcept;
|
||||
|
||||
template<typename T, bool force>
|
||||
constexpr Error field(StringViewCR name, UnionView<T, force> val) noexcept;
|
||||
@ -193,7 +199,7 @@ constexpr ox::Error TypeDescWriter::setTypeInfo(
|
||||
|
||||
// array handler
|
||||
template<typename T>
|
||||
constexpr Error TypeDescWriter::field(StringViewCR name, const T*, std::size_t, const SubscriptStack &subscriptStack) noexcept {
|
||||
constexpr Error TypeDescWriter::field(StringViewCR name, T const*, std::size_t, SubscriptStack const&subscriptStack) noexcept {
|
||||
if (m_type) {
|
||||
constexpr typename remove_pointer<T>::type *p = nullptr;
|
||||
const auto t = type(p);
|
||||
@ -204,6 +210,21 @@ constexpr Error TypeDescWriter::field(StringViewCR name, const T*, std::size_t,
|
||||
return OxError(1);
|
||||
}
|
||||
|
||||
// array handler
|
||||
template<typename T>
|
||||
constexpr Error TypeDescWriter::field(StringViewCR name, T const*, std::size_t) noexcept {
|
||||
if (m_type) {
|
||||
constexpr typename remove_pointer<T>::type *p = nullptr;
|
||||
const auto t = type(p);
|
||||
oxAssert(t != nullptr, "field(const char *name, T *val, std::size_t): Type not found or generated");
|
||||
auto const lvls = detail::indirectionLevels_v<T> + 1;
|
||||
SubscriptStack subscriptStack{lvls};
|
||||
m_type->fieldList.emplace_back(t, String(name), lvls, subscriptStack, buildTypeId(*t));
|
||||
return OxError(0);
|
||||
}
|
||||
return OxError(1);
|
||||
}
|
||||
|
||||
template<typename T, bool force>
|
||||
constexpr Error TypeDescWriter::field(StringViewCR name, UnionView<T, force> val) noexcept {
|
||||
if (m_type) {
|
||||
|
35
deps/ox/src/ox/model/modelvalue.hpp
vendored
35
deps/ox/src/ox/model/modelvalue.hpp
vendored
@ -188,8 +188,8 @@ class ModelValue {
|
||||
|
||||
constexpr Error setType(
|
||||
DescriptorType const*type,
|
||||
int subscriptLevels = 0,
|
||||
SubscriptStack const& = {}) noexcept;
|
||||
SubscriptStack const& = {},
|
||||
int subscriptLevels = 0) noexcept;
|
||||
|
||||
template<typename T>
|
||||
constexpr Error setType() noexcept;
|
||||
@ -242,7 +242,7 @@ class ModelValueArray {
|
||||
m_vec.resize(sz);
|
||||
if (sz > oldSz) {
|
||||
for (auto i = oldSz; i < sz; ++i) {
|
||||
oxReturnError(m_vec[i].setType(m_type, m_typeSubscriptLevels));
|
||||
oxReturnError(m_vec[i].setType(m_type, m_subscriptStack, m_typeSubscriptLevels));
|
||||
}
|
||||
}
|
||||
return {};
|
||||
@ -276,8 +276,9 @@ class ModelValueArray {
|
||||
|
||||
constexpr Error setType(
|
||||
DescriptorType const*type,
|
||||
int subscriptLevels,
|
||||
SubscriptStack subscriptStack) noexcept {
|
||||
SubscriptStack subscriptStack,
|
||||
int subscriptLevels) noexcept {
|
||||
oxAssert(subscriptLevels <= static_cast<int>(subscriptStack.size()), "subscript level mismatch");
|
||||
m_type = type;
|
||||
m_typeSubscriptLevels = subscriptLevels;
|
||||
m_subscriptStack = std::move(subscriptStack);
|
||||
@ -400,7 +401,7 @@ class ModelValueVector {
|
||||
m_vec.resize(sz);
|
||||
if (sz > oldSz) {
|
||||
for (auto i = oldSz; i < sz; ++i) {
|
||||
oxReturnError(m_vec[i].setType(m_type, m_typeSubscriptLevels, m_subscriptStack));
|
||||
oxReturnError(m_vec[i].setType(m_type, m_subscriptStack, m_typeSubscriptLevels));
|
||||
}
|
||||
}
|
||||
return {};
|
||||
@ -418,8 +419,9 @@ class ModelValueVector {
|
||||
|
||||
constexpr Error setType(
|
||||
DescriptorType const*type,
|
||||
int subscriptLevels,
|
||||
SubscriptStack subscriptStack) noexcept {
|
||||
SubscriptStack subscriptStack,
|
||||
int subscriptLevels) noexcept {
|
||||
oxAssert(subscriptLevels <= static_cast<int>(subscriptStack.size()), "subscript level mismatch");
|
||||
m_type = type;
|
||||
m_typeSubscriptLevels = subscriptLevels;
|
||||
m_subscriptStack = std::move(subscriptStack);
|
||||
@ -674,11 +676,11 @@ class ModelObject {
|
||||
for (const auto &f : type->fieldList) {
|
||||
auto field = make_unique<Field>();
|
||||
field->name = f.fieldName;
|
||||
oxReturnError(field->value.setType(f.type, f.subscriptLevels, f.subscriptStack));
|
||||
oxReturnError(field->value.setType(f.type, f.subscriptStack, f.subscriptLevels));
|
||||
m_fields[field->name] = &field->value;
|
||||
m_fieldsOrder.emplace_back(std::move(field));
|
||||
}
|
||||
return OxError(0);
|
||||
return {};
|
||||
}
|
||||
|
||||
};
|
||||
@ -797,12 +799,12 @@ class ModelUnion {
|
||||
auto field = make_unique<Field>();
|
||||
field->name = f.fieldName;
|
||||
field->idx = i;
|
||||
oxReturnError(field->value.setType(f.type, f.subscriptLevels));
|
||||
oxReturnError(field->value.setType(f.type, SubscriptStack{static_cast<size_t>(f.subscriptLevels)}, f.subscriptLevels));
|
||||
m_fields[field->name] = field.get();
|
||||
m_fieldsOrder.emplace_back(std::move(field));
|
||||
++i;
|
||||
}
|
||||
return OxError(0);
|
||||
return {};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
@ -1076,20 +1078,21 @@ constexpr ModelValue::Type ModelValue::type() const noexcept {
|
||||
|
||||
constexpr Error ModelValue::setType(
|
||||
const DescriptorType *type,
|
||||
int subscriptLevels,
|
||||
SubscriptStack const&subscriptStack) noexcept {
|
||||
SubscriptStack const&subscriptStack,
|
||||
int subscriptLevels) noexcept {
|
||||
freeResources();
|
||||
oxAssert(subscriptLevels <= static_cast<int>(subscriptStack.size()), "subscript level mismatch");
|
||||
if (subscriptLevels) {
|
||||
auto const&subscript = subscriptStack[subscriptStack.size() - static_cast<size_t>(subscriptLevels)];
|
||||
if (subscript.subscriptType == Subscript::SubscriptType::InlineArray) {
|
||||
m_type = Type::InlineArray;
|
||||
m_data.array = new ModelValueArray;
|
||||
oxReturnError(m_data.array->setType(type, subscriptLevels - 1, subscriptStack));
|
||||
oxReturnError(m_data.array->setType(type, subscriptStack, subscriptLevels - 1));
|
||||
oxReturnError(m_data.array->setSize(static_cast<size_t>(subscript.length)));
|
||||
} else {
|
||||
m_type = Type::Vector;
|
||||
m_data.vec = new ModelValueVector;
|
||||
oxReturnError(m_data.vec->setType(type, subscriptLevels - 1, subscriptStack));
|
||||
oxReturnError(m_data.vec->setType(type, subscriptStack, subscriptLevels - 1));
|
||||
}
|
||||
return {};
|
||||
} else if (type->typeName == types::Bool) {
|
||||
|
4
deps/ox/src/ox/oc/read.hpp
vendored
4
deps/ox/src/ox/oc/read.hpp
vendored
@ -244,7 +244,9 @@ Error OrganicClawReader::field(const char *key, T *val, std::size_t valLen) noex
|
||||
OrganicClawReader r(srcVal);
|
||||
ModelHandlerInterface handler{&r};
|
||||
for (decltype(srcSize) i = 0; i < srcSize; ++i) {
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
oxReturnError(handler.field("", &val[i]));
|
||||
OX_ALLOW_UNSAFE_BUFFERS_END
|
||||
}
|
||||
return OxError(0);
|
||||
}
|
||||
@ -272,7 +274,9 @@ Error readOC(BufferView buff, auto &val) noexcept {
|
||||
Json::Value doc;
|
||||
Json::CharReaderBuilder parserBuilder;
|
||||
auto parser = UniquePtr<Json::CharReader>(parserBuilder.newCharReader());
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
if (!parser->parse(buff.data(), buff.data() + buff.size(), &doc, nullptr)) {
|
||||
OX_ALLOW_UNSAFE_BUFFERS_END
|
||||
return OxError(1, "Could not parse JSON");
|
||||
}
|
||||
OrganicClawReader reader(buff.data(), buff.size());
|
||||
|
2
deps/ox/src/ox/oc/write.hpp
vendored
2
deps/ox/src/ox/oc/write.hpp
vendored
@ -200,7 +200,9 @@ Error OrganicClawWriter::field(const char *key, const T *val, std::size_t len) n
|
||||
OrganicClawWriter w((Json::Value(Json::arrayValue)));
|
||||
ModelHandlerInterface<OrganicClawWriter, OpType::Write> handler{&w};
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
oxReturnError(handler.field({}, &val[i]));
|
||||
OX_ALLOW_UNSAFE_BUFFERS_END
|
||||
}
|
||||
value(key) = w.m_json;
|
||||
}
|
||||
|
6
deps/ox/src/ox/std/CMakeLists.txt
vendored
6
deps/ox/src/ox/std/CMakeLists.txt
vendored
@ -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
|
||||
|
8
deps/ox/src/ox/std/algorithm.hpp
vendored
8
deps/ox/src/ox/std/algorithm.hpp
vendored
@ -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
|
||||
|
11
deps/ox/src/ox/std/array.hpp
vendored
11
deps/ox/src/ox/std/array.hpp
vendored
@ -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
|
||||
|
39
deps/ox/src/ox/std/assert.cpp
vendored
39
deps/ox/src/ox/std/assert.cpp
vendored
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
31
deps/ox/src/ox/std/assert.hpp
vendored
31
deps/ox/src/ox/std/assert.hpp
vendored
@ -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);
|
||||
}
|
||||
|
7
deps/ox/src/ox/std/basestringview.hpp
vendored
7
deps/ox/src/ox/std/basestringview.hpp
vendored
@ -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
|
||||
|
12
deps/ox/src/ox/std/buffer.hpp
vendored
12
deps/ox/src/ox/std/buffer.hpp
vendored
@ -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
|
||||
|
5
deps/ox/src/ox/std/cstrops.hpp
vendored
5
deps/ox/src/ox/std/cstrops.hpp
vendored
@ -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
|
||||
|
19
deps/ox/src/ox/std/def.hpp
vendored
19
deps/ox/src/ox/std/def.hpp
vendored
@ -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
|
||||
*/
|
||||
|
9
deps/ox/src/ox/std/error.hpp
vendored
9
deps/ox/src/ox/std/error.hpp
vendored
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
12
deps/ox/src/ox/std/fmt.hpp
vendored
12
deps/ox/src/ox/std/fmt.hpp
vendored
@ -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
|
||||
|
5
deps/ox/src/ox/std/heapmgr.cpp
vendored
5
deps/ox/src/ox/std/heapmgr.cpp
vendored
@ -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
|
||||
|
5
deps/ox/src/ox/std/istring.hpp
vendored
5
deps/ox/src/ox/std/istring.hpp
vendored
@ -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;
|
||||
|
9
deps/ox/src/ox/std/iterator.hpp
vendored
9
deps/ox/src/ox/std/iterator.hpp
vendored
@ -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
|
||||
|
4
deps/ox/src/ox/std/memops.cpp
vendored
4
deps/ox/src/ox/std/memops.cpp
vendored
@ -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
|
||||
|
5
deps/ox/src/ox/std/memops.hpp
vendored
5
deps/ox/src/ox/std/memops.hpp
vendored
@ -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
|
||||
|
4
deps/ox/src/ox/std/optional.hpp
vendored
4
deps/ox/src/ox/std/optional.hpp
vendored
@ -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"
|
||||
|
||||
|
5
deps/ox/src/ox/std/random.hpp
vendored
5
deps/ox/src/ox/std/random.hpp
vendored
@ -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
|
||||
|
157
deps/ox/src/ox/std/span.hpp
vendored
157
deps/ox/src/ox/std/span.hpp
vendored
@ -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
|
||||
|
5
deps/ox/src/ox/std/stacktrace.cpp
vendored
5
deps/ox/src/ox/std/stacktrace.cpp
vendored
@ -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
|
||||
|
9
deps/ox/src/ox/std/string.hpp
vendored
9
deps/ox/src/ox/std/string.hpp
vendored
@ -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
|
||||
|
3
deps/ox/src/ox/std/stringview.hpp
vendored
3
deps/ox/src/ox/std/stringview.hpp
vendored
@ -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
|
||||
|
3
deps/ox/src/ox/std/strops.cpp
vendored
3
deps/ox/src/ox/std/strops.cpp
vendored
@ -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([] {
|
||||
|
9
deps/ox/src/ox/std/strops.hpp
vendored
9
deps/ox/src/ox/std/strops.hpp
vendored
@ -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
|
||||
|
6
deps/ox/src/ox/std/test/tests.cpp
vendored
6
deps/ox/src/ox/std/test/tests.cpp
vendored
@ -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()) {
|
||||
|
24
deps/ox/src/ox/std/trace.cpp
vendored
24
deps/ox/src/ox/std/trace.cpp
vendored
@ -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;
|
||||
}
|
||||
|
6
deps/ox/src/ox/std/trace.hpp
vendored
6
deps/ox/src/ox/std/trace.hpp
vendored
@ -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());
|
||||
|
35
deps/ox/src/ox/std/typetraits.hpp
vendored
35
deps/ox/src/ox/std/typetraits.hpp
vendored
@ -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>
|
||||
|
11
deps/ox/src/ox/std/uuid.hpp
vendored
11
deps/ox/src/ox/std/uuid.hpp
vendored
@ -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
|
||||
|
2
deps/ox/src/ox/std/vec.cpp
vendored
2
deps/ox/src/ox/std/vec.cpp
vendored
@ -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;
|
||||
}());
|
||||
|
||||
}
|
||||
|
196
deps/ox/src/ox/std/vec.hpp
vendored
196
deps/ox/src/ox/std/vec.hpp
vendored
@ -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>
|
||||
|
6
deps/ox/src/ox/std/vector.hpp
vendored
6
deps/ox/src/ox/std/vector.hpp
vendored
@ -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
|
||||
|
Reference in New Issue
Block a user