Compare commits

...

128 Commits

Author SHA1 Message Date
e30ebce4c0 [nostalgia] Add pyenv to .gitignore
All checks were successful
Build / build (push) Successful in 2m34s
2024-05-02 23:15:01 -05:00
7163947efd [ox/std] Cleanup 2024-05-02 23:14:03 -05:00
0a0a6e306d [studio] Move UndoCommand implementation to its own file 2024-05-02 22:50:25 -05:00
97bc9332d3 [nostalgia/core] Fix TileSheetV1 to use PaletteV1 2024-05-02 22:48:35 -05:00
9caf7099b6 [keel] Fix for Ox change 2024-05-02 22:21:04 -05:00
fda1280d29 [ox/std] Make substr always take and return a StringView 2024-05-02 22:20:25 -05:00
59aa4ad21a [cityhash] Cleanup 2024-05-02 22:20:01 -05:00
1a8afa1a98 [nostalgia/sample_project] Add missing type descriptor 2024-05-02 22:11:52 -05:00
cdbc2d6cc8 [olympic/studio] Move UndoCommand to its own file 2024-05-02 22:09:35 -05:00
acd93337d4 [ox/std] Fix Integer assignment operator return
All checks were successful
Build / build (push) Successful in 2m27s
2024-04-29 22:54:34 -05:00
cebd3b0a0f [ox/std] Fix Integer assignment operator return 2024-04-29 22:52:34 -05:00
43e2e2155b [ox/std] Cleanup 2024-04-29 22:48:22 -05:00
be1f90955b [ox/std] Make safeDelete constexpr
All checks were successful
Build / build (push) Successful in 2m32s
2024-04-29 22:43:27 -05:00
0f2c18d554 [ox/std] Add std::string(_view) variant of MaybeView
All checks were successful
Build / build (push) Successful in 2m29s
2024-04-25 23:03:38 -05:00
0c0ccd1a69 [nostalgia/core/studio] Cleanup scratchpad code
All checks were successful
Build / build (push) Successful in 2m32s
2024-04-24 23:09:50 -05:00
1b629da8fc [ox/std] Make Vector::contains always noexcept
All checks were successful
Build / build (push) Successful in 2m29s
2024-04-24 21:39:02 -05:00
32e4702dc7 [ox] Improve hasing and MaybeView
All checks were successful
Build / build (push) Successful in 2m29s
* Add CityHash dep
* Use CityHash for HashMap
* Make MaybeView more versatile
* Cleanup some inappropriate MaybeView uses
2024-04-24 20:59:37 -05:00
6b47133c22 [nostalgia] Cleanup StudioModules
All checks were successful
Build / build (push) Successful in 2m22s
2024-04-24 00:58:10 -05:00
0764720f9a [nostalgia,olympic] Update for Ox changes 2024-04-24 00:54:43 -05:00
78955376d6 [glutils] Update for Ox changes 2024-04-24 00:54:25 -05:00
a00a0bd2ff [ox] Rename BString to IString 2024-04-24 00:54:02 -05:00
ed4f0e1f2b [nostalgia,olympic] Replace oxIgnoreError with std::ignore 2024-04-22 23:43:22 -05:00
ea1feb726e [ox] Remove oxIgnoreError 2024-04-22 23:40:42 -05:00
e9a6a09629 [ox] Run liccor
All checks were successful
Build / build (push) Successful in 2m20s
2024-04-21 17:01:48 -05:00
d7f309750e Merge commit 'c0baf7efca0e4c3a86a018ad2564d9df7b07c133'
All checks were successful
Build / build (push) Successful in 2m22s
2024-04-21 13:13:26 -05:00
84205879d4 [olympic] Cleanup ItemMaker, remove unnecessary copy
All checks were successful
Build / build (push) Successful in 2m22s
2024-04-21 10:32:42 -05:00
ebf3a6961e [ox/std] Add String constructor that takes a StringLiteral 2024-04-21 10:31:26 -05:00
eeb2a5a151 [olympic/studio] Add new ImGui util functions 2024-04-21 10:24:53 -05:00
453f2750dd [nostalgia/core/studio] Cleanup context types 2024-04-21 10:24:29 -05:00
189ba4c545 [olympic/studio] Make studio::run static 2024-04-21 10:23:55 -05:00
057738088e [olympic] Change TypeId building to use constexpr globals 2024-04-21 10:23:22 -05:00
272eabc732 [nostalgia/core/opengl] Unbind vertex arrays when done with them 2024-04-21 10:22:32 -05:00
a02566697a [glutils] Remove trailing whitespace 2024-04-21 10:21:44 -05:00
dfd27afd67 [ox/std] Add implicit String constructor for str literals
All checks were successful
Build / build (push) Successful in 2m20s
Also make String more constexpr friendly
2024-04-18 23:59:47 -05:00
6bfe184261 [ox/std] Remove unnecessary copying from HashMap::expand
All checks were successful
Build / build (push) Successful in 2m21s
2024-04-18 23:39:33 -05:00
700d7016d5 [nostalgia] Update for Ox changes 2024-04-18 23:33:06 -05:00
922323833c [ox] Cleanup 2024-04-18 23:32:54 -05:00
3b8d13dce3 [nostalgia,olympic] Fixes for Ox update
All checks were successful
Build / build (push) Successful in 2m25s
2024-04-18 19:25:07 -05:00
a20d7fd923 [ox] Cleanup 2024-04-18 19:24:56 -05:00
6808adc8a1 [ox/std] Replace ox::ignore with std::ignore 2024-04-13 00:35:49 -05:00
abc076d657 [ox/std] Cleanup 2024-04-13 00:10:09 -05:00
1b790a34c4 [ox/std] Fix Signed_c and Unsigned_c 2024-04-13 00:07:40 -05:00
9220271630 [nostalgia/core] Update pack transforms to use ModelTypeId_v 2024-04-10 22:20:26 -05:00
7941a514ba [ox/model] Add constexpr ModelTypeId_v 2024-04-10 00:00:48 -05:00
0c09c5306e [ox/std] Fix sfmt constexpr problems 2024-04-09 23:47:18 -05:00
3ff91af86b [ox/std] Sort of fix custom assert 2024-04-09 23:46:54 -05:00
79b42e1df7 [ox/std] Fix some Vector constexpr problems 2024-04-09 23:46:12 -05:00
5eec9085f8 [ox/std] Add nodiscard to some string functions 2024-04-09 22:40:37 -05:00
af7c89564c [ox/std] Add ox::ignore 2024-04-09 22:40:20 -05:00
2c0e02277c [ox/std] Add assert to AnyPtr::Wrap::copyTo to ensure sufficiently large buff
All checks were successful
Build / build (push) Successful in 2m39s
2024-03-24 02:22:37 -05:00
e3c74637db [turbine] Make applicationData return const&
All checks were successful
Build / build (push) Successful in 2m35s
2024-03-23 17:19:33 -05:00
41e08d67aa [turbine] Make keyEventHandler nodiscard 2024-03-23 17:12:44 -05:00
50f3479d10 [ox/std] Make AnyPtr constexpr
All checks were successful
Build / build (push) Successful in 2m38s
2024-03-23 17:05:20 -05:00
1616ca7018 [turbine] Replace WrapPtr with ox::AnyPtr
All checks were successful
Build / build (push) Successful in 2m33s
2024-03-23 16:53:04 -05:00
3fa247e3d4 [ox/std] Add AnyPtr 2024-03-23 16:52:43 -05:00
27f1df8f33 [nostalgia,olympic] Further reduce use of applicationData 2024-03-23 16:07:49 -05:00
a4f0c7cdb5 [nostalgia/core/studio] Remove applicationData usages
All checks were successful
Build / build (push) Successful in 2m35s
2024-03-23 14:52:30 -05:00
6a52319156 [turbine] Cleanup applicationData
All checks were successful
Build / build (push) Successful in 2m38s
2024-03-17 20:59:14 -05:00
205f2a698c [turbine] Fix applicationData to properly return null 2024-03-17 20:05:01 -05:00
82f02896c9 [turbine] Cleanup type safety code for application data
All checks were successful
Build / build (push) Successful in 2m35s
2024-03-17 14:33:14 -05:00
aa43cb3d8d [turbine] Add some type safety to application data
All checks were successful
Build / build (push) Successful in 2m34s
2024-03-16 23:10:44 -05:00
05d08a7687 Merge commit 'd6403991d49292d4f2b7d441636949472ca2b249'
All checks were successful
Build / build (push) Successful in 2m22s
2024-03-14 23:33:20 -05:00
c6750d50fc [studio/modlib] Add ig::ChildStackItem 2024-03-14 23:32:05 -05:00
dade484d87 [olympic/studio] Make StudioContext::ui a ref instead of ptr 2024-03-14 23:31:01 -05:00
04f3d6b491 [keel] Fix some static const vars to be constexpr
All checks were successful
Build / build (push) Successful in 2m23s
2024-02-29 23:53:36 -06:00
b015fe88b7 [ox/std] Make ranges predicates const refs 2024-02-17 11:43:25 -06:00
db2dc28f92 [keel] Remove use of removed ModelValue operator
All checks were successful
Build / build (push) Successful in 2m24s
2024-02-11 20:35:48 -06:00
74fb051ef2 [ox] Remove panicing ModelValue operators 2024-02-11 20:35:19 -06:00
24fda7d589 [ox] Make serialize and allocate Writer_c functions take refs
All checks were successful
Build / build (push) Successful in 2m18s
2024-02-11 19:39:29 -06:00
a60cdf0a61 Merge commit '9c712cc38ae706b021807b271899bce56c234fa5' 2024-02-11 17:30:45 -06:00
b97d7d9956 [ox/preloader] Remove debug code
Some checks are pending
Build / build (push) Waiting to run
2024-02-11 17:29:54 -06:00
ce1eea817d [olympic/keel] Remove debug line 2024-02-11 17:28:19 -06:00
9a0a2fd46a Merge commit '56f9d7a4634c9de9b09df390c4385c67ab646607' 2024-02-11 17:24:22 -06:00
4e50889b5c [ox/model,ox/preloader] Add ability to handle inline arrays
Some checks are pending
Build / build (push) Waiting to run
2024-02-11 17:23:38 -06:00
9c0acf1b8f Merge commit 'ace68f7c1d870ed53e69c55ba53709a9425388be' 2024-02-04 10:21:12 -06:00
ee05118478 [ox] Add ability for ModelValue to represent inline arrays, add to preloader
Some checks failed
Build / build (push) Failing after 17s
2024-02-04 10:19:30 -06:00
a41e93c582 Merge commit '8e0467ca5fdb3f983738a97c17cba742a0d233fd' 2024-02-01 21:07:56 -06:00
59fa39070f [keel] Update pack for Preloader changes
All checks were successful
Build / build (push) Successful in 2m19s
2024-02-01 21:07:42 -06:00
c55994f67d [ox/std] Add Vector::capacity 2024-02-01 21:06:53 -06:00
e81d28a681 [ox] Fix various preloader problems 2024-02-01 21:06:35 -06:00
0626c2a815 [ox/fs] Add comparison operator for FileAddress 2024-02-01 21:02:46 -06:00
dbcd37d7ea Merge commit '0d61e5a064382a7076b62d32b25c70298ee0706e' 2024-01-31 23:18:13 -06:00
10a12f2ab2 [nostalgia/core] Add getTileCnt to header
All checks were successful
Build / build (push) Successful in 2m23s
2024-01-31 23:17:59 -06:00
2667be88f6 [nostalgia/core] Add largestPage function for Palette 2024-01-31 23:17:46 -06:00
5972d8acef [nostalgia/core] Fix TileSetEntry model 2024-01-31 23:17:28 -06:00
9c026e1a6c [nostalgia/core/studio] Add function to remove unused data from TileSheets 2024-01-31 23:17:09 -06:00
1dff26d895 [nostalgia/core] Add getTileCnt and fix getTileIdx 2024-01-31 23:16:41 -06:00
ff2eb5b11b [olympic/keel] Remove const r-value funcion from AssetRef 2024-01-31 23:15:53 -06:00
6a500345b4 Merge commit '057272347486efe5046691f32f51604e3a594e6a' 2024-01-31 23:13:34 -06:00
28b1c6dcf4 [ox/preloader] Fix case where alignOf always used NativePlatSpec
All checks were successful
Build / build (push) Successful in 2m21s
2024-01-31 23:07:40 -06:00
ef9cb8bea4 [olympic/modlib] Add ListBox to ImGui util 2024-01-30 21:46:38 -06:00
0d106bde21 [ox/oc] Fix objects to always write when members of arrays 2024-01-30 21:45:58 -06:00
f038b89ab4 Merge commit 'cfc27a384b00388fc1ce30ac47c266ddd1f8e6f1' 2024-01-28 18:05:09 -06:00
b75bbc4d20 [olympic,nostalgia] Change order of oxModelFieldRename args
All checks were successful
Build / build (push) Successful in 2m22s
2024-01-28 18:03:50 -06:00
227dd68a4f [ox/model] Change order of oxModelFieldRename args 2024-01-28 18:03:50 -06:00
02db760b8c [olympic] Add more ImGui helpers, studio::Editor::pushCommand 2024-01-28 18:03:12 -06:00
09c57545bc [ox/std] Add Vector::at
All checks were successful
Build / build (push) Successful in 2m22s
2024-01-28 16:29:39 -06:00
b9fddd47c2 Merge commit 'db978290f3465d2da30a27a98b12face50bbe091' 2024-01-27 23:55:20 -06:00
f128664a81 [olympic/studio] Add ig::IndentStackItem
All checks were successful
Build / build (push) Successful in 2m28s
2024-01-27 23:54:57 -06:00
e84df7801e [glutils] Add ProgramSource::vboLen 2024-01-27 23:53:32 -06:00
caa59f3724 [nostalgia/core] Add functions for mapping tile idx to subsheet 2024-01-27 23:52:40 -06:00
1cf09433e8 [nostalgia/core/studio] Cleanup TileSheetEditor with new GlUtils helpers 2024-01-27 23:51:51 -06:00
9948346ce4 [ox/model] Fix clangd false alarm 2024-01-27 23:40:16 -06:00
aa8200beed [glutils] Add helper functions for setting up shaders 2024-01-27 23:39:03 -06:00
961ab75662 Merge commit 'ae1f8ce11a81624f376be3a3dd56e80ba479dd89' 2024-01-20 15:41:04 -06:00
124c7029bd [olympic/studio] Change Studio modules to pass StudioContext instead of turbine::Context
All checks were successful
Build / build (push) Successful in 2m23s
2024-01-20 15:40:08 -06:00
d740609c8e Merge commit '6640e00ad9ee5b731a2ddb06da31436463c3ae65' 2024-01-20 15:02:16 -06:00
5d1f680a51 [nostalgia/core] Cleanup TileSheetEditor with new ImGui util functions
All checks were successful
Build / build (push) Successful in 2m21s
2024-01-20 14:59:43 -06:00
08be822bdd [ox/fs] Add FileAddress::operator==(FileAddress) 2024-01-19 20:22:52 -06:00
c2e34b6456 Merge commit 'a9128caf4ddd187f14496b84242dfe07ee9a6467'
All checks were successful
Build / build (push) Successful in 2m32s
2024-01-19 01:09:23 -06:00
173d3f4bc7 [olympic/studio] Add PushButton, PopupBtns, ComboBox, and IDStackItem to ImGui utils 2024-01-19 01:09:10 -06:00
8a29c0952c [olympic/studio] Fix imguiutil.hpp name, add StudioContext::tctx 2024-01-19 00:15:28 -06:00
5848bc8eb7 [nostalgia/core/studio] Change Subsheet Editor button position
All checks were successful
Build / build (push) Successful in 2m21s
2024-01-18 22:09:09 -06:00
7ba66787f8 [nostalgia/core/studio] Cleanup
All checks were successful
Build / build (push) Successful in 2m29s
2024-01-18 01:27:31 -06:00
e367575974 [olympic/studio] Fix NewMenu not to overwrite existing files or create a file without name
All checks were successful
Build / build (push) Successful in 2m30s
2024-01-18 00:24:11 -06:00
2bc2003caa [nostalgia/core/studio] Add key shortcuts for switching Palette pages
All checks were successful
Build / build (push) Successful in 2m22s
2024-01-17 22:48:53 -06:00
b31062e609 [nostalgia] Update liccor file 2024-01-17 22:36:09 -06:00
e4285bd48b [nostalgia/studio] Tweak background color of TileSheet editor
All checks were successful
Build / build (push) Successful in 2m20s
2024-01-17 22:23:22 -06:00
a76638cc86 [olympic/studio] Make Project::romFS return a reference 2024-01-17 22:08:22 -06:00
5433fd9b1d [nostalgia/core] Add new version of Palette with pages
All checks were successful
Build / build (push) Successful in 2m35s
2024-01-17 01:30:29 -06:00
b46cb65b7f [nostalgia/studio] Add version
All checks were successful
Build / build (push) Successful in 2m24s
2024-01-05 21:54:22 -06:00
877349df46 [nostalgia/core/studio] Increase max tilesheet export size, fix input handling when popups open 2024-01-04 22:47:57 -06:00
5418c06296 [olympic] Change olympic::s_version to olympic::appVersion
All checks were successful
Build / build (push) Successful in 2m17s
2024-01-01 14:14:16 -06:00
dd9c1100c3 [glutils] Update copyright for 2024
All checks were successful
Build / build (push) Successful in 2m16s
2024-01-01 12:06:57 -06:00
db82aee7c7 [teagba] Update copyright for 2024 2024-01-01 12:06:57 -06:00
edf15858ca [teagba] Update copyright for 2024
All checks were successful
Build / build (push) Successful in 2m19s
2024-01-01 12:04:09 -06:00
d1efbb2ffa [ox] Update copyright for 2024 2024-01-01 12:03:16 -06:00
051623f4b5 [olympic,nostalgia] Update copyright for 2024 2024-01-01 12:02:40 -06:00
352 changed files with 4399 additions and 1964 deletions

View File

@ -57,6 +57,7 @@ misc-*,
readability-duplicate-include,
-misc-non-private-member-variables-in-classes,
-misc-no-recursion,
-misc-include-cleaner,
bugprone-*,
clang-analyzer-*,
modernize-*,

1
.gitignore vendored
View File

@ -7,6 +7,7 @@
.stfolder
.stignore
scripts/__pycache__
pyenv
CMakeLists.txt.user
ROM.oxfs
Session.vim

View File

@ -2,4 +2,4 @@
source:
- src
copyright_notice: |-
Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
Copyright 2016 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved.

6
deps/glutils/.liccor.yml vendored Normal file
View File

@ -0,0 +1,6 @@
---
source:
- include
- src
copyright_notice: |-
Copyright 2016 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
* Copyright 2016 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/
#pragma once
@ -150,8 +150,39 @@ class FrameBufferBind {
void bind(const FrameBuffer &fb) noexcept;
struct ShaderVarSet {
GLsizei len{};
ox::String name;
};
ox::Result<GLProgram> buildShaderProgram(ox::CStringView const&vert, ox::CStringView const&frag, ox::CStringView const&geo = "") noexcept;
struct ProgramSource {
ox::Vector<glutils::ShaderVarSet> const shaderParams;
GLsizei const rowLen = [this] {
GLsizei len{};
for (auto const&v : shaderParams) {
len += v.len;
}
return len;
}();
GLsizei const vboLen = rowLen * 4;
ox::String const vertShader{};
ox::String const fragShader{};
ox::String const geomShader{};
};
ox::Result<GLProgram> buildShaderProgram(ProgramSource const&src) noexcept;
ox::Result<GLProgram> buildShaderProgram(
ox::CStringView const&vert,
ox::CStringView const&frag,
ox::CStringView const&geo = "") noexcept;
void setupShaderParams(
GLProgram const&shader,
ox::Vector<ShaderVarSet> const&vars,
GLsizei vertexRowLen) noexcept;
void setupShaderParams(GLProgram const&shader, ox::Vector<ShaderVarSet> const&vars) noexcept;
glutils::GLVertexArray generateVertexArrayObject() noexcept;
@ -160,6 +191,8 @@ glutils::GLBuffer generateBuffer() noexcept;
[[nodiscard]]
FrameBuffer generateFrameBuffer(int width, int height) noexcept;
void resizeFrameBuffer(FrameBuffer &fb, int width, int height) noexcept;
/**
* Resizes a FrameBuffer, and creates if it does not already exist.
*/
@ -177,7 +210,7 @@ struct BufferSet {
};
void sendVbo(BufferSet const&bs) noexcept;
void sendEbo(BufferSet const&bs) noexcept;
void clearScreen() noexcept;

View File

@ -1,9 +1,9 @@
/*
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
* Copyright 2016 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/
#include <ox/std/assert.hpp>
#include <ox/std/bstring.hpp>
#include <ox/std/istring.hpp>
#include <ox/std/trace.hpp>
#include "glutils/glutils.hpp"
@ -88,6 +88,40 @@ static ox::Result<GLShader> buildShader(
return shader;
}
ox::Result<GLProgram> buildShaderProgram(ProgramSource const&src) noexcept {
oxRequireM(program, buildShaderProgram(
src.vertShader,
src.fragShader,
src.geomShader));
setupShaderParams(program, src.shaderParams, src.rowLen);
return std::move(program);
}
void setupShaderParams(
GLProgram const&shader,
ox::Vector<ShaderVarSet> const&vars,
GLsizei vertexRowLen) noexcept {
// setup vars
for (auto lenWritten = 0LU; auto const&v : vars) {
auto const attr = static_cast<GLuint>(glGetAttribLocation(shader, v.name.c_str()));
glEnableVertexAttribArray(attr);
glVertexAttribPointer(
attr, v.len, GL_FLOAT, GL_FALSE,
vertexRowLen * static_cast<GLsizei>(sizeof(float)),
std::bit_cast<void*>(uintptr_t{lenWritten * sizeof(float)}));
lenWritten += static_cast<size_t>(v.len);
}
}
void setupShaderParams(GLProgram const&shader, ox::Vector<ShaderVarSet> const&vars) noexcept {
// get row len
GLsizei vertexRowLen{};
for (auto const&v : vars) {
vertexRowLen += v.len;
}
setupShaderParams(shader, vars, vertexRowLen);
}
ox::Result<GLProgram> buildShaderProgram(
ox::CStringView const&vert,
ox::CStringView const&frag,
@ -147,11 +181,7 @@ FrameBuffer generateFrameBuffer(int width, int height) noexcept {
return fb;
}
void resizeInitFrameBuffer(FrameBuffer &fb, int width, int height) noexcept {
if (!fb) {
fb = generateFrameBuffer(width, height);
return;
}
void resizeFrameBuffer(FrameBuffer &fb, int width, int height) noexcept {
width = ox::max(1, width);
height = ox::max(1, height);
fb.width = width;
@ -171,6 +201,14 @@ void resizeInitFrameBuffer(FrameBuffer &fb, int width, int height) noexcept {
glBindRenderbuffer(GL_RENDERBUFFER, 0);
}
void resizeInitFrameBuffer(FrameBuffer &fb, int width, int height) noexcept {
if (!fb) {
fb = generateFrameBuffer(width, height);
return;
}
resizeFrameBuffer(fb, width, height);
}
void resizeInitFrameBuffer(FrameBuffer &fb, ox::Size const&sz) noexcept {
resizeInitFrameBuffer(fb, sz.width, sz.height);
}

2
deps/ox/.liccor.yml vendored
View File

@ -2,7 +2,7 @@
source:
- src
copyright_notice: |-
Copyright 2015 - 2022 gary@drinkingtea.net
Copyright 2015 - 2024 gary@drinkingtea.net
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -82,4 +82,5 @@ if(OX_USE_STDLIB)
set(JSONCPP_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/deps/jsoncpp/include")
add_subdirectory(deps/jsoncpp)
endif()
add_subdirectory(deps/cityhash)
add_subdirectory(src)

30
deps/ox/deps/cityhash/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,30 @@
cmake_minimum_required(VERSION 3.19)
set(CMAKE_POLICY_DEFAULT_CMP0110 NEW) # requires CMake 3.19
project(CityHash CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(NOSTALGIA_BUILD_PLAYER OFF)
set(NOSTALGIA_BUILD_STUDIO_APP OFF)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
if(APPLE)
set(CMAKE_MACOSX_RPATH OFF)
else()
if(UNIX)
set(BUILD_SHARED_LIBS ON)
endif()
set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib")
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
endif()
add_library(CityHash INTERFACE)
target_include_directories(CityHash INTERFACE include)

View File

@ -0,0 +1,674 @@
// Copyright (c) 2011 Google, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// CityHash, by Geoff Pike and Jyrki Alakuijala
//
// http://code.google.com/p/cityhash/
//
// This file provides a few functions for hashing strings. All of them are
// high-quality functions in the sense that they pass standard tests such
// as Austin Appleby's SMHasher. They are also fast.
//
// For 64-bit x86 code, on short strings, we don't know of anything faster than
// CityHash64 that is of comparable quality. We believe our nearest competitor
// is Murmur3. For 64-bit x86 code, CityHash64 is an excellent choice for hash
// tables and most other hashing (excluding cryptography).
//
// For 64-bit x86 code, on long strings, the picture is more complicated.
// On many recent Intel CPUs, such as Nehalem, Westmere, Sandy Bridge, etc.,
// CityHashCrc128 appears to be faster than all competitors of comparable
// quality. CityHash128 is also good but not quite as fast. We believe our
// nearest competitor is Bob Jenkins' Spooky. We don't have great data for
// other 64-bit CPUs, but for long strings we know that Spooky is slightly
// faster than CityHash on some relatively recent AMD x86-64 CPUs, for example.
// Note that CityHashCrc128 is declared in citycrc.h.
//
// For 32-bit x86 code, we don't know of anything faster than CityHash32 that
// is of comparable quality. We believe our nearest competitor is Murmur3A.
// (On 64-bit CPUs, it is typically faster to use the other CityHash variants.)
//
// Functions in the CityHash family are not suitable for cryptography.
//
// Please see CityHash's README file for more details on our performance
// measurements and so on.
//
// WARNING: This code has been only lightly tested on big-endian platforms!
// It is known to work well on little-endian platforms that have a small penalty
// for unaligned reads, such as current Intel and AMD moderate-to-high-end CPUs.
// It should work on all 32-bit and 64-bit platforms that allow unaligned reads;
// bug reports are welcome.
//
// By the way, for some hash functions, given strings a and b, the hash
// of a+b is easily derived from the hashes of a and b. This property
// doesn't hold for any hash functions in this file.
#ifndef CITY_HASH_H_
#define CITY_HASH_H_
#if __has_include(<cstdint>)
#include <cstdint>
#else
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned int uint32_t;
typedef unsigned uint_t;
#if defined(__arm__) || defined(__ppc__)
typedef long long int64_t;
typedef unsigned long long uint64_t;
typedef __INTMAX_TYPE__ intmax_t;
typedef __UINTMAX_TYPE__ uintmax_t;
#else
typedef long int64_t;
typedef unsigned long uint64_t;
typedef int64_t intmax_t;
typedef uint64_t uintmax_t;
#endif
#if defined(_LP64) || defined(__ppc64__) || defined(__aarch64__)
typedef long intptr_t;
typedef unsigned long uintptr_t;
#elif defined(_WIN64)
typedef int64_t intptr_t;
typedef uint64_t uintptr_t;
#elif defined(_LP32) || defined(__ppc__) || defined(_WIN32) || defined(__arm__)
typedef int32_t intptr_t;
typedef uint32_t uintptr_t;
#else
#error intptr_t, and uintptr_t undefined
#endif
using size_t = decltype(alignof(int));
#endif
namespace cityhash::detail {
template<typename T>
struct remove_reference {
using type = T;
};
template<typename T>
struct remove_reference<T&> {
using type = T;
};
template<typename T>
struct remove_reference<T&&> {
using type = T;
};
template<typename T>
using remove_reference_t = typename remove_reference<T>::type;
template<typename T>
constexpr remove_reference_t<T> &&move(T &&t) noexcept {
return static_cast<remove_reference_t<T>&&>(t);
}
template<typename T>
using remove_reference_t = typename remove_reference<T>::type;
template<typename T1, typename T2>
struct pair {
T1 first{};
T2 second{};
constexpr pair() noexcept = default;
constexpr pair(T1 a, T2 b) noexcept: first(detail::move(a)), second(detail::move(b)) {}
};
template<typename T>
constexpr void swap(T &a, T &b) noexcept {
auto temp = detail::move(a);
a = detail::move(b);
b = detail::move(temp);
}
}
namespace cityhash {
using uint128 = cityhash::detail::pair<uint64_t, uint64_t>;
namespace detail {
template<typename T>
[[nodiscard]]
constexpr T byteSwap(T i) noexcept {
if constexpr(sizeof(T) == 1) {
return i;
} else if constexpr(sizeof(T) == 2) {
return static_cast<T>(i << 8) | static_cast<T>(i >> 8);
} else if constexpr(sizeof(T) == 4) {
return ((i >> 24) & 0x000000ff) |
((i >> 8) & 0x0000ff00) |
((i << 8) & 0x00ff0000) |
((i << 24) & 0xff000000);
} else if constexpr(sizeof(T) == 8) {
return ((i >> 56) & 0x00000000000000ff) |
((i >> 40) & 0x000000000000ff00) |
((i >> 24) & 0x0000000000ff0000) |
((i >> 8) & 0x00000000ff000000) |
((i << 8) & 0x000000ff00000000) |
((i << 24) & 0x0000ff0000000000) |
((i << 40) & 0x00ff000000000000) |
((i << 56) & 0xff00000000000000);
}
}
[[nodiscard]]
constexpr uint64_t Uint128Low64(const uint128& x) noexcept { return x.first; }
[[nodiscard]]
constexpr uint64_t Uint128High64(const uint128& x) noexcept { return x.second; }
// Hash 128 input bits down to 64 bits of output.
// This is intended to be a reasonably good hash function.
[[nodiscard]]
constexpr uint64_t Hash128to64(const uint128& x) noexcept {
// Murmur-inspired hashing.
const uint64_t kMul = 0x9ddfea08eb382d69ULL;
uint64_t a = (detail::Uint128Low64(x) ^ detail::Uint128High64(x)) * kMul;
a ^= (a >> 47);
uint64_t b = (detail::Uint128High64(x) ^ a) * kMul;
b ^= (b >> 47);
b *= kMul;
return b;
}
[[nodiscard]]
constexpr uint64_t UNALIGNED_LOAD64(const char *p) noexcept {
uint64_t result{};
result |= static_cast<uint64_t>(p[0]);
result |= static_cast<uint64_t>(p[1]) << 8;
result |= static_cast<uint64_t>(p[2]) << 16;
result |= static_cast<uint64_t>(p[3]) << 24;
result |= static_cast<uint64_t>(p[4]) << 32;
result |= static_cast<uint64_t>(p[5]) << 40;
result |= static_cast<uint64_t>(p[6]) << 48;
result |= static_cast<uint64_t>(p[7]) << 56;
//memcpy(&result, p, sizeof(result));
return result;
}
[[nodiscard]]
constexpr uint32_t UNALIGNED_LOAD32(const char *p) noexcept {
uint32_t result{};
result |= static_cast<uint32_t>(p[0]);
result |= static_cast<uint32_t>(p[1]) << 8;
result |= static_cast<uint32_t>(p[2]) << 16;
result |= static_cast<uint32_t>(p[3]) << 24;
//memcpy(&result, p, sizeof(result));
return result;
}
#ifdef WORDS_BIGENDIAN
#define uint32_in_expected_order(x) (detail::byteSwap<uint32_t>(x))
#define uint64_in_expected_order(x) (detail::byteSwap<uint64_t>(x))
#else
#define uint32_in_expected_order(x) (x)
#define uint64_in_expected_order(x) (x)
#endif
#if !defined(LIKELY)
#if HAVE_BUILTIN_EXPECT
#define LIKELY(x) (__builtin_expect(!!(x), 1))
#else
#define LIKELY(x) (x)
#endif
#endif
[[nodiscard]]
constexpr uint64_t Fetch64(const char *p) noexcept {
return uint64_in_expected_order(UNALIGNED_LOAD64(p));
}
[[nodiscard]]
constexpr uint32_t Fetch32(const char *p) noexcept {
return uint32_in_expected_order(UNALIGNED_LOAD32(p));
}
// Some primes between 2^63 and 2^64 for various uses.
constexpr uint64_t k0 = 0xc3a5c85c97cb3127ULL;
constexpr uint64_t k1 = 0xb492b66fbe98f273ULL;
constexpr uint64_t k2 = 0x9ae16a3b2f90404fULL;
// Magic numbers for 32-bit hashing. Copied from Murmur3.
constexpr uint32_t c1 = 0xcc9e2d51;
constexpr uint32_t c2 = 0x1b873593;
// A 32-bit to 32-bit integer hash copied from Murmur3.
[[nodiscard]]
constexpr uint32_t fmix(uint32_t h) noexcept {
h ^= h >> 16;
h *= 0x85ebca6b;
h ^= h >> 13;
h *= 0xc2b2ae35;
h ^= h >> 16;
return h;
}
[[nodiscard]]
constexpr uint32_t Rotate32(uint32_t val, int shift) noexcept {
// Avoid shifting by 32: doing so yields an undefined result.
return shift == 0 ? val : ((val >> shift) | (val << (32 - shift)));
}
#undef PERMUTE3
#define PERMUTE3(a, b, c) do { detail::swap(a, b); detail::swap(a, c); } while (0)
[[nodiscard]]
constexpr uint32_t Mur(uint32_t a, uint32_t h) noexcept {
// Helper from Murmur3 for combining two 32-bit values.
a *= detail::c1;
a = Rotate32(a, 17);
a *= detail::c2;
h ^= a;
h = Rotate32(h, 19);
return h * 5 + 0xe6546b64;
}
[[nodiscard]]
constexpr uint32_t Hash32Len13to24(const char *s, size_t len) noexcept {
uint32_t a = Fetch32(s - 4 + (len >> 1));
uint32_t b = Fetch32(s + 4);
uint32_t c = Fetch32(s + len - 8);
uint32_t d = Fetch32(s + (len >> 1));
uint32_t e = Fetch32(s);
uint32_t f = Fetch32(s + len - 4);
uint32_t h = static_cast<uint32_t>(len);
return detail::fmix(Mur(f, Mur(e, Mur(d, Mur(c, Mur(b, Mur(a, h)))))));
}
[[nodiscard]]
constexpr uint32_t Hash32Len0to4(const char *s, size_t len) noexcept {
uint32_t b = 0;
uint32_t c = 9;
for (size_t i = 0; i < len; i++) {
auto const v = static_cast<signed char>(s[i]);
b = b * detail::c1 + static_cast<uint32_t>(v);
c ^= b;
}
return detail::fmix(Mur(b, Mur(static_cast<uint32_t>(len), c)));
}
[[nodiscard]]
constexpr uint32_t Hash32Len5to12(const char *s, size_t len) noexcept {
uint32_t a = static_cast<uint32_t>(len), b = a * 5, c = 9, d = b;
a += Fetch32(s);
b += Fetch32(s + len - 4);
c += Fetch32(s + ((len >> 1) & 4));
return detail::fmix(Mur(c, Mur(b, Mur(a, d))));
}
// Bitwise right rotate. Normally this will compile to a single
// instruction, especially if the shift is a manifest constant.
[[nodiscard]]
constexpr uint64_t Rotate(uint64_t val, int shift) noexcept {
// Avoid shifting by 64: doing so yields an undefined result.
return shift == 0 ? val : ((val >> shift) | (val << (64 - shift)));
}
[[nodiscard]]
constexpr uint64_t ShiftMix(uint64_t val) noexcept {
return val ^ (val >> 47);
}
[[nodiscard]]
constexpr uint64_t HashLen16(uint64_t u, uint64_t v) noexcept {
return Hash128to64(uint128(u, v));
}
[[nodiscard]]
constexpr uint64_t HashLen16(uint64_t u, uint64_t v, uint64_t mul) noexcept {
// Murmur-inspired hashing.
uint64_t a = (u ^ v) * mul;
a ^= (a >> 47);
uint64_t b = (v ^ a) * mul;
b ^= (b >> 47);
b *= mul;
return b;
}
[[nodiscard]]
constexpr uint64_t HashLen0to16(const char *s, size_t len) noexcept {
if (len >= 8) {
uint64_t mul = detail::k2 + len * 2;
uint64_t a = detail::Fetch64(s) + detail::k2;
uint64_t b = detail::Fetch64(s + len - 8);
uint64_t c = detail::Rotate(b, 37) * mul + a;
uint64_t d = (detail::Rotate(a, 25) + b) * mul;
return HashLen16(c, d, mul);
}
if (len >= 4) {
uint64_t mul = detail::k2 + len * 2;
uint64_t a = Fetch32(s);
return HashLen16(len + (a << 3), Fetch32(s + len - 4), mul);
}
if (len > 0) {
uint8_t a = static_cast<uint8_t>(s[0]);
uint8_t b = static_cast<uint8_t>(s[len >> 1]);
uint8_t c = static_cast<uint8_t>(s[len - 1]);
uint32_t y = static_cast<uint32_t>(a) + (static_cast<uint32_t>(b) << 8);
uint32_t z = static_cast<uint32_t>(len) + (static_cast<uint32_t>(c) << 2);
return ShiftMix(y * detail::k2 ^ z * detail::k0) * detail::k2;
}
return detail::k2;
}
// This probably works well for 16-byte strings as well, but it may be overkill
// in that case.
[[nodiscard]]
constexpr uint64_t HashLen17to32(const char *s, size_t len) noexcept {
uint64_t mul = detail::k2 + len * 2;
uint64_t a = detail::Fetch64(s) * detail::k1;
uint64_t b = detail::Fetch64(s + 8);
uint64_t c = detail::Fetch64(s + len - 8) * mul;
uint64_t d = detail::Fetch64(s + len - 16) * detail::k2;
return HashLen16(detail::Rotate(a + b, 43) + detail::Rotate(c, 30) + d,
a + detail::Rotate(b + detail::k2, 18) + c, mul);
}
// Return a 16-byte hash for 48 bytes. Quick and dirty.
// Callers do best to use "random-looking" values for a and b.
[[nodiscard]]
constexpr detail::pair<uint64_t, uint64_t> WeakHashLen32WithSeeds(
uint64_t w, uint64_t x, uint64_t y, uint64_t z, uint64_t a, uint64_t b) noexcept {
a += w;
b = detail::Rotate(b + a + z, 21);
uint64_t c = a;
a += x;
a += y;
b += detail::Rotate(a, 44);
return detail::pair(a + z, b + c);
}
// Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty.
[[nodiscard]]
constexpr detail::pair<uint64_t, uint64_t> WeakHashLen32WithSeeds(
const char* s, uint64_t a, uint64_t b) noexcept {
return WeakHashLen32WithSeeds(detail::Fetch64(s),
detail::Fetch64(s + 8),
detail::Fetch64(s + 16),
detail::Fetch64(s + 24),
a,
b);
}
// Return an 8-byte hash for 33 to 64 bytes.
[[nodiscard]]
constexpr uint64_t HashLen33to64(const char *s, size_t len) noexcept {
uint64_t mul = detail::k2 + len * 2;
uint64_t a = detail::Fetch64(s) * detail::k2;
uint64_t b = detail::Fetch64(s + 8);
uint64_t c = detail::Fetch64(s + len - 24);
uint64_t d = detail::Fetch64(s + len - 32);
uint64_t e = detail::Fetch64(s + 16) * detail::k2;
uint64_t f = detail::Fetch64(s + 24) * 9;
uint64_t g = detail::Fetch64(s + len - 8);
uint64_t h = detail::Fetch64(s + len - 16) * mul;
uint64_t u = detail::Rotate(a + g, 43) + (detail::Rotate(b, 30) + c) * 9;
uint64_t v = ((a + g) ^ d) + f + 1;
uint64_t w = detail::byteSwap((u + v) * mul) + h;
uint64_t x = detail::Rotate(e + f, 42) + c;
uint64_t y = (detail::byteSwap((v + w) * mul) + g) * mul;
uint64_t z = e + f + c;
a = detail::byteSwap((x + z) * mul + y) + b;
b = ShiftMix((z + a) * mul + d + h) * mul;
return b + x;
}
// A subroutine for CityHash128(). Returns a decent 128-bit hash for strings
// of any length representable in signed long. Based on City and Murmur.
[[nodiscard]]
constexpr uint128 CityMurmur(const char *s, size_t len, uint128 seed) noexcept {
uint64_t a = detail::Uint128Low64(seed);
uint64_t b = detail::Uint128High64(seed);
uint64_t c = 0;
uint64_t d = 0;
if (len <= 16) {
a = ShiftMix(a * detail::k1) * detail::k1;
c = b * detail::k1 + HashLen0to16(s, len);
d = ShiftMix(a + (len >= 8 ? detail::Fetch64(s) : c));
} else {
c = HashLen16(detail::Fetch64(s + len - 8) + detail::k1, a);
d = HashLen16(b + len, c + detail::Fetch64(s + len - 16));
a += d;
// len > 16 here, so do...while is safe
do {
a ^= ShiftMix(detail::Fetch64(s) * detail::k1) * detail::k1;
a *= detail::k1;
b ^= a;
c ^= ShiftMix(detail::Fetch64(s + 8) * detail::k1) * detail::k1;
c *= detail::k1;
d ^= c;
s += 16;
len -= 16;
} while (len > 16);
}
a = HashLen16(a, c);
b = HashLen16(d, b);
return uint128(a ^ b, HashLen16(b, a));
}
}
[[nodiscard]]
constexpr uint32_t CityHash32(const char *s, size_t len) noexcept {
if (len <= 24) {
return len <= 12 ?
(len <= 4 ? detail::Hash32Len0to4(s, len) : detail::Hash32Len5to12(s, len)) :
detail::Hash32Len13to24(s, len);
}
// len > 24
uint32_t h = static_cast<uint32_t>(len), g = detail::c1 * h, f = g;
uint32_t a0 = detail::Rotate32(detail::Fetch32(s + len - 4) * detail::c1, 17) * detail::c2;
uint32_t a1 = detail::Rotate32(detail::Fetch32(s + len - 8) * detail::c1, 17) * detail::c2;
uint32_t a2 = detail::Rotate32(detail::Fetch32(s + len - 16) * detail::c1, 17) * detail::c2;
uint32_t a3 = detail::Rotate32(detail::Fetch32(s + len - 12) * detail::c1, 17) * detail::c2;
uint32_t a4 = detail::Rotate32(detail::Fetch32(s + len - 20) * detail::c1, 17) * detail::c2;
h ^= a0;
h = detail::Rotate32(h, 19);
h = h * 5 + 0xe6546b64;
h ^= a2;
h = detail::Rotate32(h, 19);
h = h * 5 + 0xe6546b64;
g ^= a1;
g = detail::Rotate32(g, 19);
g = g * 5 + 0xe6546b64;
g ^= a3;
g = detail::Rotate32(g, 19);
g = g * 5 + 0xe6546b64;
f += a4;
f = detail::Rotate32(f, 19);
f = f * 5 + 0xe6546b64;
size_t iters = (len - 1) / 20;
do {
uint32_t a0 = detail::Rotate32(detail::Fetch32(s) * detail::c1, 17) * detail::c2;
uint32_t a1 = detail::Fetch32(s + 4);
uint32_t a2 = detail::Rotate32(detail::Fetch32(s + 8) * detail::c1, 17) * detail::c2;
uint32_t a3 = detail::Rotate32(detail::Fetch32(s + 12) * detail::c1, 17) * detail::c2;
uint32_t a4 = detail::Fetch32(s + 16);
h ^= a0;
h = detail::Rotate32(h, 18);
h = h * 5 + 0xe6546b64;
f += a1;
f = detail::Rotate32(f, 19);
f = f * detail::c1;
g += a2;
g = detail::Rotate32(g, 18);
g = g * 5 + 0xe6546b64;
h ^= a3 + a1;
h = detail::Rotate32(h, 19);
h = h * 5 + 0xe6546b64;
g ^= a4;
g = detail::byteSwap(g) * 5;
h += a4 * 5;
h = detail::byteSwap(h);
f += a0;
PERMUTE3(f, h, g);
s += 20;
} while (--iters != 0);
g = detail::Rotate32(g, 11) * detail::c1;
g = detail::Rotate32(g, 17) * detail::c1;
f = detail::Rotate32(f, 11) * detail::c1;
f = detail::Rotate32(f, 17) * detail::c1;
h = detail::Rotate32(h + g, 19);
h = h * 5 + 0xe6546b64;
h = detail::Rotate32(h, 17) * detail::c1;
h = detail::Rotate32(h + f, 19);
h = h * 5 + 0xe6546b64;
h = detail::Rotate32(h, 17) * detail::c1;
return h;
}
[[nodiscard]]
constexpr uint64_t CityHash64(const char *s, size_t len) noexcept {
if (len <= 32) {
if (len <= 16) {
return detail::HashLen0to16(s, len);
} else {
return detail::HashLen17to32(s, len);
}
} else if (len <= 64) {
return detail::HashLen33to64(s, len);
}
// For strings over 64 bytes we hash the end first, and then as we
// loop we keep 56 bytes of state: v, w, x, y, and z.
uint64_t x = detail::Fetch64(s + len - 40);
uint64_t y = detail::Fetch64(s + len - 16) + detail::Fetch64(s + len - 56);
uint64_t z = detail::HashLen16(detail::Fetch64(s + len - 48) + len, detail::Fetch64(s + len - 24));
detail::pair<uint64_t, uint64_t> v = detail::WeakHashLen32WithSeeds(s + len - 64, len, z);
detail::pair<uint64_t, uint64_t> w = detail::WeakHashLen32WithSeeds(s + len - 32, y + detail::k1, x);
x = x * detail::k1 + detail::Fetch64(s);
// Decrease len to the nearest multiple of 64, and operate on 64-byte chunks.
len = (len - 1) & ~static_cast<size_t>(63);
do {
x = detail::Rotate(x + y + v.first + detail::Fetch64(s + 8), 37) * detail::k1;
y = detail::Rotate(y + v.second + detail::Fetch64(s + 48), 42) * detail::k1;
x ^= w.second;
y += v.first + detail::Fetch64(s + 40);
z = detail::Rotate(z + w.first, 33) * detail::k1;
v = detail::WeakHashLen32WithSeeds(s, v.second * detail::k1, x + w.first);
w = detail::WeakHashLen32WithSeeds(s + 32, z + w.second, y + detail::Fetch64(s + 16));
detail::swap(z, x);
s += 64;
len -= 64;
} while (len != 0);
return detail::HashLen16(detail::HashLen16(v.first, w.first) + detail::ShiftMix(y) * detail::k1 + z,
detail::HashLen16(v.second, w.second) + x);
}
[[nodiscard]]
constexpr uint64_t CityHash64WithSeeds(const char *s, size_t len,
uint64_t seed0, uint64_t seed1) noexcept {
return detail::HashLen16(CityHash64(s, len) - seed0, seed1);
}
[[nodiscard]]
constexpr uint64_t CityHash64WithSeed(const char *s, size_t len, uint64_t seed) noexcept {
return CityHash64WithSeeds(s, len, detail::k2, seed);
}
[[nodiscard]]
constexpr uint128 CityHash128WithSeed(const char *s, size_t len, uint128 seed) noexcept {
if (len < 128) {
return detail::CityMurmur(s, len, seed);
}
// We expect len >= 128 to be the common case. Keep 56 bytes of state:
// v, w, x, y, and z.
detail::pair<uint64_t, uint64_t> v, w;
uint64_t x = detail::Uint128Low64(seed);
uint64_t y = detail::Uint128High64(seed);
uint64_t z = len * detail::k1;
v.first = detail::Rotate(y ^ detail::k1, 49) * detail::k1 + detail::Fetch64(s);
v.second = detail::Rotate(v.first, 42) * detail::k1 + detail::Fetch64(s + 8);
w.first = detail::Rotate(y + z, 35) * detail::k1 + x;
w.second = detail::Rotate(x + detail::Fetch64(s + 88), 53) * detail::k1;
// This is the same inner loop as CityHash64(), manually unrolled.
do {
x = detail::Rotate(x + y + v.first + detail::Fetch64(s + 8), 37) * detail::k1;
y = detail::Rotate(y + v.second + detail::Fetch64(s + 48), 42) * detail::k1;
x ^= w.second;
y += v.first + detail::Fetch64(s + 40);
z = detail::Rotate(z + w.first, 33) * detail::k1;
v = detail::WeakHashLen32WithSeeds(s, v.second * detail::k1, x + w.first);
w = detail::WeakHashLen32WithSeeds(s + 32, z + w.second, y + detail::Fetch64(s + 16));
detail::swap(z, x);
s += 64;
x = detail::Rotate(x + y + v.first + detail::Fetch64(s + 8), 37) * detail::k1;
y = detail::Rotate(y + v.second + detail::Fetch64(s + 48), 42) * detail::k1;
x ^= w.second;
y += v.first + detail::Fetch64(s + 40);
z = detail::Rotate(z + w.first, 33) * detail::k1;
v = detail::WeakHashLen32WithSeeds(s, v.second * detail::k1, x + w.first);
w = detail::WeakHashLen32WithSeeds(s + 32, z + w.second, y + detail::Fetch64(s + 16));
detail::swap(z, x);
s += 64;
len -= 128;
} while (LIKELY(len >= 128));
x += detail::Rotate(v.first + z, 49) * detail::k0;
y = y * detail::k0 + detail::Rotate(w.second, 37);
z = z * detail::k0 + detail::Rotate(w.first, 27);
w.first *= 9;
v.first *= detail::k0;
// If 0 < len < 128, hash up to 4 chunks of 32 bytes each from the end of s.
for (size_t tail_done = 0; tail_done < len; ) {
tail_done += 32;
y = detail::Rotate(x + y, 42) * detail::k0 + v.second;
w.first += detail::Fetch64(s + len - tail_done + 16);
x = x * detail::k0 + w.first;
z += w.second + detail::Fetch64(s + len - tail_done);
w.second += v.first;
v = detail::WeakHashLen32WithSeeds(s + len - tail_done, v.first + z, v.second);
v.first *= detail::k0;
}
// At this point our 56 bytes of state should contain more than
// enough information for a strong 128-bit hash. We use two
// different 56-byte-to-8-byte hashes to get a 16-byte final result.
x = detail::HashLen16(x, v.first);
y = detail::HashLen16(y + z, w.first);
return uint128(detail::HashLen16(x + v.second, w.second) + y,
detail::HashLen16(x + w.second, y + v.second));
}
[[nodiscard]]
constexpr uint128 CityHash128(const char *s, size_t len) noexcept {
return len >= 16 ?
CityHash128WithSeed(s + 16, len - 16,
uint128(detail::Fetch64(s), detail::Fetch64(s + 8) + detail::k0)) :
CityHash128WithSeed(s, len, uint128(detail::k0, detail::k1));
}
}
#endif // CITY_HASH_H_

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include <ox/std/string.hpp>
@ -27,7 +27,7 @@ ClArgs::ClArgs(int argc, const char **args) noexcept {
m_bools[arg] = false;
}
m_strings[arg] = val;
if (auto r = ox_atoi(val.c_str()); r.error == 0) {
if (auto r = ox::atoi(val.c_str()); r.error == 0) {
m_ints[arg] = r.value;
}
++i;

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -13,7 +13,7 @@
namespace ox {
Result<ClawHeader> readClawHeader(const char *buff, std::size_t buffLen) noexcept {
const auto s1End = ox_strchr(buff, ';', buffLen);
const auto s1End = ox::strchr(buff, ';', buffLen);
if (!s1End) {
return OxError(1, "Could not read Claw header");
}
@ -22,7 +22,7 @@ Result<ClawHeader> readClawHeader(const char *buff, std::size_t buffLen) noexcep
buff += s1Size + 1;
buffLen -= s1Size + 1;
const auto s2End = ox_strchr(buff, ';', buffLen);
const auto s2End = ox::strchr(buff, ';', buffLen);
if (!s2End) {
return OxError(2, "Could not read Claw header");
}
@ -31,7 +31,7 @@ Result<ClawHeader> readClawHeader(const char *buff, std::size_t buffLen) noexcep
buff += s2Size + 1;
buffLen -= s2Size + 1;
const auto s3End = ox_strchr(buff, ';', buffLen);
const auto s3End = ox::strchr(buff, ';', buffLen);
if (!s3End) {
return OxError(3, "Could not read Claw header");
}
@ -49,7 +49,7 @@ Result<ClawHeader> readClawHeader(const char *buff, std::size_t buffLen) noexcep
return OxError(4, "Claw format does not match any supported format/version combo");
}
hdr.typeName = typeName;
if (auto r = ox_atoi(versionStr.c_str()); r.error == 0) {
if (auto r = ox::atoi(versionStr.c_str()); r.error == 0) {
hdr.typeVersion = r.value;
}
hdr.data = buff;
@ -64,7 +64,7 @@ Result<ClawHeader> readClawHeader(const ox::Buffer &buff) noexcept {
Result<Buffer> stripClawHeader(const char *buff, std::size_t buffLen) noexcept {
oxRequire(header, readClawHeader(buff, buffLen));
Buffer out(header.dataSize);
ox_memcpy(out.data(), header.data, out.size());
ox::listcpy(out.data(), header.data, out.size());
return out;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include <cstdio>

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -29,7 +29,7 @@ struct TestStructNest {
static constexpr auto TypeVersion = 1;
bool Bool = false;
uint32_t Int = 0;
ox::BString<32> String = "";
ox::IString<32> String = "";
};
struct TestStruct {
@ -47,7 +47,7 @@ struct TestStruct {
int32_t Int8 = 0;
int unionIdx = 1;
TestUnion Union;
ox::BString<32> String = "";
ox::IString<32> String = "";
uint32_t List[4] = {0, 0, 0, 0};
TestStructNest EmptyStruct;
TestStructNest Struct;

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include "write.hpp"

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
@ -61,14 +61,14 @@ struct type_version<T, decltype((void) T::TypeVersion, -1)> {
template<typename T>
constexpr const char *getTypeName(const T *t) noexcept {
TypeInfoCatcher tnc;
oxIgnoreError(model(&tnc, t));
std::ignore = model(&tnc, t);
return tnc.name;
}
template<typename T>
constexpr int getTypeVersion(const T *t) noexcept {
TypeInfoCatcher tnc;
oxIgnoreError(model(&tnc, t));
std::ignore = model(&tnc, t);
return tnc.version;
}
@ -88,7 +88,7 @@ ox::Error writeClawHeader(Writer_c auto &writer, const T *t, ClawFormat fmt) noe
oxReturnError(writer.put(';'));
const auto tn = detail::getTypeVersion(t);
if (tn > -1) {
oxReturnError(ox::itoa(tn, writer));
oxReturnError(ox::writeItoa(tn, writer));
}
oxReturnError(writer.put(';'));
return {};

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include "signal.hpp"

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
@ -391,7 +391,7 @@ Error Signal<Error(Args...)>::disconnectObject(const void *receiver) const noexc
template<class... Args>
void Signal<Error(Args...)>::emit(Args... args) const noexcept {
for (auto &f : m_slots) {
oxIgnoreError(f->call(ox::forward<Args>(args)...));
std::ignore = f->call(ox::forward<Args>(args)...);
}
}

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#undef NDEBUG

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include "filestoretemplate.hpp"

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
@ -279,7 +279,7 @@ Error FileStoreTemplate<size_t>::write(uint64_t id64, const void *data, FsSize_t
oxAssert(destData.size() == dataSize, "Allocation size does not match data.");
// write data if any was provided
if (data != nullptr) {
ox_memcpy(destData, data, dest->size());
ox::memcpy(destData, data, dest->size());
oxTrace("ox.fs.FileStoreTemplate.write", "Data written");
}
auto fsData = fileStoreData();
@ -336,7 +336,7 @@ Error FileStoreTemplate<size_t>::read(uint64_t id, void *out, FsSize_t outSize,
return OxError(1);
}
ox_memcpy(out, srcData, srcData.size());
ox::memcpy(out, srcData, srcData.size());
if (size) {
*size = src.size();
}
@ -367,7 +367,7 @@ Error FileStoreTemplate<size_t>::read(uint64_t id, FsSize_t readStart, FsSize_t
return OxError(1);
}
ox_memcpy(out, srcData.get() + readStart, readSize);
ox::memcpy(out, srcData.get() + readStart, readSize);
if (size) {
*size = src.size();
}
@ -400,7 +400,7 @@ Error FileStoreTemplate<size_t>::read(uint64_t id, FsSize_t readStart,
return OxError(1);
}
ox_memcpy(out, srcData.get() + readStart, readSize);
ox::memcpy(out, srcData.get() + readStart, readSize);
if (size) {
*size = src.size();
}

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include "directory.hpp"

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
@ -48,7 +48,7 @@ struct OX_PACKED DirectoryEntry {
auto d = data();
if (d.valid()) {
d->inode = inode;
ox_strncpy(d->name, name, ox::min(bufferSize, static_cast<InodeId_t>(MaxFileNameLength)));
ox::strncpy(d->name, name, ox::min(bufferSize, static_cast<InodeId_t>(MaxFileNameLength)));
return OxError(0);
}
return OxError(1);

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include <ox/model/modelops.hpp>
@ -46,9 +46,9 @@ FileAddress &FileAddress::operator=(const FileAddress &other) noexcept {
case FileAddressType::Path:
{
if (other.m_data.path) {
auto strSize = ox_strlen(other.m_data.path) + 1;
auto strSize = ox::strlen(other.m_data.path) + 1;
m_data.path = new char[strSize];
ox_memcpy(m_data.path, other.m_data.path, strSize);
ox::memcpy(m_data.path, other.m_data.path, strSize);
} else {
m_data.constPath = "";
m_type = FileAddressType::ConstPath;
@ -88,6 +88,32 @@ FileAddress &FileAddress::operator=(FileAddress &&other) noexcept {
return *this;
}
bool FileAddress::operator==(FileAddress const&other) const noexcept {
if (m_type != other.m_type) {
auto const aIsPath =
m_type == FileAddressType::Path || m_type == FileAddressType::ConstPath;
auto const bIsPath =
other.m_type == FileAddressType::Path || other.m_type == FileAddressType::ConstPath;
if (!(aIsPath && bIsPath)) {
return false;
}
}
switch (m_type) {
case FileAddressType::ConstPath:
case FileAddressType::Path: {
auto const a = getPath();
auto const b = other.getPath();
return (other.m_type == FileAddressType::ConstPath || other.m_type == FileAddressType::Path)
&& (a.value == b.value);
}
case FileAddressType::Inode:
return m_data.inode == other.m_data.inode;
case FileAddressType::None:
return true;
}
return true;
}
bool FileAddress::operator==(CRStringView path) const noexcept {
auto [p, err] = getPath();
if (err) {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -22,6 +22,9 @@ enum class FileAddressType: int8_t {
Inode,
};
template<typename T>
constexpr Error model(T *h, CommonPtrWith<class FileAddress> auto *fa) noexcept;
class FileAddress {
template<typename T>
@ -41,13 +44,10 @@ class FileAddress {
protected:
FileAddressType m_type = FileAddressType::None;
Data m_data;
Data m_data{};
public:
constexpr FileAddress() noexcept {
m_data.inode = 0;
m_type = FileAddressType::None;
}
constexpr FileAddress() noexcept = default;
FileAddress(const FileAddress &other) noexcept;
@ -67,6 +67,8 @@ class FileAddress {
FileAddress &operator=(FileAddress &&other) noexcept;
bool operator==(const FileAddress &other) const noexcept;
bool operator==(CRStringView path) const noexcept;
[[nodiscard]]
@ -89,12 +91,12 @@ class FileAddress {
}
}
constexpr Result<ox::StringView> getPath() const noexcept {
constexpr Result<ox::CStringView> getPath() const noexcept {
switch (m_type) {
case FileAddressType::Path:
return ox::StringView(m_data.path);
return ox::CStringView(m_data.path);
case FileAddressType::ConstPath:
return ox::StringView(m_data.constPath);
return ox::CStringView(m_data.constPath);
default:
return OxError(1);
}

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include <ox/std/error.hpp>

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include <ox/std/error.hpp>
@ -186,7 +186,7 @@ Error PassThroughFS::writeFileInode(uint64_t, const void*, uint64_t, FileType) n
}
std::string_view PassThroughFS::stripSlash(StringView path) noexcept {
const auto pathLen = ox_strlen(path);
const auto pathLen = ox::strlen(path);
for (auto i = 0u; i < pathLen && path[0] == '/'; i++) {
path = substr(path, 1);
}

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include <ox/std/memops.hpp>
@ -19,7 +19,7 @@ PathIterator::PathIterator(const char *path, std::size_t maxSize, std::size_t it
m_iterator = iterator;
}
PathIterator::PathIterator(const char *path): PathIterator(path, ox_strlen(path)) {
PathIterator::PathIterator(const char *path): PathIterator(path, ox::strlen(path)) {
}
PathIterator::PathIterator(CRStringView path): PathIterator(path.data(), path.bytes()) {
@ -29,10 +29,10 @@ PathIterator::PathIterator(CRStringView path): PathIterator(path.data(), path.by
* @return 0 if no error
*/
Error PathIterator::dirPath(char *out, std::size_t outSize) {
const auto idx = ox_lastIndexOf(m_path, '/', m_maxSize);
const auto idx = ox::lastIndexOf(m_path, '/', m_maxSize);
const auto size = static_cast<std::size_t>(idx + 1);
if (idx >= 0 && size < outSize) {
ox_memcpy(out, m_path, size);
ox::memcpy(out, m_path, size);
out[size] = 0;
return OxError(0);
} else {
@ -44,12 +44,12 @@ Error PathIterator::dirPath(char *out, std::size_t outSize) {
* @return 0 if no error
*/
Error PathIterator::fileName(char *out, std::size_t outSize) {
auto idx = ox_lastIndexOf(m_path, '/', m_maxSize);
auto idx = ox::lastIndexOf(m_path, '/', m_maxSize);
if (idx >= 0) {
idx++; // pass up the preceding /
std::size_t fileNameSize = static_cast<size_t>(ox_strlen(&m_path[idx]));
std::size_t fileNameSize = static_cast<size_t>(ox::strlen(&m_path[idx]));
if (fileNameSize < outSize) {
ox_memcpy(out, &m_path[idx], fileNameSize);
ox::memcpy(out, &m_path[idx], fileNameSize);
out[fileNameSize] = 0;
return OxError(0);
} else {
@ -67,8 +67,8 @@ Error PathIterator::get(char *pathOut, std::size_t pathOutSize) {
oxTracef("ox.fs.PathIterator.get", "m_iterator ({}) >= m_maxSize ({})", m_iterator, m_maxSize);
return OxError(1);
}
if (!ox_strlen(&m_path[m_iterator])) {
oxTrace("ox.fs.PathIterator.get", "!ox_strlen(&m_path[m_iterator])");
if (!ox::strlen(&m_path[m_iterator])) {
oxTrace("ox.fs.PathIterator.get", "!ox::strlen(&m_path[m_iterator])");
return OxError(1);
}
auto start = m_iterator;
@ -76,10 +76,10 @@ Error PathIterator::get(char *pathOut, std::size_t pathOutSize) {
start++;
}
// end is at the next /
const char *substr = ox_strchr(&m_path[start], '/', m_maxSize - start);
const char *substr = ox::strchr(&m_path[start], '/', m_maxSize - start);
// correct end if it is invalid, which happens if there is no next /
if (!substr) {
substr = ox_strchr(&m_path[start], 0, m_maxSize - start);
substr = ox::strchr(&m_path[start], 0, m_maxSize - start);
}
const auto end = static_cast<size_t>(substr - m_path);
size = end - start;
@ -87,7 +87,7 @@ Error PathIterator::get(char *pathOut, std::size_t pathOutSize) {
if (size >= pathOutSize || size == 0) {
return OxError(1);
}
ox_memcpy(pathOut, &m_path[start], size);
ox::memcpy(pathOut, &m_path[start], size);
// truncate trailing /
if (size && pathOut[size - 1] == '/') {
size--;
@ -100,17 +100,17 @@ Error PathIterator::get(char *pathOut, std::size_t pathOutSize) {
Error PathIterator::next(char *pathOut, std::size_t pathOutSize) {
std::size_t size = 0;
auto retval = OxError(1);
if (m_iterator < m_maxSize && ox_strlen(&m_path[m_iterator])) {
if (m_iterator < m_maxSize && ox::strlen(&m_path[m_iterator])) {
retval = OxError(0);
if (m_path[m_iterator] == '/') {
m_iterator++;
}
const auto start = m_iterator;
// end is at the next /
const char *substr = ox_strchr(&m_path[start], '/', m_maxSize - start);
const char *substr = ox::strchr(&m_path[start], '/', m_maxSize - start);
// correct end if it is invalid, which happens if there is no next /
if (!substr) {
substr = ox_strchr(&m_path[start], 0, m_maxSize - start);
substr = ox::strchr(&m_path[start], 0, m_maxSize - start);
}
const auto end = static_cast<size_t>(substr - m_path);
size = end - start;
@ -118,7 +118,7 @@ Error PathIterator::next(char *pathOut, std::size_t pathOutSize) {
if (size >= pathOutSize) {
return OxError(1);
}
ox_memcpy(pathOut, &m_path[start], size);
ox::memcpy(pathOut, &m_path[start], size);
}
// truncate trailing /
if (size && pathOut[size - 1] == '/') {
@ -132,14 +132,14 @@ Error PathIterator::next(char *pathOut, std::size_t pathOutSize) {
/**
* @return 0 if no error
*/
Error PathIterator::get(BString<MaxFileNameLength> *fileName) {
Error PathIterator::get(IString<MaxFileNameLength> *fileName) {
return get(fileName->data(), fileName->cap());
}
/**
* @return 0 if no error
*/
Error PathIterator::next(BString<MaxFileNameLength> *fileName) {
Error PathIterator::next(IString<MaxFileNameLength> *fileName) {
return next(fileName->data(), fileName->cap());
}
@ -147,17 +147,17 @@ Result<std::size_t> PathIterator::nextSize() const {
std::size_t size = 0;
auto retval = OxError(1);
auto it = m_iterator;
if (it < m_maxSize && ox_strlen(&m_path[it])) {
if (it < m_maxSize && ox::strlen(&m_path[it])) {
retval = OxError(0);
if (m_path[it] == '/') {
it++;
}
const auto start = it;
// end is at the next /
const char *substr = ox_strchr(&m_path[start], '/', m_maxSize - start);
const char *substr = ox::strchr(&m_path[start], '/', m_maxSize - start);
// correct end if it is invalid, which happens if there is no next /
if (!substr) {
substr = ox_strchr(&m_path[start], 0, m_maxSize - start);
substr = ox::strchr(&m_path[start], 0, m_maxSize - start);
}
const auto end = static_cast<std::size_t>(substr - m_path);
size = end - start;
@ -168,16 +168,16 @@ Result<std::size_t> PathIterator::nextSize() const {
bool PathIterator::hasNext() const {
std::size_t size = 0;
if (m_iterator < m_maxSize && ox_strlen(&m_path[m_iterator])) {
if (m_iterator < m_maxSize && ox::strlen(&m_path[m_iterator])) {
std::size_t start = m_iterator;
if (m_path[start] == '/') {
start++;
}
// end is at the next /
const char *substr = ox_strchr(&m_path[start], '/', m_maxSize - start);
const char *substr = ox::strchr(&m_path[start], '/', m_maxSize - start);
// correct end if it is invalid, which happens if there is no next /
if (!substr) {
substr = ox_strchr(&m_path[start], 0, m_maxSize - start);
substr = ox::strchr(&m_path[start], 0, m_maxSize - start);
}
const auto end = static_cast<std::size_t>(substr - m_path);
size = end - start;
@ -192,16 +192,16 @@ bool PathIterator::valid() const {
PathIterator PathIterator::next() const {
std::size_t size = 0;
auto iterator = m_iterator;
if (iterator < m_maxSize && ox_strlen(&m_path[iterator])) {
if (iterator < m_maxSize && ox::strlen(&m_path[iterator])) {
if (m_path[iterator] == '/') {
iterator++;
}
const auto start = iterator;
// end is at the next /
const char *substr = ox_strchr(&m_path[start], '/', m_maxSize - start);
const char *substr = ox::strchr(&m_path[start], '/', m_maxSize - start);
// correct end if it is invalid, which happens if there is no next /
if (!substr) {
substr = ox_strchr(&m_path[start], 0, m_maxSize - start);
substr = ox::strchr(&m_path[start], 0, m_maxSize - start);
}
const auto end = static_cast<std::size_t>(substr - m_path);
size = end - start;

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
@ -13,7 +13,7 @@
namespace ox {
constexpr std::size_t MaxFileNameLength = 255;
using FileName = BString<MaxFileNameLength>;
using FileName = IString<MaxFileNameLength>;
class PathIterator {
private:

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
@ -173,15 +173,15 @@ class OX_PACKED NodeBuffer {
template<typename size_t, typename Item>
NodeBuffer<size_t, Item>::NodeBuffer(std::size_t size) noexcept {
m_header.size = static_cast<size_t>(size);
ox_memset(this + 1, 0, size - sizeof(*this));
ox::memset(this + 1, 0, size - sizeof(*this));
oxTracef("ox.NodeBuffer.constructor", "{}", m_header.firstItem.get());
}
template<typename size_t, typename Item>
NodeBuffer<size_t, Item>::NodeBuffer(const NodeBuffer &other, std::size_t size) noexcept {
oxTracef("ox.ptrarith.NodeBuffer.copy", "other.m_header.firstItem: {}", other.m_header.firstItem.get());
ox_memset(this + 1, 0, size - sizeof(*this));
ox_memcpy(this, &other, size);
ox::memset(this + 1, 0, size - sizeof(*this));
ox::memcpy(this, &other, size);
}
template<typename size_t, typename Item>
@ -291,7 +291,7 @@ Result<typename NodeBuffer<size_t, Item>::ItemPtr> NodeBuffer<size_t, Item>::mal
oxTrace("ox.ptrarith.NodeBuffer.malloc.fail", "Unknown");
return OxError(1, "NodeBuffer::malloc: unknown failure");
}
ox_memset(out, 0, fullSize);
ox::memset(out, 0, fullSize);
new (out) Item;
out->setSize(sz);
@ -367,7 +367,7 @@ Error NodeBuffer<size_t, Item>::setSize(std::size_t size) noexcept {
} else {
m_header.size = static_cast<size_t>(size);
auto data = reinterpret_cast<uint8_t*>(this) + end;
ox_memset(data, 0, size - end);
ox::memset(data, 0, size - end);
return OxError(0);
}
}
@ -405,7 +405,7 @@ Error NodeBuffer<size_t, Item>::compact(F cb) noexcept {
return OxError(2);
}
// move node
ox_memcpy(dest, src, src->fullSize());
ox::memcpy(dest, src, src->fullSize());
oxReturnError(cb(src, dest));
// update surrounding nodes
auto prev = ptr(dest->prev);

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
// make sure asserts are enabled for the test file
@ -34,7 +34,7 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
using BuffPtr_t = uint32_t;
ox::Vector<char> buff(5 * ox::units::MB);
auto buffer = new (buff.data()) ox::ptrarith::NodeBuffer<BuffPtr_t, NodeType<BuffPtr_t>>(buff.size());
using String = ox::BString<6>;
using String = ox::IString<6>;
auto a1 = buffer->malloc(sizeof(String)).value;
auto a2 = buffer->malloc(sizeof(String)).value;
oxAssert(a1.valid(), "Allocation 1 failed.");
@ -61,9 +61,9 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
auto const path = ox::String("/usr/share/charset.gbag");
ox::PathIterator it(path.c_str(), path.len());
auto buff = static_cast<char*>(ox_alloca(path.len() + 1));
oxAssert(it.next(buff, path.len()) == 0 && ox_strcmp(buff, "usr") == 0, "PathIterator shows wrong next");
oxAssert(it.next(buff, path.len()) == 0 && ox_strcmp(buff, "share") == 0, "PathIterator shows wrong next");
oxAssert(it.next(buff, path.len()) == 0 && ox_strcmp(buff, "charset.gbag") == 0, "PathIterator shows wrong next");
oxAssert(it.next(buff, path.len()) == 0 && ox::strcmp(buff, "usr") == 0, "PathIterator shows wrong next");
oxAssert(it.next(buff, path.len()) == 0 && ox::strcmp(buff, "share") == 0, "PathIterator shows wrong next");
oxAssert(it.next(buff, path.len()) == 0 && ox::strcmp(buff, "charset.gbag") == 0, "PathIterator shows wrong next");
return OxError(0);
}
},
@ -73,8 +73,8 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
auto const path = ox::String("/usr/share/");
ox::PathIterator it(path.c_str(), path.len());
auto buff = static_cast<char*>(ox_alloca(path.len() + 1));
oxAssert(it.next(buff, path.len()) == 0 && ox_strcmp(buff, "usr") == 0, "PathIterator shows wrong next");
oxAssert(it.next(buff, path.len()) == 0 && ox_strcmp(buff, "share") == 0, "PathIterator shows wrong next");
oxAssert(it.next(buff, path.len()) == 0 && ox::strcmp(buff, "usr") == 0, "PathIterator shows wrong next");
oxAssert(it.next(buff, path.len()) == 0 && ox::strcmp(buff, "share") == 0, "PathIterator shows wrong next");
return OxError(0);
}
},
@ -84,7 +84,7 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
auto const path = ox::String("/");
ox::PathIterator it(path.c_str(), path.len());
auto buff = static_cast<char*>(ox_alloca(path.len() + 1));
oxAssert(it.next(buff, path.len()) == 0 && ox_strcmp(buff, "\0") == 0, "PathIterator shows wrong next");
oxAssert(it.next(buff, path.len()) == 0 && ox::strcmp(buff, "\0") == 0, "PathIterator shows wrong next");
return OxError(0);
}
},
@ -94,9 +94,9 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
auto const path = ox::String("usr/share/charset.gbag");
ox::PathIterator it(path.c_str(), path.len());
auto buff = static_cast<char*>(ox_alloca(path.len() + 1));
oxAssert(it.next(buff, path.len()) == 0 && ox_strcmp(buff, "usr") == 0, "PathIterator shows wrong next");
oxAssert(it.next(buff, path.len()) == 0 && ox_strcmp(buff, "share") == 0, "PathIterator shows wrong next");
oxAssert(it.next(buff, path.len()) == 0 && ox_strcmp(buff, "charset.gbag") == 0, "PathIterator shows wrong next");
oxAssert(it.next(buff, path.len()) == 0 && ox::strcmp(buff, "usr") == 0, "PathIterator shows wrong next");
oxAssert(it.next(buff, path.len()) == 0 && ox::strcmp(buff, "share") == 0, "PathIterator shows wrong next");
oxAssert(it.next(buff, path.len()) == 0 && ox::strcmp(buff, "charset.gbag") == 0, "PathIterator shows wrong next");
return OxError(0);
}
},
@ -106,8 +106,8 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
auto const path = ox::String("usr/share/");
ox::PathIterator it(path.c_str(), path.len());
auto buff = static_cast<char*>(ox_alloca(path.len() + 1));
oxAssert(it.next(buff, path.len()) == 0 && ox_strcmp(buff, "usr") == 0, "PathIterator shows wrong next");
oxAssert(it.next(buff, path.len()) == 0 && ox_strcmp(buff, "share") == 0, "PathIterator shows wrong next");
oxAssert(it.next(buff, path.len()) == 0 && ox::strcmp(buff, "usr") == 0, "PathIterator shows wrong next");
oxAssert(it.next(buff, path.len()) == 0 && ox::strcmp(buff, "share") == 0, "PathIterator shows wrong next");
return OxError(0);
}
},
@ -117,7 +117,7 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
auto const path = ox::String("/usr/share/charset.gbag");
ox::PathIterator it(path.c_str(), path.len());
auto buff = static_cast<char*>(ox_alloca(path.len() + 1));
oxAssert(it.dirPath(buff, path.len()) == 0 && ox_strcmp(buff, "/usr/share/") == 0, "PathIterator shows incorrect dir path");
oxAssert(it.dirPath(buff, path.len()) == 0 && ox::strcmp(buff, "/usr/share/") == 0, "PathIterator shows incorrect dir path");
return OxError(0);
}
},
@ -127,7 +127,7 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
auto const path = ox::String("/usr/share/charset.gbag");
ox::PathIterator it(path.c_str(), path.len());
auto buff = static_cast<char*>(ox_alloca(path.len() + 1));
oxAssert(it.fileName(buff, path.len()) == 0 && ox_strcmp(buff, "charset.gbag") == 0, "PathIterator shows incorrect file name");
oxAssert(it.fileName(buff, path.len()) == 0 && ox::strcmp(buff, "charset.gbag") == 0, "PathIterator shows incorrect file name");
return OxError(0);
}
},
@ -135,7 +135,7 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
"PathIterator::hasNext",
[](ox::StringView) {
const auto path = "/file1";
ox::PathIterator it(path, ox_strlen(path));
ox::PathIterator it(path, ox::strlen(path));
oxAssert(it.hasNext(), "PathIterator shows incorrect hasNext");
oxAssert(!it.next().hasNext(), "PathIterator shows incorrect hasNext");
return OxError(0);
@ -171,9 +171,9 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
[](ox::StringView) {
constexpr auto buffLen = 5000;
constexpr auto str1 = "Hello, World!";
constexpr auto str1Len = ox_strlen(str1) + 1;
constexpr auto str1Len = ox::strlen(str1) + 1;
constexpr auto str2 = "Hello, Moon!";
constexpr auto str2Len = ox_strlen(str2) + 1;
constexpr auto str2Len = ox::strlen(str2) + 1;
auto list = new (ox_alloca(buffLen)) ox::ptrarith::NodeBuffer<uint32_t, ox::FileStoreItem<uint32_t>>(buffLen);
oxAssert(ox::FileStore32::format(list, buffLen), "FileStore::format failed.");
ox::FileStore32 fileStore(list, buffLen);

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include <cstdio>

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -47,13 +47,13 @@ class CirculerBuffer {
}
// write seg 1
const auto seg1Sz = ox::min(sz, m_buff.size() - m_writePt);
ox_memcpy(&m_buff[m_writePt], &buff[0], seg1Sz);
ox::listcpy(&m_buff[m_writePt], &buff[0], seg1Sz);
m_writePt += sz;
if (seg1Sz != sz) {
m_writePt -= m_buff.size();
// write seg 2
const auto seg2Sz = sz - seg1Sz;
ox_memcpy(&m_buff[0], &buff[seg1Sz], seg2Sz);
ox::listcpy(&m_buff[0], &buff[seg1Sz], seg2Sz);
oxAssert(m_buff[0] == buff[seg1Sz], "break");
}
return {};
@ -70,7 +70,7 @@ class CirculerBuffer {
return {};
}
constexpr ox::Error seekp(int, ios_base::seekdir) {
constexpr ox::Error seekp(int, ios_base::seekdir) noexcept {
return OxError(1, "Unimplemented");
}
@ -84,13 +84,13 @@ class CirculerBuffer {
const auto bytesRead = ox::min(outSize, m_buff.size() - avail());
// read seg 1
const auto seg1Sz = ox::min(bytesRead, m_buff.size() - m_readPt);
ox_memcpy(&out[0], &m_buff[m_readPt], seg1Sz);
ox::listcpy(&out[0], &m_buff[m_readPt], seg1Sz);
m_readPt += bytesRead;
if (seg1Sz != bytesRead) {
m_readPt -= m_buff.size();
// read seg 2
const auto seg2Sz = bytesRead - seg1Sz;
ox_memcpy(&out[seg1Sz], &m_buff[0], seg2Sz);
ox::listcpy(&out[seg1Sz], &m_buff[0], seg2Sz);
}
return bytesRead;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -98,7 +98,7 @@ void LoggerConn::msgSend() noexcept {
break;
}
//std::printf("LoggerConn: sending %lu bytes\n", read);
oxIgnoreError(send(tmp.data(), read));
std::ignore = send(tmp.data(), read);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
@ -71,7 +71,7 @@ constexpr McInt encodeInteger(I pInput) noexcept {
// move input to uint64_t to allow consistent bit manipulation, and to avoid
// overflow concerns
uint64_t val = 0;
ox_memcpy(&val, &input, sizeof(input));
ox::memcpy(&val, &input, sizeof(input));
if (val) {
// bits needed to represent number factoring in space possibly
// needed for signed bit
@ -94,7 +94,7 @@ constexpr McInt encodeInteger(I pInput) noexcept {
}
if (bytes == 9) {
out.data[0] = bytesIndicator;
ox_memcpy(&out.data[1], &leVal, 8);
ox::memcpy(&out.data[1], &leVal, 8);
if (inputNegative) {
out.data[1] |= 0b1000'0000;
}
@ -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, &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.data(), &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.data(), sizeof(out));
return out;
}
}

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include "err.hpp"

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -77,7 +77,7 @@ class MetalClawReaderTemplate: public ModelHandlerBase<MetalClawReaderTemplate<R
constexpr Error field(const char*, BasicString<SmallStringSize> *val) noexcept;
template<std::size_t L>
constexpr Error field(const char*, BString<L> *val) noexcept;
constexpr Error field(const char*, IString<L> *val) noexcept;
constexpr Error fieldCString(const char*, char *val, std::size_t buffLen) noexcept;
@ -336,7 +336,7 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char*, BasicString<
template<Reader_c Reader>
template<std::size_t L>
constexpr Error MetalClawReaderTemplate<Reader>::field(const char *name, BString<L> *val) noexcept {
constexpr Error MetalClawReaderTemplate<Reader>::field(const char *name, IString<L> *val) noexcept {
return fieldCString(name, val->data(), val->cap());
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -27,7 +27,7 @@ struct TestStructNest {
static constexpr auto TypeVersion = 1;
bool Bool = false;
uint32_t Int = 0;
ox::BString<32> BString = "";
ox::IString<32> IString = "";
};
struct TestStruct {
@ -46,7 +46,7 @@ struct TestStruct {
int unionIdx = 1;
TestUnion Union;
ox::String String;
ox::BString<32> BString = "";
ox::IString<32> IString = "";
uint32_t List[4] = {0, 0, 0, 0};
ox::Vector<uint32_t> Vector = {1, 2, 3, 4, 5};
ox::Vector<uint32_t> Vector2 = {1, 2, 3, 4, 5};
@ -72,7 +72,7 @@ constexpr ox::Error model(T *io, ox::CommonPtrWith<TestUnion> auto *obj) noexcep
oxModelBegin(TestStructNest)
oxModelField(Bool)
oxModelField(Int)
oxModelField(BString)
oxModelField(IString)
oxModelEnd()
template<typename T>
@ -95,7 +95,7 @@ constexpr ox::Error model(T *io, ox::CommonPtrWith<TestStruct> auto *obj) noexce
oxReturnError(io->field("Union", ox::UnionView{&obj->Union, obj->unionIdx}));
}
oxReturnError(io->field("String", &obj->String));
oxReturnError(io->field("BString", &obj->BString));
oxReturnError(io->field("IString", &obj->IString));
oxReturnError(io->field("List", obj->List, 4));
oxReturnError(io->field("Vector", &obj->Vector));
oxReturnError(io->field("Vector2", &obj->Vector2));
@ -127,7 +127,7 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
TestStruct testIn, testOut;
testIn.Bool = true;
testIn.Int = 42;
testIn.BString = "Test String 1";
testIn.IString = "Test String 1";
testIn.String = "Test String 2";
testIn.Vector = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, };
testIn.Vector2 = {};
@ -137,7 +137,7 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
testIn.List[3] = 4;
testIn.Struct.Bool = true;
testIn.Struct.Int = 300;
testIn.Struct.BString = "Test String 3";
testIn.Struct.IString = "Test String 3";
testIn.unionIdx = 1;
testIn.Union.Int = 93;
// run tests
@ -157,7 +157,7 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
oxAssert(testIn.Int8 == testOut.Int8, "Int8 value mismatch");
oxAssert(testIn.Union.Int == testOut.Union.Int, "Union.Int value mismatch");
oxAssert(testIn.String == testOut.String, "String value mismatch");
oxAssert(testIn.BString == testOut.BString, "BString value mismatch");
oxAssert(testIn.IString == testOut.IString, "IString value mismatch");
oxAssert(testIn.List[0] == testOut.List[0], "List[0] value mismatch");
oxAssert(testIn.List[1] == testOut.List[1], "List[1] value mismatch");
oxAssert(testIn.List[2] == testOut.List[2], "List[2] value mismatch");
@ -171,9 +171,9 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
oxAssert(testIn.Map["aoeu"] == testOut.Map["aoeu"], "Map[\"aoeu\"] value mismatch");
oxAssert(testIn.EmptyStruct.Bool == testOut.EmptyStruct.Bool, "EmptyStruct.Bool value mismatch");
oxAssert(testIn.EmptyStruct.Int == testOut.EmptyStruct.Int, "EmptyStruct.Int value mismatch");
oxAssert(testIn.EmptyStruct.BString == testOut.EmptyStruct.BString, "EmptyStruct.BString value mismatch");
oxAssert(testIn.EmptyStruct.IString == testOut.EmptyStruct.IString, "EmptyStruct.IString value mismatch");
oxAssert(testIn.Struct.Int == testOut.Struct.Int, "Struct.Int value mismatch");
oxAssert(testIn.Struct.BString == testOut.Struct.BString, "Struct.BString value mismatch");
oxAssert(testIn.Struct.IString == testOut.Struct.IString, "Struct.IString value mismatch");
oxAssert(testIn.Struct.Bool == testOut.Struct.Bool, "Struct.Bool value mismatch");
return OxError(0);
}
@ -303,14 +303,14 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
TestStruct testIn;
testIn.Bool = true;
testIn.Int = 42;
testIn.BString = "Test String 1";
testIn.IString = "Test String 1";
testIn.List[0] = 1;
testIn.List[1] = 2;
testIn.List[2] = 3;
testIn.List[3] = 4;
testIn.Struct.Bool = true;
testIn.Struct.Int = 300;
testIn.Struct.BString = "Test String 2";
testIn.Struct.IString = "Test String 2";
testIn.unionIdx = 1;
testIn.Union.Int = 93;
oxAssert(ox::writeMC(dataBuff.data(), dataBuff.size(), testIn), "Data generation failed");
@ -320,27 +320,27 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
ox::ModelObject testOut;
oxReturnError(testOut.setType(type));
oxAssert(ox::readMC(dataBuff.data(), dataBuff.size(), &testOut), "Data read failed");
oxAssert(testOut["Int"].get<int>() == testIn.Int, "testOut.Int failed");
oxAssert(testOut["Bool"].get<bool>() == testIn.Bool, "testOut.Bool failed");
oxAssert(testOut["BString"].get<ox::String>() == testIn.BString.c_str(), "testOut.String failed");
oxAssert(testOut["String"].get<ox::String>() == testIn.String, "testOut.String failed");
auto &testOutStruct = testOut["Struct"].get<ox::ModelObject>();
auto &testOutUnion = testOut["Union"].get<ox::ModelUnion>();
auto &testOutList = testOut["List"].get<ox::ModelValueVector>();
auto testOutStructCopy = testOut["Struct"].get<ox::ModelObject>();
auto testOutUnionCopy = testOut["Union"].get<ox::ModelUnion>();
auto testOutListCopy = testOut["List"].get<ox::ModelValueVector>();
oxAssert(testOut.at("Int").unwrap()->get<int>() == testIn.Int, "testOut.Int failed");
oxAssert(testOut.at("Bool").unwrap()->get<bool>() == testIn.Bool, "testOut.Bool failed");
oxAssert(testOut.at("IString").unwrap()->get<ox::String>() == testIn.IString.c_str(), "testOut.String failed");
oxAssert(testOut.at("String").unwrap()->get<ox::String>() == testIn.String, "testOut.String failed");
auto &testOutStruct = testOut.at("Struct").unwrap()->get<ox::ModelObject>();
auto &testOutUnion = testOut.at("Union").unwrap()->get<ox::ModelUnion>();
auto &testOutList = testOut.at("List").unwrap()->get<ox::ModelValueVector>();
auto testOutStructCopy = testOut.at("Struct").unwrap()->get<ox::ModelObject>();
auto testOutUnionCopy = testOut.at("Union").unwrap()->get<ox::ModelUnion>();
auto testOutListCopy = testOut.at("List").unwrap()->get<ox::ModelValueVector>();
oxAssert(testOutStruct.typeName() == TestStructNest::TypeName, "ModelObject TypeName failed");
oxAssert(testOutStruct.typeVersion() == TestStructNest::TypeVersion, "ModelObject TypeVersion failed");
oxAssert(testOutStruct["Bool"].get<bool>() == testIn.Struct.Bool, "testOut.Struct.Bool failed");
oxAssert(testOutStruct["BString"].get<ox::String>() == testIn.Struct.BString.c_str(), "testOut.Struct.BString failed");
oxAssert(testOut["unionIdx"].get<int>() == testIn.unionIdx, "testOut.unionIdx failed");
oxAssert(testOutStruct.at("Bool").unwrap()->get<bool>() == testIn.Struct.Bool, "testOut.Struct.Bool failed");
oxAssert(testOutStruct.at("IString").unwrap()->get<ox::String>() == testIn.Struct.IString.c_str(), "testOut.Struct.IString failed");
oxAssert(testOut.at("unionIdx").unwrap()->get<int>() == testIn.unionIdx, "testOut.unionIdx failed");
oxAssert(testOutUnion.unionIdx() == testIn.unionIdx, "testOut.Union idx wrong");
oxAssert(testOutUnion["Int"].get<uint32_t>() == testIn.Union.Int, "testOut.Union.Int failed");
oxAssert(testOutUnion.at("Int").unwrap()->get<uint32_t>() == testIn.Union.Int, "testOut.Union.Int failed");
oxAssert(testOutList[0].get<uint32_t>() == testIn.List[0], "testOut.List[0] failed");
oxAssert(testOutList[1].get<uint32_t>() == testIn.List[1], "testOut.Struct.List[1] failed");
oxAssert(testOutStructCopy["Bool"].get<bool>() == testIn.Struct.Bool, "testOut.Struct.Bool (copy) failed");
oxAssert(testOutStructCopy["BString"].get<ox::String>() == testIn.Struct.BString.c_str(), "testOut.Struct.BString (copy) failed");
oxAssert(testOutStructCopy.at("Bool").unwrap()->get<bool>() == testIn.Struct.Bool, "testOut.Struct.Bool (copy) failed");
oxAssert(testOutStructCopy.at("IString").unwrap()->get<ox::String>() == testIn.Struct.IString.c_str(), "testOut.Struct.IString (copy) failed");
oxAssert(testOutListCopy[0].get<uint32_t>() == testIn.List[0], "testOut.Struct.List[0] (copy) failed");
oxAssert(testOutListCopy[1].get<uint32_t>() == testIn.List[1], "testOut.Struct.List[1] (copy) failed");
return OxError(0);
@ -357,14 +357,14 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
TestStruct testIn, testOut;
testIn.Bool = true;
testIn.Int = 42;
testIn.BString = "Test String 1";
testIn.IString = "Test String 1";
testIn.List[0] = 1;
testIn.List[1] = 2;
testIn.List[2] = 3;
testIn.List[3] = 4;
testIn.Struct.Bool = false;
testIn.Struct.Int = 300;
testIn.Struct.BString = "Test String 2";
testIn.Struct.IString = "Test String 2";
oxAssert(ox::writeMC(dataBuff, dataBuffLen, testIn), "Data generation failed");
ox::TypeStore typeStore;
const auto [type, typeErr] = ox::buildTypeDef(&typeStore, &testIn);

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -66,7 +66,7 @@ class MetalClawWriter {
constexpr Error field(const char*, const BasicString<SmallStringSize> *val) noexcept;
template<std::size_t L>
constexpr Error field(const char*, const BString<L> *val) noexcept;
constexpr Error field(const char*, const IString<L> *val) noexcept;
constexpr Error fieldCString(const char *name, const char *const*val, std::size_t buffLen) noexcept;
@ -206,7 +206,7 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const BasicString<Sm
template<Writer_c Writer>
template<std::size_t L>
constexpr Error MetalClawWriter<Writer>::field(const char *name, const BString<L> *val) noexcept {
constexpr Error MetalClawWriter<Writer>::field(const char *name, const IString<L> *val) noexcept {
return fieldCString(name, val->data(), val->cap());
}
@ -214,7 +214,7 @@ template<Writer_c Writer>
constexpr Error MetalClawWriter<Writer>::fieldCString(const char*, const char *const*val, std::size_t) noexcept {
bool fieldSet = false;
if (!m_unionIdx.has_value() || *m_unionIdx == m_field) {
const auto strLen = *val ? ox_strlen(*val) : 0;
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));

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -13,5 +13,5 @@
#define oxModelBegin(modelName) constexpr ox::Error model(auto *io, [[maybe_unused]] ox::CommonPtrWith<modelName> auto *o) noexcept { oxReturnError(io->template setTypeInfo<modelName>());
#define oxModelEnd() return OxError(0); }
#define oxModelField(fieldName) oxReturnError(io->field(#fieldName, &o->fieldName));
#define oxModelFieldRename(serFieldName, objFieldName) oxReturnError(io->field(#serFieldName, &o->objFieldName));
#define oxModelFieldRename(objFieldName, serFieldName) oxReturnError(io->field(#serFieldName, &o->objFieldName));
#define oxModelFriend(modelName) friend constexpr ox::Error model(auto*, ox::CommonPtrWith<modelName> auto*) noexcept

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include "desctypes.hpp"

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -9,7 +9,7 @@
#pragma once
#include <ox/std/byteswap.hpp>
#include <ox/std/bstring.hpp>
#include <ox/std/istring.hpp>
#include <ox/std/memory.hpp>
#include <ox/std/string.hpp>
#include <ox/std/trace.hpp>
@ -152,7 +152,7 @@ class TypeDescWriter {
template<std::size_t sz>
[[nodiscard]]
constexpr const DescriptorType *type(const BString<sz> *val) const noexcept;
constexpr const DescriptorType *type(const IString<sz> *val) const noexcept;
template<typename T>
[[nodiscard]]
@ -334,7 +334,7 @@ constexpr const DescriptorType *TypeDescWriter::type(const char*) const noexcept
}
template<std::size_t sz>
constexpr const DescriptorType *TypeDescWriter::type(const BString<sz>*) const noexcept {
constexpr const DescriptorType *TypeDescWriter::type(const IString<sz>*) const noexcept {
constexpr auto PT = PrimitiveType::String;
return getType(types::BString, 0, PT, 0);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,15 +1,15 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
#include <ox/std/byteswap.hpp>
#include <ox/std/bstring.hpp>
#include <ox/std/istring.hpp>
#include <ox/std/memory.hpp>
#include <ox/std/string.hpp>
#include <ox/std/trace.hpp>

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -131,6 +131,8 @@ class ModelHandlerInterface {
}
case ModelValue::Type::Vector:
return m_handler->field(name, &v->template get<ModelValueVector>());
case ModelValue::Type::InlineArray:
return m_handler->field(name, &v->template get<ModelValueArray>());
}
oxErrf("invalid type: {}: {}\n", name, static_cast<int>(v->type()));
oxPanic(OxError(1), "invalid type");

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
@ -276,8 +276,8 @@ constexpr void moveModel(T *dst, T *src) noexcept {
constexpr auto size = ModelFieldCount_v<T>;
detail::MemberList<size> dstFields;
detail::Mover<size> mover(&dstFields);
oxIgnoreError(model(&dstFields, dst));
oxIgnoreError(model(&mover, src));
std::ignore = model(&dstFields, dst);
std::ignore = model(&mover, src);
}
template<typename T>
@ -285,8 +285,8 @@ constexpr void copyModel(T *dst, const T *src) noexcept {
constexpr auto size = ModelFieldCount_v<T>;
detail::MemberList<size> dstFields;
detail::Copier<size> copier(&dstFields);
oxIgnoreError(model(&dstFields, dst));
oxIgnoreError(model(&copier, src));
std::ignore = model(&dstFields, dst);
std::ignore = model(&copier, src);
}
template<typename T>
@ -295,8 +295,8 @@ constexpr bool equalsModel(T *a, T *b) noexcept {
constexpr auto size = T::Fields;
detail::MemberList<size> aFields;
detail::Equals<size> equals(&aFields);
oxIgnoreError(model(&aFields, a));
oxIgnoreError(model(&equals, b));
std::ignore = model(&aFields, a);
std::ignore = model(&equals, b);
return equals.value;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -31,6 +31,7 @@ namespace ox {
class ModelObject;
class ModelUnion;
class ModelValue;
class ModelValueArray;
class ModelValueVector;
class ModelValue {
@ -50,6 +51,7 @@ class ModelValue {
Object,
Union,
Vector,
InlineArray,
};
private:
@ -68,6 +70,7 @@ class ModelValue {
ModelObject *obj;
ModelUnion *uni;
ModelValueVector *vec;
ModelValueArray *array;
} m_data;
template<typename T>
@ -101,6 +104,8 @@ class ModelValue {
return Type::String;
} else if constexpr(is_same_v<U, ModelValueVector>) {
return Type::Vector;
} else if constexpr(is_same_v<U, ModelValueArray>) {
return Type::InlineArray;
} else {
return Type::Undefined;
}
@ -134,6 +139,8 @@ class ModelValue {
return *t.m_data.obj;
} else if constexpr(type == Type::Vector) {
return *t.m_data.vec;
} else if constexpr(type == Type::InlineArray) {
return *t.m_data.array;
} else {
return t.m_data.i32;
}
@ -147,10 +154,12 @@ class ModelValue {
constexpr ModelValue(ModelValue &&other) noexcept;
template<typename T>
explicit constexpr ModelValue(const T &val) noexcept;
explicit constexpr ModelValue(const T &val) noexcept
requires(!ox::is_same_v<ox::remove_reference_t<T>, ModelValue>);
template<typename T>
explicit constexpr ModelValue(T &&val) noexcept;
explicit constexpr ModelValue(T &&val) noexcept
requires(!ox::is_same_v<ox::remove_reference_t<T>, ModelValue>);
constexpr ~ModelValue() noexcept;
@ -177,7 +186,10 @@ class ModelValue {
[[nodiscard]]
constexpr Type type() const noexcept;
constexpr Error setType(const DescriptorType *type, int subscriptLevels = 0) noexcept;
constexpr Error setType(
DescriptorType const*type,
int subscriptLevels = 0,
SubscriptStack const& = {}) noexcept;
template<typename T>
constexpr Error setType() noexcept;
@ -199,11 +211,166 @@ class ModelValue {
};
class ModelValueArray {
private:
Vector<ModelValue> m_vec;
const DescriptorType *m_type = nullptr;
int m_typeSubscriptLevels = 0;
SubscriptStack m_subscriptStack;
String m_typeName;
int m_typeVersion = 0;
public:
constexpr explicit ModelValueArray() noexcept = default;
constexpr ModelValueArray(ModelValueArray const&other) noexcept {
for (auto &v : other.m_vec) {
m_vec.emplace_back(v);
}
m_typeName = other.m_typeName;
m_typeVersion = other.m_typeVersion;
}
constexpr ModelValueArray(ModelValueArray &&other) noexcept {
m_vec = std::move(other.m_vec);
m_typeName = std::move(other.m_typeName);
m_typeVersion = other.m_typeVersion;
}
constexpr ox::Error setSize(std::size_t sz) noexcept {
const auto oldSz = m_vec.size();
m_vec.resize(sz);
if (sz > oldSz) {
for (auto i = oldSz; i < sz; ++i) {
oxReturnError(m_vec[i].setType(m_type, m_typeSubscriptLevels));
}
}
return {};
}
[[nodiscard]]
constexpr auto data() const noexcept {
return m_vec.data();
}
[[nodiscard]]
constexpr auto data() noexcept {
return m_vec.data();
}
constexpr static ox::Result<ModelValueArray> make(size_t sz) noexcept {
ox::Result<ModelValueArray> out;
out.error = out.value.setSize(sz);
return out;
}
[[nodiscard]]
constexpr auto &get() noexcept {
return m_vec;
}
[[nodiscard]]
constexpr auto const&get() const noexcept {
return m_vec;
}
constexpr Error setType(
DescriptorType const*type,
int subscriptLevels,
SubscriptStack subscriptStack) noexcept {
m_type = type;
m_typeSubscriptLevels = subscriptLevels;
m_subscriptStack = std::move(subscriptStack);
return {};
}
[[nodiscard]]
constexpr String const&typeName() const noexcept {
return m_typeName;
}
[[nodiscard]]
constexpr int typeVersion() const noexcept {
return m_typeVersion;
}
[[nodiscard]]
constexpr std::size_t size() const noexcept {
return m_vec.size();
}
constexpr auto &operator[](std::size_t i) noexcept {
return m_vec[i];
}
constexpr auto &operator[](std::size_t i) const noexcept {
return m_vec[i];
}
[[nodiscard]]
auto begin() noexcept {
return m_vec.begin();
}
[[nodiscard]]
auto begin() const noexcept {
return m_vec.cbegin();
}
[[nodiscard]]
auto cbegin() const noexcept {
return m_vec.cbegin();
}
[[nodiscard]]
auto rbegin() noexcept {
return m_vec.rbegin();
}
[[nodiscard]]
auto crbegin() const noexcept {
return m_vec.crbegin();
}
[[nodiscard]]
auto end() noexcept {
return m_vec.end();
}
[[nodiscard]]
auto end() const noexcept {
return m_vec.cend();
}
[[nodiscard]]
auto cend() const noexcept {
return m_vec.cend();
}
[[nodiscard]]
auto rend() noexcept {
return m_vec.rend();
}
[[nodiscard]]
auto crend() const noexcept {
return m_vec.crend();
}
};
template<>
[[nodiscard]]
consteval bool isArray(ModelValueArray*) noexcept {
return true;
}
class ModelValueVector {
private:
Vector<ModelValue> m_vec;
const DescriptorType *m_type = nullptr;
int m_typeSubscriptLevels = 0;
SubscriptStack m_subscriptStack;
String m_typeName;
int m_typeVersion = 0;
@ -233,7 +400,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));
oxReturnError(m_vec[i].setType(m_type, m_typeSubscriptLevels, m_subscriptStack));
}
}
return {};
@ -249,9 +416,13 @@ class ModelValueVector {
return m_vec;
}
constexpr Error setType(const DescriptorType *type, int subscriptLevels) noexcept {
constexpr Error setType(
DescriptorType const*type,
int subscriptLevels,
SubscriptStack subscriptStack) noexcept {
m_type = type;
m_typeSubscriptLevels = subscriptLevels;
m_subscriptStack = std::move(subscriptStack);
return {};
}
@ -334,7 +505,12 @@ consteval bool isVector(const ModelValueVector*) noexcept {
return true;
}
constexpr Error model(auto *h, CommonPtrWith<ModelObject> auto *obj) noexcept;
constexpr Error model(auto *h, CommonPtrWith<ModelUnion> auto *obj) noexcept;
class ModelObject {
friend constexpr Error model(auto *h, CommonPtrWith<ModelObject> auto *obj) noexcept;
public:
struct Field {
String name;
@ -466,12 +642,9 @@ class ModelObject {
return {};
}
constexpr auto &operator[](StringView const&k) noexcept {
auto [v, err] = m_fields.at(k);
if (err) [[unlikely]] {
oxPanic(err, ox::sfmt("field {} does not exist in type {}", k, buildTypeId(*m_type)).c_str());
}
return **v;
constexpr ox::Result<ModelValue*> at(StringView const&k) noexcept {
oxRequire(v, m_fields.at(k));
return *v;
}
constexpr auto &operator[](const std::size_t i) noexcept {
@ -501,7 +674,7 @@ 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));
oxReturnError(field->value.setType(f.type, f.subscriptLevels, f.subscriptStack));
m_fields[field->name] = &field->value;
m_fieldsOrder.emplace_back(std::move(field));
}
@ -517,7 +690,7 @@ class ModelUnion {
String name;
ModelValue value;
};
oxModelFriend(ModelUnion);
friend constexpr Error model(auto *h, CommonPtrWith<ModelUnion> auto *obj) noexcept;
friend ModelValue;
Vector<UniquePtr<Field>> m_fieldsOrder;
HashMap<String, Field*> m_fields;
@ -555,12 +728,9 @@ class ModelUnion {
return UniquePtr<ModelUnion>(new ModelUnion(other));
}
constexpr auto &operator[](StringView const&k) noexcept {
const auto [v, err] = m_fields.at(k);
if (err) [[unlikely]] {
oxPanic(err, ox::sfmt("field {} does not exist in type {}", k, buildTypeId(*m_type)).c_str());
}
return (*v)->value;
constexpr ox::Result<ModelValue*> at(StringView const&k) noexcept {
oxRequire(v, m_fields.at(k));
return &(*v)->value;
}
constexpr auto &operator[](const std::size_t i) noexcept {
@ -647,6 +817,12 @@ class ModelUnion {
};
template<typename PlatSpec>
[[nodiscard]]
constexpr std::size_t sizeOf(ModelValueArray const*v) noexcept {
return sizeOf<PlatSpec>(&(*v)[0]) * v->size();
}
template<typename PlatSpec>
[[nodiscard]]
constexpr std::size_t sizeOf(const ModelValueVector*) noexcept {
@ -708,10 +884,22 @@ constexpr std::size_t sizeOf(const ModelValue *t) noexcept {
case ModelValue::Type::Vector:
size = sizeOf<PlatSpec>(&t->get<ox::ModelValueVector>());
break;
case ModelValue::Type::InlineArray:
{
auto &list = t->get<ox::ModelValueArray>();
size = sizeOf<PlatSpec>(&list[0]) * list.size();
break;
}
}
return size;
}
template<typename PlatSpec>
[[nodiscard]]
constexpr std::size_t alignOf(ModelValueArray const&v) noexcept {
return alignOf<PlatSpec>(v[0]);
}
template<typename PlatSpec>
[[nodiscard]]
constexpr std::size_t alignOf(const ModelValueVector&) noexcept {
@ -722,56 +910,63 @@ constexpr std::size_t alignOf(const ModelValueVector&) noexcept {
template<typename PlatSpec>
[[nodiscard]]
constexpr std::size_t alignOf(const ModelValue &t) noexcept {
std::size_t size = 0;
std::size_t alignment = 0;
switch (t.type()) {
case ModelValue::Type::Bool:
size = PlatSpec::alignOf(t.get<bool>());
alignment = PlatSpec::alignOf(t.get<bool>());
break;
case ModelValue::Type::Undefined:
size = 1;
alignment = 1;
break;
case ModelValue::Type::UnsignedInteger8:
size = PlatSpec::alignOf(t.get<uint8_t>());
alignment = PlatSpec::alignOf(t.get<uint8_t>());
break;
case ModelValue::Type::UnsignedInteger16:
size = PlatSpec::alignOf(t.get<uint16_t>());
alignment = PlatSpec::alignOf(t.get<uint16_t>());
break;
case ModelValue::Type::UnsignedInteger32:
size = PlatSpec::alignOf(t.get<uint32_t>());
alignment = PlatSpec::alignOf(t.get<uint32_t>());
break;
case ModelValue::Type::UnsignedInteger64:
size = PlatSpec::alignOf(t.get<uint64_t>());
alignment = PlatSpec::alignOf(t.get<uint64_t>());
break;
case ModelValue::Type::SignedInteger8:
size = PlatSpec::alignOf(t.get<int8_t>());
alignment = PlatSpec::alignOf(t.get<int8_t>());
break;
case ModelValue::Type::SignedInteger16:
size = PlatSpec::alignOf(t.get<int16_t>());
alignment = PlatSpec::alignOf(t.get<int16_t>());
break;
case ModelValue::Type::SignedInteger32:
size = PlatSpec::alignOf(t.get<int32_t>());
alignment = PlatSpec::alignOf(t.get<int32_t>());
break;
case ModelValue::Type::SignedInteger64:
size = PlatSpec::alignOf(t.get<int64_t>());
alignment = PlatSpec::alignOf(t.get<int64_t>());
break;
case ModelValue::Type::String:
size = PlatSpec::alignOf(t.get<ox::String>());
alignment = alignOf<PlatSpec>(t.get<ox::String>());
break;
case ModelValue::Type::Object:
size = alignOf<PlatSpec>(t.get<ox::ModelObject>());
alignment = alignOf<PlatSpec>(t.get<ox::ModelObject>());
break;
case ModelValue::Type::Union:
size = alignOf<PlatSpec>(t.get<ox::ModelUnion>());
alignment = alignOf<PlatSpec>(t.get<ox::ModelUnion>());
break;
case ModelValue::Type::Vector:
size = alignOf<PlatSpec>(t.get<ox::ModelValueVector>());
alignment = alignOf<PlatSpec>(t.get<ox::ModelValueVector>());
break;
case ModelValue::Type::InlineArray:
{
auto &list = t.get<ox::ModelValueArray>();
alignment = alignOf<PlatSpec>(list[0]);
break;
}
}
return size;
return alignment;
}
constexpr Error model(auto *h, CommonPtrWith<ModelObject> auto *obj) noexcept {
oxReturnError(h->template setTypeInfo<ModelObject>(obj->typeName().c_str(), obj->typeVersion(), {}, obj->m_fieldsOrder.size()));
oxReturnError(h->template setTypeInfo<ModelObject>(
obj->typeName().c_str(), obj->typeVersion(), {}, obj->m_fieldsOrder.size()));
for (auto &f : obj->m_fieldsOrder) {
oxReturnError(h->field(f->name.c_str(), &f->value));
}
@ -779,7 +974,8 @@ constexpr Error model(auto *h, CommonPtrWith<ModelObject> auto *obj) noexcept {
}
constexpr Error model(auto *h, CommonPtrWith<ModelUnion> auto *obj) noexcept {
oxReturnError(h->template setTypeInfo<ModelUnion>(obj->typeName().c_str(), obj->typeVersion(), {}, obj->m_fieldsOrder.size()));
oxReturnError(h->template setTypeInfo<ModelUnion>(
obj->typeName().c_str(), obj->typeVersion(), {}, obj->m_fieldsOrder.size()));
for (auto &f : obj->m_fieldsOrder) {
oxReturnError(h->field(f->name.c_str(), &f->value));
}
@ -799,7 +995,7 @@ constexpr ModelValue::ModelValue(const ModelValue &other) noexcept {
case Type::SignedInteger16:
case Type::SignedInteger32:
case Type::SignedInteger64:
ox_memcpy(&m_data, &other.m_data, sizeof(m_data));
ox::memcpy(&m_data, &other.m_data, sizeof(m_data));
break;
case Type::String:
m_data.str = new String(other.get<String>());
@ -813,6 +1009,9 @@ constexpr ModelValue::ModelValue(const ModelValue &other) noexcept {
case Type::Vector:
m_data.vec = new ModelValueVector(*other.m_data.vec);
break;
case Type::InlineArray:
m_data.array = new ModelValueArray(*other.m_data.array);
break;
}
}
@ -829,8 +1028,8 @@ constexpr ModelValue::ModelValue(ModelValue &&other) noexcept {
case Type::SignedInteger16:
case Type::SignedInteger32:
case Type::SignedInteger64:
ox_memcpy(&m_data, &other.m_data, sizeof(m_data));
ox_memset(&other.m_data, 0, sizeof(m_data));
ox::memcpy(&m_data, &other.m_data, sizeof(m_data));
ox::memset(&other.m_data, 0, sizeof(m_data));
break;
case Type::String:
m_data.str = other.m_data.str;
@ -848,17 +1047,23 @@ constexpr ModelValue::ModelValue(ModelValue &&other) noexcept {
m_data.vec = other.m_data.vec;
other.m_data.vec = new ModelValueVector;
break;
case Type::InlineArray:
m_data.array = other.m_data.array;
other.m_data.array = new ModelValueArray();
break;
}
}
template<typename T>
constexpr ModelValue::ModelValue(const T &val) noexcept {
set(val);
constexpr ModelValue::ModelValue(const T &val) noexcept
requires(!ox::is_same_v<ox::remove_reference_t<T>, ModelValue>) {
std::ignore = set(val);
}
template<typename T>
constexpr ModelValue::ModelValue(T &&val) noexcept {
set(ox::forward(val));
constexpr ModelValue::ModelValue(T &&val) noexcept
requires(!ox::is_same_v<ox::remove_reference_t<T>, ModelValue>) {
std::ignore = set(ox::forward<T>(val));
}
constexpr ModelValue::~ModelValue() noexcept {
@ -869,12 +1074,24 @@ constexpr ModelValue::Type ModelValue::type() const noexcept {
return m_type;
}
constexpr Error ModelValue::setType(const DescriptorType *type, int subscriptLevels) noexcept {
constexpr Error ModelValue::setType(
const DescriptorType *type,
int subscriptLevels,
SubscriptStack const&subscriptStack) noexcept {
freeResources();
if (subscriptLevels) {
m_type = Type::Vector;
m_data.vec = new ModelValueVector;
return m_data.vec->setType(type, subscriptLevels - 1);
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->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));
}
return {};
} else if (type->typeName == types::Bool) {
m_type = Type::Bool;
} else if (type->typeName == types::BasicString ||
@ -917,7 +1134,8 @@ constexpr Error ModelValue::setType() noexcept {
constexpr auto type = getType<T>();
freeResources();
m_type = type;
// 2022.09.04: Clang retardedly requires initializing the union values directly, rather than using getValue<type>()
// 2022.09.04: Clang retardedly requires initializing the union values directly,
// rather than using getValue<type>()
if constexpr(type == Type::Object) {
m_data.obj = new ModelObject;
oxReturnError(m_data.obj->setType(type));
@ -959,7 +1177,7 @@ constexpr Error ModelValue::set(const T &v) noexcept {
}
auto &value = getValue<type>(*this);
if constexpr(type == Type::Vector || type == Type::Object ||
type == Type::Union || type == Type::String) {
type == Type::Union || type == Type::String || type == Type::InlineArray) {
safeDelete(&value);
}
value = v;
@ -974,10 +1192,10 @@ constexpr Error ModelValue::set(T &&v) noexcept {
}
auto &value = getValue<type>(*this);
if constexpr(type == Type::Vector || type == Type::Object ||
type == Type::Union || type == Type::String) {
type == Type::Union || type == Type::String || type == Type::InlineArray) {
safeDelete(&value);
}
value = ox::forward<T>(v);
value = std::move(v);
return OxError(0);
}
@ -1002,7 +1220,7 @@ constexpr ModelValue &ModelValue::operator=(const ModelValue &other) noexcept {
case Type::SignedInteger16:
case Type::SignedInteger32:
case Type::SignedInteger64:
ox_memcpy(&m_data, &other.m_data, sizeof(m_data));
ox::memcpy(&m_data, &other.m_data, sizeof(m_data));
break;
case Type::String:
m_data.str = new String(other.get<String>());
@ -1016,6 +1234,9 @@ constexpr ModelValue &ModelValue::operator=(const ModelValue &other) noexcept {
case Type::Vector:
m_data.vec = new ModelValueVector(*other.m_data.vec);
break;
case Type::InlineArray:
m_data.array = new ModelValueArray(*other.m_data.array);
break;
}
return *this;
}
@ -1037,8 +1258,8 @@ constexpr ModelValue &ModelValue::operator=(ModelValue &&other) noexcept {
case Type::SignedInteger16:
case Type::SignedInteger32:
case Type::SignedInteger64:
ox_memcpy(&m_data, &other.m_data, sizeof(m_data));
ox_memset(&other.m_data, 0, sizeof(m_data));
ox::memcpy(&m_data, &other.m_data, sizeof(m_data));
ox::memset(&other.m_data, 0, sizeof(m_data));
break;
case Type::String:
m_data.str = other.m_data.str;
@ -1056,6 +1277,10 @@ constexpr ModelValue &ModelValue::operator=(ModelValue &&other) noexcept {
m_data.vec = other.m_data.vec;
other.m_data.vec = new ModelValueVector;
break;
case Type::InlineArray:
m_data.array = other.m_data.array;
other.m_data.array = new ModelValueArray;
break;
}
return *this;
}
@ -1085,6 +1310,9 @@ constexpr void ModelValue::freeResources() noexcept {
case Type::Vector:
safeDelete(m_data.vec);
break;
case Type::InlineArray:
safeDelete(m_data.array);
break;
}
m_type = Type::Undefined;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -99,7 +99,7 @@ struct TypeInfoCatcher {
template<typename T>
constexpr int getModelTypeVersion(T *val) noexcept {
TypeInfoCatcher nc;
oxIgnoreError(model(&nc, val));
std::ignore = model(&nc, val);
return nc.version;
}
@ -122,7 +122,7 @@ consteval int requireModelTypeVersion() noexcept {
template<typename T, typename Str = const char*>
constexpr Str getModelTypeName(T *val) noexcept {
TypeNameCatcher nc;
oxIgnoreError(model(&nc, val));
std::ignore = model(&nc, val);
return nc.name;
}
@ -147,4 +147,19 @@ constexpr auto ModelTypeName_v = getModelTypeName<T, Str>();
template<typename T, typename Str = const char*>
constexpr auto ModelTypeVersion_v = requireModelTypeVersion<T>();
template<typename T, typename Str = const char*>
constexpr auto ModelTypeVersionStr_v = [] {
constexpr auto version = ModelTypeVersion_v<T>;
constexpr auto versionStr = ox::sfmt("{}", version);
return ox::IString<versionStr.len()>{versionStr};
};
template<typename T>
constexpr auto ModelTypeId_v = [] {
constexpr auto name = ModelTypeName_v<T, ox::StringView>;
constexpr auto version = ModelTypeVersion_v<T>;
constexpr auto versionStr = ox::sfmt<ox::IString<19>>("{}", version);
return ox::sfmt<ox::IString<name.len() + versionStr.len() + 1>>("{};{}", name, versionStr);
}();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -21,7 +21,7 @@
#endif
#include <ox/std/array.hpp>
#include <ox/std/bstring.hpp>
#include <ox/std/istring.hpp>
#include <ox/std/string.hpp>
#include <ox/std/strops.hpp>
#include <ox/std/types.hpp>
@ -131,7 +131,12 @@ template<typename T, std::size_t sz>
constexpr bool isBareArray_v<T[sz]> = true;
template<typename T>
constexpr bool isArray_v = false;
consteval bool isArray(T*) noexcept {
return false;
}
template<typename T>
constexpr bool isArray_v = isArray(static_cast<T*>(nullptr));
template<typename T>
constexpr bool isArray_v<T[]> = true;
@ -142,6 +147,16 @@ constexpr bool isArray_v<T[sz]> = true;
template<typename T, std::size_t sz>
constexpr bool isArray_v<Array<T, sz>> = true;
template<typename T, std::size_t sz>
consteval bool isArray(T[sz]) noexcept {
return true;
}
template<typename T, std::size_t sz>
consteval bool isArray(Array<T, sz>) noexcept {
return true;
}
template<typename T>
constexpr bool isSmartPtr_v = false;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
@ -64,7 +64,7 @@ constexpr Error DataWalker<Reader, T>::read(const DescriptorField &f, Reader *rd
template<typename Reader, typename T>
constexpr void DataWalker<Reader, T>::pushNamePath(const FieldName &fn) noexcept {
m_path.push_back(fn);
m_path.emplace_back(fn);
}
template<typename Reader, typename T>

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -15,7 +15,7 @@ namespace ox {
OrganicClawReader::OrganicClawReader(const uint8_t *buff, std::size_t buffSize) {
auto json = reinterpret_cast<const char*>(buff);
auto jsonLen = ox_strnlen(json, buffSize);
auto jsonLen = ox::strnlen(json, buffSize);
Json::CharReaderBuilder parserBuilder;
auto parser = std::unique_ptr<Json::CharReader>(parserBuilder.newCharReader());
if (!parser->parse(json, json + jsonLen, &m_json, nullptr)) {
@ -198,7 +198,7 @@ Error OrganicClawReader::fieldCString(const char *key, char *val, std::size_t bu
if (strSize >= buffLen) {
err = OxError(2, "String size exceeds capacity of destination");
} else {
ox_memcpy(data, begin, static_cast<std::size_t>(strSize));
ox::memcpy(data, begin, static_cast<std::size_t>(strSize));
data[strSize] = 0;
}
} else {
@ -224,7 +224,7 @@ Error OrganicClawReader::fieldCString(const char *key, char **val) noexcept {
const auto strSize = static_cast<std::size_t>(end - begin);
safeDelete(*val);
*val = new char[strSize + 1];
ox_memcpy(data, begin, static_cast<std::size_t>(strSize));
ox::memcpy(data, begin, static_cast<std::size_t>(strSize));
data[strSize] = 0;
} else {
err = OxError(1, "Type mismatch");
@ -242,7 +242,7 @@ Error OrganicClawReader::fieldCString(const char *key, char **val, std::size_t b
if (jv.empty()) {
auto data = val;
if (data) {
data[0] = 0;
data[0] = nullptr;
}
} else if (jv.isString()) {
jv.getString(&begin, &end);
@ -252,8 +252,8 @@ Error OrganicClawReader::fieldCString(const char *key, char **val, std::size_t b
safeDelete(*val);
*val = new char[strSize + 1];
}
ox_memcpy(data, begin, static_cast<std::size_t>(strSize));
data[strSize] = 0;
ox::memcpy(data, begin, static_cast<std::size_t>(strSize));
data[strSize] = nullptr;
} else {
err = OxError(1, "Type mismatch");
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -70,7 +70,7 @@ class OrganicClawReader {
Error field(const char *key, BasicString<L> *val) noexcept;
template<std::size_t L>
Error field(const char *key, BString<L> *val) noexcept;
Error field(const char *key, IString<L> *val) noexcept;
Error fieldCString(const char *key, char *val, std::size_t buffLen) noexcept;
@ -206,7 +206,7 @@ Error OrganicClawReader::field(const char *key, BasicString<L> *val) noexcept {
}
template<std::size_t L>
Error OrganicClawReader::field(const char *key, BString<L> *val) noexcept {
Error OrganicClawReader::field(const char *key, IString<L> *val) noexcept {
return fieldCString(key, val->data(), val->cap());
}
@ -274,7 +274,7 @@ Result<T> readOC(const char *json, std::size_t jsonLen) noexcept {
template<typename T>
Result<T> readOC(const char *json) noexcept {
return readOC<T>(json, ox_strlen(json));
return readOC<T>(json, ox::strlen(json));
}
template<typename T>

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -35,7 +35,7 @@ struct TestStructNest {
static constexpr auto TypeVersion = 1;
bool Bool = false;
uint32_t Int = 0;
ox::BString<32> String = "";
ox::IString<32> String = "";
};
struct TestStruct {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -27,7 +27,7 @@ Error OrganicClawWriter::fieldCString(const char *key, const char *const*val, in
}
Error OrganicClawWriter::fieldCString(const char *key, const char *const*val) noexcept {
return fieldCString(key, const_cast<const char**>(val), static_cast<int>(ox_strlen(val)));
return fieldCString(key, const_cast<const char**>(val), static_cast<int>(ox::strlen(val)));
}
Error OrganicClawWriter::field(const char *key, const UUID *uuid) noexcept {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -27,7 +27,7 @@ class OrganicClawWriter {
friend Result<Buffer> writeOC(const auto &val) noexcept;
protected:
Json::Value m_json;
Json::Value m_json{Json::Value(Json::objectValue)};
Json::ArrayIndex m_fieldIt = 0;
int m_unionIdx = -1;
@ -132,7 +132,7 @@ class OrganicClawWriter {
}
template<std::size_t L>
Error field(char const*key, BString<L> const*val) noexcept {
Error field(char const*key, IString<L> const*val) noexcept {
if (targetValid() && val->len()) {
value(key) = val->c_str();
}
@ -215,7 +215,7 @@ Error OrganicClawWriter::field(const char *key, const T *val) noexcept {
OrganicClawWriter w;
ModelHandlerInterface<OrganicClawWriter, OpType::Write> handler{&w};
oxReturnError(model(&handler, val));
if (!w.m_json.isNull()) {
if (!w.m_json.empty() || m_json.isArray()) {
value(key) = w.m_json;
}
}

View File

@ -1,5 +1,9 @@
/*
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once

View File

@ -1,10 +1,15 @@
/*
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
#include <ox/std/serialize.hpp>
#include <ox/std/string.hpp>
#include <ox/std/typetraits.hpp>
#include "alignmentcatcher.hpp"
@ -47,7 +52,7 @@ constexpr std::size_t alignOf(const T &v) noexcept {
typename PlatSpec::PtrType p = 0;
return PlatSpec::alignOf(p);
} else {
AlignmentCatcher<NativePlatSpec> c;
AlignmentCatcher<PlatSpec> c;
oxAssert(model(c.interface(), &v), "Could not get alignment for type");
return c.biggestAlignment;
}

View File

@ -1,5 +1,9 @@
/*
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include "preloader.hpp"

View File

@ -1,5 +1,9 @@
/*
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
@ -10,10 +14,12 @@
#include <ox/std/error.hpp>
#include <ox/std/memops.hpp>
#include <ox/std/memory.hpp>
#include <ox/std/string.hpp>
#include <ox/std/types.hpp>
#include <ox/std/typetraits.hpp>
#include <ox/std/units.hpp>
#include <ox/model/modelhandleradaptor.hpp>
#include <ox/model/modelvalue.hpp>
#include "platspecs.hpp"
@ -58,6 +64,7 @@ class Preloader: public ModelHandlerBase<Preloader<PlatSpec>, OpType::Reflect> {
restore(pRestore), seekdir(pSeekdir) {}
};
ox::Vector<AllocStackItem, 8> m_allocStack;
ox::Vector<size_t> m_allocStart{};
constexpr Preloader() noexcept: m_writer(&m_buff) {}
@ -101,9 +108,9 @@ class Preloader: public ModelHandlerBase<Preloader<PlatSpec>, OpType::Reflect> {
template<typename T>
constexpr ox::Error field(CRStringView, const T **val, std::size_t cnt) noexcept;
constexpr ox::Result<std::size_t> startAlloc(std::size_t sz) noexcept;
constexpr ox::Result<std::size_t> startAlloc(size_t sz, size_t align) noexcept;
constexpr ox::Result<std::size_t> startAlloc(std::size_t sz, std::size_t restore) noexcept;
constexpr ox::Result<std::size_t> startAlloc(size_t sz, size_t align, std::size_t restore) noexcept;
constexpr ox::Error endAlloc() noexcept;
@ -125,6 +132,8 @@ class Preloader: public ModelHandlerBase<Preloader<PlatSpec>, OpType::Reflect> {
constexpr ox::Error fieldVector(CRStringView, const auto *val, ox::VectorMemMap<PlatSpec> vecVal) noexcept;
constexpr ox::Error fieldArray(CRStringView name, ox::ModelValueArray const*val) noexcept;
constexpr bool unionCheckAndIt() noexcept;
};
@ -165,15 +174,19 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView name, const T *val)
}
oxReturnError(pad(val));
if constexpr(ox::is_integral_v<T>) {
//oxDebugf("Preloader::field(name, val): {}", name);
return ox::serialize(&m_writer, PlatSpec::correctEndianness(*val));
return ox::serialize(m_writer, PlatSpec::correctEndianness(*val));
} else if constexpr(ox::is_pointer_v<T>) {
const PtrType a = startAlloc(sizeOf<PlatSpec>(*val), m_writer.tellp()) + PlatSpec::RomStart;
const PtrType a = startAlloc(sizeOf<PlatSpec>(val), alignOf<PlatSpec>(*val), m_writer.tellp()) + PlatSpec::RomStart;
oxReturnError(field(name, *val));
oxReturnError(endAlloc());
return ox::serialize(&m_writer, PlatSpec::correctEndianness(a));
} else if constexpr(ox::isVector_v<T> || ox::is_same_v<T, ox::ModelValueVector>) {
return ox::serialize(m_writer, PlatSpec::correctEndianness(a));
} else if constexpr(ox::isVector_v<T>) {
return fieldVector(name, val);
} else if constexpr(ox::is_same_v<T, ox::ModelValueVector>) {
val->types();
return fieldVector(name, val);
} else if constexpr(ox::is_same_v<T, ox::ModelValueArray>) {
return fieldArray(name, val);
} else {
m_unionIdx.emplace_back(-1);
const auto out = preload<PlatSpec, T>(this, val);
@ -199,7 +212,7 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView, const ox::BasicStri
const auto restore = m_writer.tellp();
std::size_t a = 0;
if (sz && sz >= SmallStringSize) {
oxReturnError(ox::allocate(&m_writer, sz).moveTo(a));
oxReturnError(ox::allocate(m_writer, sz).moveTo(a));
} else {
a = restore;
}
@ -207,7 +220,7 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView, const ox::BasicStri
oxReturnError(m_writer.seekp(a));
oxReturnError(m_writer.write(val->data(), sz));
oxReturnError(m_writer.seekp(restore));
oxReturnError(serialize(&m_writer, vecVal));
oxReturnError(serialize(m_writer, vecVal));
m_ptrs.emplace_back(restore + offsetof(VecMap, items), vecVal.items);
return {};
}
@ -218,6 +231,7 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView name, const ox::Arra
if (!unionCheckAndIt()) {
return {};
}
oxReturnError(pad(&(*val)[0]));
// serialize the Array elements
if constexpr(sz) {
m_unionIdx.emplace_back(-1);
@ -235,28 +249,40 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView, const T **val, std:
if (!unionCheckAndIt()) {
return {};
}
// serialize the array
m_unionIdx.emplace_back(-1);
for (std::size_t i = 0; i < cnt; ++i) {
oxReturnError(this->interface()->field(nullptr, &val[i]));
if (cnt) {
oxReturnError(pad(*val));
// serialize the array
m_unionIdx.emplace_back(-1);
for (std::size_t i = 0; i < cnt; ++i) {
oxReturnError(this->interface()->field(nullptr, &val[i]));
}
m_unionIdx.pop_back();
}
m_unionIdx.pop_back();
return {};
}
template<typename PlatSpec>
constexpr ox::Result<std::size_t> Preloader<PlatSpec>::startAlloc(std::size_t sz) noexcept {
oxRequire(a, ox::allocate(&m_writer, sz));
constexpr ox::Result<std::size_t> Preloader<PlatSpec>::startAlloc(size_t sz, size_t align) noexcept {
m_allocStack.emplace_back(static_cast<typename PlatSpec::PtrType>(m_writer.tellp()));
oxReturnError(m_writer.seekp(0, ox::ios_base::end));
const auto padding = m_writer.tellp() % align;
oxRequireM(a, ox::allocate(m_writer, sz + padding));
a += padding;
oxReturnError(m_writer.seekp(a));
m_allocStart.push_back(a);
return a;
}
template<typename PlatSpec>
constexpr ox::Result<std::size_t> Preloader<PlatSpec>::startAlloc(std::size_t sz, std::size_t restore) noexcept {
oxRequire(a, ox::allocate(&m_writer, sz));
constexpr ox::Result<std::size_t> Preloader<PlatSpec>::startAlloc(
std::size_t sz, size_t align, std::size_t restore) noexcept {
m_allocStack.emplace_back(restore, ox::ios_base::beg);
oxReturnError(m_writer.seekp(0, ox::ios_base::end));
const auto padding = m_writer.tellp() % align;
oxRequireM(a, ox::allocate(m_writer, sz + padding));
a += padding;
oxReturnError(m_writer.seekp(a));
m_allocStart.push_back(a);
return a;
}
@ -268,6 +294,7 @@ constexpr ox::Error Preloader<PlatSpec>::endAlloc() noexcept {
const auto &si = *m_allocStack.back().unwrap();
oxReturnError(m_writer.seekp(static_cast<ox::ssize_t>(si.restore), si.seekdir));
m_allocStack.pop_back();
m_allocStart.pop_back();
return {};
}
@ -275,8 +302,9 @@ template<typename PlatSpec>
constexpr ox::Error Preloader<PlatSpec>::offsetPtrs(std::size_t offset) noexcept {
for (const auto &p : m_ptrs) {
oxReturnError(m_writer.seekp(p.loc));
const auto val = PlatSpec::template correctEndianness<typename PlatSpec::PtrType>(static_cast<typename PlatSpec::PtrType>(p.value + offset));
oxReturnError(ox::serialize(&m_writer, val));
const auto val = PlatSpec::template correctEndianness<typename PlatSpec::PtrType>(
static_cast<typename PlatSpec::PtrType>(p.value + offset));
oxReturnError(ox::serialize(m_writer, val));
}
oxReturnError(m_writer.seekp(0, ox::ios_base::end));
return {};
@ -295,11 +323,12 @@ constexpr ox::Error Preloader<PlatSpec>::pad(const T *v) noexcept {
}
template<typename PlatSpec>
constexpr ox::Error Preloader<PlatSpec>::fieldVector(CRStringView name, const ox::ModelValueVector *val) noexcept {
constexpr ox::Error Preloader<PlatSpec>::fieldVector(
CRStringView name, const ox::ModelValueVector *val) noexcept {
// serialize the Vector
ox::VectorMemMap<PlatSpec> vecVal{
.size = PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(val->size())),
.cap = PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(val->size())),
.size = PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(val->size())),
.cap = PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(val->size())),
};
return fieldVector(name, val, vecVal);
}
@ -327,7 +356,11 @@ constexpr ox::Error Preloader<PlatSpec>::fieldVector(
// serialize the Vector elements
if (val->size()) {
const auto sz = sizeOf<PlatSpec>(&(*val)[0]) * val->size();
oxRequire(p, ox::allocate(&m_writer, sz));
const auto align = alignOf<PlatSpec>((*val)[0]);
oxReturnError(m_writer.seekp(0, ox::ios_base::end));
const auto padding = m_writer.tellp() % align;
oxRequireM(p, ox::allocate(m_writer, sz + padding));
p += padding;
oxReturnError(m_writer.seekp(p));
m_unionIdx.emplace_back(-1);
for (std::size_t i = 0; i < val->size(); ++i) {
@ -341,11 +374,22 @@ constexpr ox::Error Preloader<PlatSpec>::fieldVector(
vecVal.items = 0;
}
// serialize the Vector
oxReturnError(serialize(&m_writer, vecVal));
oxReturnError(serialize(m_writer, vecVal));
m_ptrs.emplace_back(m_writer.tellp() - PtrSize, vecVal.items);
return {};
}
template<typename PlatSpec>
constexpr ox::Error Preloader<PlatSpec>::fieldArray(CRStringView, ox::ModelValueArray const*val) noexcept {
oxDebugf("array size: {}", val->size());
oxDebugf("array sizeOf: {}", sizeOf<PlatSpec>(val));
oxReturnError(pad(&(*val)[0]));
for (auto const&v : *val) {
oxReturnError(this->interface()->field({}, &v));
}
return {};
}
template<typename PlatSpec>
constexpr bool Preloader<PlatSpec>::unionCheckAndIt() noexcept {
auto &u = *m_unionIdx.back().unwrap();

View File

@ -1,5 +1,9 @@
/*
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once

View File

@ -1,5 +1,9 @@
/*
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once

View File

@ -81,6 +81,7 @@ target_link_libraries(
OxStd PUBLIC
$<$<CXX_COMPILER_ID:GNU>:gcc>
OxTraceHook
CityHash
)
install(
@ -90,7 +91,7 @@ install(
assert.hpp
bit.hpp
bounds.hpp
bstring.hpp
istring.hpp
buffer.hpp
buildinfo.hpp
byteswap.hpp
@ -103,8 +104,10 @@ install(
hardware.hpp
hashmap.hpp
heapmgr.hpp
ignore.hpp
iterator.hpp
math.hpp
maybeview.hpp
memops.hpp
memory.hpp
new.hpp

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once

109
deps/ox/src/ox/std/anyptr.hpp vendored Normal file
View File

@ -0,0 +1,109 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
#include "assert.hpp"
#include "array.hpp"
#include "def.hpp"
#include "span.hpp"
namespace ox {
class AnyPtr {
private:
struct WrapBase {
virtual constexpr ~WrapBase() = default;
virtual constexpr WrapBase *copyTo(ox::Span<char> s) noexcept = 0;
virtual constexpr operator bool() const noexcept = 0;
};
template<typename T>
struct Wrap: public WrapBase {
T *data{};
constexpr Wrap(T *pData) noexcept: data(pData) {
}
constexpr WrapBase *copyTo(ox::Span<char> s) noexcept override {
oxAssert(s.size() >= sizeof(Wrap), "too small buffer");
if (std::is_constant_evaluated()) {
return new Wrap(data);
} else {
return new(s.data()) Wrap(data);
}
}
constexpr operator bool() const noexcept override {
return data != nullptr;
}
};
WrapBase *m_wrapPtr{};
ox::Array<char, sizeof(Wrap<void*>)> m_wrapData;
public:
constexpr AnyPtr() noexcept = default;
template<typename T>
constexpr AnyPtr(T *ptr) noexcept {
if (std::is_constant_evaluated()) {
m_wrapPtr = new Wrap(ptr);
} else {
m_wrapPtr = new(m_wrapData.data()) Wrap(ptr);
}
}
constexpr AnyPtr(AnyPtr const&other) noexcept {
if (other) {
m_wrapPtr = other.m_wrapPtr->copyTo(m_wrapData);
}
}
constexpr ~AnyPtr() noexcept {
if (std::is_constant_evaluated()) {
ox::safeDelete(m_wrapPtr);
}
}
template<typename T>
constexpr AnyPtr &operator=(T *ptr) noexcept {
if (std::is_constant_evaluated()) {
ox::safeDelete(m_wrapPtr);
m_wrapPtr = new Wrap(ptr);
} else {
m_wrapPtr = new(m_wrapData.data()) Wrap(ptr);
}
return *this;
}
constexpr AnyPtr &operator=(AnyPtr const&ptr) noexcept {
if (this != &ptr) {
if (ptr) {
ox::safeDelete(m_wrapPtr);
m_wrapPtr = ptr.m_wrapPtr->copyTo(m_wrapData);
} else {
m_wrapPtr = nullptr;
}
}
return *this;
}
constexpr operator bool() const noexcept {
return m_wrapPtr && *m_wrapPtr;
}
template<typename T>
[[nodiscard]]
constexpr T *get() const noexcept {
#ifdef OX_BARE_METAL
return static_cast<Wrap<T>*>(m_wrapPtr)->data;
#else
return dynamic_cast<Wrap<T>*>(m_wrapPtr)->data;
#endif
}
};
}

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
@ -13,7 +13,6 @@
#include "initializerlist.hpp"
#include "iterator.hpp"
#include "math.hpp"
#include "memory.hpp"
#include "new.hpp"
#include "types.hpp"
#include "utility.hpp"

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include "stacktrace.hpp"

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -131,7 +131,7 @@ class BaseStringView {
constexpr explicit BaseStringView(std::nullptr_t) noexcept {}
constexpr explicit BaseStringView(const char *str) noexcept: m_str(str), m_len(str ? ox_strlen(str) : 0) {}
constexpr explicit BaseStringView(const char *str) noexcept: m_str(str), m_len(str ? ox::strlen(str) : 0) {}
constexpr explicit BaseStringView(const char *str, std::size_t len) noexcept: m_str(str), m_len(len) {}

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include "bit.hpp"

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
@ -34,7 +34,7 @@ namespace ox {
template<typename To, typename From>
constexpr typename enable_if<sizeof(To) == sizeof(From), To>::type cbit_cast(From src) noexcept {
To dst = {};
ox_memcpy(&dst, &src, sizeof(src));
ox::memcpy(&dst, &src, sizeof(src));
return dst;
}

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2023 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once

View File

@ -1,281 +0,0 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#pragma once
#include "memops.hpp"
#include "stringview.hpp"
#include "strops.hpp"
#include "typetraits.hpp"
namespace ox {
// Bounded String
template<std::size_t buffLen>
class BString {
private:
char m_buff[buffLen + 1];
public:
constexpr BString() noexcept;
constexpr BString(StringView str) noexcept;
constexpr BString(const char *str) noexcept;
constexpr BString &operator=(CRStringView str) noexcept;
constexpr BString &operator=(const char *str) noexcept;
constexpr BString &operator=(char *str) noexcept;
constexpr BString &operator=(Integer_c auto i) noexcept;
constexpr BString &operator+=(const char *str) noexcept;
constexpr BString &operator+=(char *str) noexcept;
constexpr BString &operator+=(Integer_c auto i) noexcept;
constexpr BString &operator+=(StringView s) noexcept;
constexpr BString operator+(const char *str) const noexcept;
constexpr BString operator+(char *str) const noexcept;
constexpr BString operator+(Integer_c auto i) const noexcept;
constexpr bool operator==(const char *other) const noexcept;
constexpr bool operator==(const OxString_c auto &other) const noexcept;
constexpr bool operator!=(const char *other) const noexcept;
constexpr bool operator!=(const OxString_c auto &other) noexcept;
constexpr char operator[](std::size_t i) const noexcept;
constexpr char &operator[](std::size_t i) noexcept;
constexpr Error append(const char *str, std::size_t strLen) noexcept;
[[nodiscard]]
constexpr const char *data() const noexcept;
[[nodiscard]]
constexpr char *data() noexcept;
[[nodiscard]]
constexpr const char *c_str() const noexcept;
/**
* Returns the number of characters in this string.
*/
[[nodiscard]]
constexpr std::size_t len() const noexcept;
/**
* Returns the number of bytes used for this string.
*/
[[nodiscard]]
constexpr std::size_t bytes() const noexcept;
/**
* Returns the capacity of bytes for this string.
*/
[[nodiscard]]
constexpr std::size_t cap() const noexcept;
};
template<std::size_t size>
constexpr BString<size>::BString() noexcept: m_buff{{0}} {
}
template<std::size_t size>
constexpr BString<size>::BString(StringView str) noexcept: m_buff{{0}} {
operator=(str);
}
template<std::size_t size>
constexpr BString<size>::BString(const char *str) noexcept: m_buff{{0}} {
operator=(str);
}
template<std::size_t size>
constexpr BString<size> &BString<size>::operator=(Integer_c auto i) noexcept {
char str[65] = {};
ox_itoa(i, str);
return this->operator=(str);
}
template<std::size_t size>
constexpr BString<size> &BString<size>::operator=(ox::CRStringView str) noexcept {
std::size_t strLen = str.bytes() + 1;
if (cap() < strLen) {
strLen = cap();
}
ox_memcpy(m_buff, str.data(), strLen);
// make sure last element is a null terminator
m_buff[strLen] = 0;
return *this;
}
template<std::size_t size>
constexpr BString<size> &BString<size>::operator=(const char *str) noexcept {
std::size_t strLen = ox_strlen(str) + 1;
if (cap() < strLen) {
strLen = cap();
}
ox_memcpy(m_buff, str, strLen);
// make sure last element is a null terminator
m_buff[cap()] = 0;
return *this;
}
template<std::size_t size>
constexpr BString<size> &BString<size>::operator=(char *str) noexcept {
return *this = static_cast<const char*>(str);
}
template<std::size_t size>
constexpr BString<size> &BString<size>::operator+=(const char *str) noexcept {
std::size_t strLen = ox_strlen(str) + 1;
oxIgnoreError(append(str, strLen));
return *this;
}
template<std::size_t size>
constexpr BString<size> &BString<size>::operator+=(char *str) noexcept {
return *this += static_cast<const char*>(str);
}
template<std::size_t size>
constexpr BString<size> &BString<size>::operator+=(Integer_c auto i) noexcept {
char str[65] = {};
ox_itoa(i, str);
return this->operator+=(str);
}
template<std::size_t size>
constexpr BString<size> &BString<size>::operator+=(StringView s) noexcept {
std::size_t strLen = s.bytes();
oxIgnoreError(append(s.data(), strLen));
return *this;
}
template<std::size_t size>
constexpr BString<size> BString<size>::operator+(const char *str) const noexcept {
auto out = *this;
std::size_t strLen = ox_strlen(str) + 1;
oxIgnoreError(out.append(str, strLen));
return out;
}
template<std::size_t size>
constexpr BString<size> BString<size>::operator+(char *str) const noexcept {
return *this + static_cast<const char*>(str);
}
template<std::size_t size>
constexpr BString<size> BString<size>::operator+(Integer_c auto i) const noexcept {
char str[65] = {};
ox_itoa(i, str);
return this->operator+(str);
}
template<std::size_t buffLen>
constexpr bool BString<buffLen>::operator==(const char *other) const noexcept {
return ox::StringView(*this) == other;
}
template<std::size_t buffLen>
constexpr bool BString<buffLen>::operator==(const OxString_c auto &other) const noexcept {
return ox::StringView(*this) == ox::StringView(other);
}
template<std::size_t buffLen>
constexpr bool BString<buffLen>::operator!=(const char *other) const noexcept {
return !operator==(other);
}
template<std::size_t buffLen>
constexpr bool BString<buffLen>::operator!=(const OxString_c auto &other) noexcept {
return !operator==(other);
}
template<std::size_t buffLen>
constexpr char BString<buffLen>::operator[](std::size_t i) const noexcept {
return m_buff[i];
}
template<std::size_t buffLen>
constexpr char &BString<buffLen>::operator[](std::size_t i) noexcept {
return m_buff[i];
}
template<std::size_t buffLen>
constexpr Error BString<buffLen>::append(const char *str, std::size_t strLen) noexcept {
Error err;
auto currentLen = len();
if (cap() < currentLen + strLen + 1) {
strLen = cap() - currentLen;
err = OxError(1, "Insufficient space for full string");
}
ox_strncpy(m_buff + currentLen, str, strLen);
// make sure last element is a null terminator
m_buff[currentLen + strLen] = 0;
return err;
}
template<std::size_t buffLen>
constexpr const char *BString<buffLen>::data() const noexcept {
return static_cast<const char*>(m_buff);
}
template<std::size_t buffLen>
constexpr char *BString<buffLen>::data() noexcept {
return static_cast<char*>(m_buff);
}
template<std::size_t buffLen>
constexpr const char *BString<buffLen>::c_str() const noexcept {
return static_cast<const char*>(m_buff);
}
template<std::size_t buffLen>
constexpr std::size_t BString<buffLen>::len() const noexcept {
std::size_t length = 0;
for (std::size_t i = 0; i < buffLen; i++) {
uint8_t b = static_cast<uint8_t>(m_buff[i]);
if (b) {
const auto asciiChar = (b & 128) == 0;
const auto utf8Char = (b & (256 << 6)) == (256 << 6);
if (asciiChar || utf8Char) {
length++;
}
} else {
break;
}
}
return length;
}
template<std::size_t buffLen>
constexpr std::size_t BString<buffLen>::bytes() const noexcept {
std::size_t i = 0;
for (i = 0; i < buffLen && m_buff[i]; i++);
return i + 1; // add one for null terminator
}
template<std::size_t buffLen>
constexpr std::size_t BString<buffLen>::cap() const noexcept {
return buffLen;
}
}

View File

@ -1,9 +1,9 @@
/*
* Copyright 2015 - 2022 gary@drinkingtea.net
* Copyright 2015 - 2024 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include "error.hpp"

Some files were not shown because too many files have changed in this diff Show More