Compare commits
4 Commits
cd60c4abaf
...
09d840cfd0
Author | SHA1 | Date | |
---|---|---|---|
09d840cfd0 | |||
aeb1ef3b12 | |||
b66f61c217 | |||
b089bf460b |
12
deps/ox/src/ox/std/array.hpp
vendored
12
deps/ox/src/ox/std/array.hpp
vendored
@ -137,12 +137,16 @@ constexpr Array<T, ArraySize>::Array(Array &&other) noexcept {
|
|||||||
|
|
||||||
template<typename T, std::size_t ArraySize>
|
template<typename T, std::size_t ArraySize>
|
||||||
constexpr bool Array<T, ArraySize>::operator==(const Array &other) const {
|
constexpr bool Array<T, ArraySize>::operator==(const Array &other) const {
|
||||||
for (std::size_t i = 0; i < ArraySize; i++) {
|
if (std::is_constant_evaluated()) {
|
||||||
if (!(m_items[i] == other.m_items[i])) {
|
for (std::size_t i = 0; i < ArraySize; i++) {
|
||||||
return false;
|
if (!(m_items[i] == other.m_items[i])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return memcmp(this, &other, sizeof(*this)) == 0;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, std::size_t ArraySize>
|
template<typename T, std::size_t ArraySize>
|
||||||
|
18
deps/ox/src/ox/std/smallmap.hpp
vendored
18
deps/ox/src/ox/std/smallmap.hpp
vendored
@ -29,11 +29,12 @@ class SmallMap {
|
|||||||
K key = {};
|
K key = {};
|
||||||
T value{};
|
T value{};
|
||||||
};
|
};
|
||||||
|
using PairVector = Vector<Pair>;
|
||||||
Vector<K> m_keys;
|
Vector<K> m_keys;
|
||||||
Vector<Pair> m_pairs;
|
PairVector m_pairs;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit constexpr SmallMap(std::size_t size = 127);
|
constexpr SmallMap() = default;
|
||||||
|
|
||||||
constexpr SmallMap(SmallMap const&other);
|
constexpr SmallMap(SmallMap const&other);
|
||||||
|
|
||||||
@ -68,17 +69,13 @@ class SmallMap {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
template<typename KK>
|
template<typename KK>
|
||||||
constexpr Pair const&access(Vector<Pair> const&pairs, KK const&key, bool &isNew) const;
|
constexpr Pair const&access(PairVector const&pairs, KK const&key, bool &isNew) const;
|
||||||
|
|
||||||
template<typename KK>
|
template<typename KK>
|
||||||
constexpr Pair &access(Vector<Pair> &pairs, KK const&key, bool &isNew);
|
constexpr Pair &access(PairVector &pairs, KK const&key, bool &isNew);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename K, typename T>
|
|
||||||
constexpr SmallMap<K, T>::SmallMap(std::size_t size): m_pairs(size) {
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
constexpr SmallMap<K, T>::SmallMap(SmallMap<K, T> const&other) {
|
constexpr SmallMap<K, T>::SmallMap(SmallMap<K, T> const&other) {
|
||||||
m_pairs = other.m_pairs;
|
m_pairs = other.m_pairs;
|
||||||
@ -188,13 +185,12 @@ constexpr Vector<K> const&SmallMap<K, T>::keys() const noexcept {
|
|||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
constexpr void SmallMap<K, T>::clear() {
|
constexpr void SmallMap<K, T>::clear() {
|
||||||
m_pairs.clear();
|
m_pairs.clear();
|
||||||
m_pairs.resize(127);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
template<typename KK>
|
template<typename KK>
|
||||||
constexpr typename SmallMap<K, T>::Pair const&SmallMap<K, T>::access(
|
constexpr typename SmallMap<K, T>::Pair const&SmallMap<K, T>::access(
|
||||||
Vector<Pair> const&pairs, KK const&k, bool &isNew) const {
|
PairVector const&pairs, KK const&k, bool &isNew) const {
|
||||||
for (auto const&p : pairs) {
|
for (auto const&p : pairs) {
|
||||||
if (p.key == k) {
|
if (p.key == k) {
|
||||||
isNew = false;
|
isNew = false;
|
||||||
@ -209,7 +205,7 @@ constexpr typename SmallMap<K, T>::Pair const&SmallMap<K, T>::access(
|
|||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
template<typename KK>
|
template<typename KK>
|
||||||
constexpr typename SmallMap<K, T>::Pair &SmallMap<K, T>::access(
|
constexpr typename SmallMap<K, T>::Pair &SmallMap<K, T>::access(
|
||||||
Vector<Pair> &pairs, KK const&k, bool &isNew) {
|
PairVector &pairs, KK const&k, bool &isNew) {
|
||||||
for (auto &p : pairs) {
|
for (auto &p : pairs) {
|
||||||
if (p.key == k) {
|
if (p.key == k) {
|
||||||
isNew = false;
|
isNew = false;
|
||||||
|
4
deps/ox/src/ox/std/test/CMakeLists.txt
vendored
4
deps/ox/src/ox/std/test/CMakeLists.txt
vendored
@ -12,8 +12,10 @@ add_test("[ox/std] ox_memcmp HIJKLMN != ABCDEFG" ${CMAKE_RUNTIME_OUTPUT_DIRECTOR
|
|||||||
add_test("[ox/std] ox_memcmp ABCDEFG == ABCDEFG" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "ABCDEFG == ABCDEFG")
|
add_test("[ox/std] ox_memcmp ABCDEFG == ABCDEFG" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "ABCDEFG == ABCDEFG")
|
||||||
add_test("[ox/std] ox_memcmp ABCDEFGHI == ABCDEFG" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "ABCDEFGHI == ABCDEFG")
|
add_test("[ox/std] ox_memcmp ABCDEFGHI == ABCDEFG" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "ABCDEFGHI == ABCDEFG")
|
||||||
add_test("[ox/std] itoa" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "itoa")
|
add_test("[ox/std] itoa" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "itoa")
|
||||||
add_test("[ox/std] BString" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "BString")
|
add_test("[ox/std] IString" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "IString")
|
||||||
add_test("[ox/std] String" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "String")
|
add_test("[ox/std] String" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "String")
|
||||||
|
add_test("[ox/std] SmallMap" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "SmallMap")
|
||||||
|
add_test("[ox/std] SmallMap2" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "SmallMap2")
|
||||||
add_test("[ox/std] Vector" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "Vector")
|
add_test("[ox/std] Vector" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "Vector")
|
||||||
add_test("[ox/std] HashMap" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "HashMap")
|
add_test("[ox/std] HashMap" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "HashMap")
|
||||||
add_test("[ox/std] HeapMgr" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest malloc)
|
add_test("[ox/std] HeapMgr" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest malloc)
|
||||||
|
156
deps/ox/src/ox/std/test/tests.cpp
vendored
156
deps/ox/src/ox/std/test/tests.cpp
vendored
@ -6,13 +6,111 @@
|
|||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ox/std/def.hpp"
|
#if __has_include(<chrono>)
|
||||||
|
#include<chrono>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ox/std/def.hpp>
|
||||||
#undef NDEBUG
|
#undef NDEBUG
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <ox/std/uuid.hpp>
|
#include <ox/std/uuid.hpp>
|
||||||
#include <ox/std/std.hpp>
|
#include <ox/std/std.hpp>
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
static uint64_t nowMs() {
|
||||||
|
#if __has_include(<chrono>)
|
||||||
|
using namespace std::chrono;
|
||||||
|
return static_cast<uint64_t>(
|
||||||
|
duration_cast<milliseconds>(
|
||||||
|
system_clock::now().time_since_epoch()).count());
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Map = ox::SmallMap<ox::String, ox::UUID>>
|
||||||
|
uint64_t timeMapStrToUuid(int elemCnt, int lookups, uint64_t seed = 4321) noexcept {
|
||||||
|
ox::UUID::seedGenerator({1234, seed});
|
||||||
|
Map map;
|
||||||
|
// setup test map
|
||||||
|
for (int i = 0; i < elemCnt; ++i) {
|
||||||
|
auto const uuid = ox::UUID::generate().unwrap();
|
||||||
|
map[uuid.toString()] = uuid;
|
||||||
|
}
|
||||||
|
auto const keys = map.keys();
|
||||||
|
ox::Random rand;
|
||||||
|
// start
|
||||||
|
auto const startTime = nowMs();
|
||||||
|
for (int i = 0; i < lookups; ++i) {
|
||||||
|
auto const&k = keys[rand.gen() % keys.size()];
|
||||||
|
map[k];
|
||||||
|
}
|
||||||
|
return nowMs() - startTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Map = ox::SmallMap<ox::UUID, ox::String>>
|
||||||
|
uint64_t timeMapUuidToStr(int elemCnt, int lookups, uint64_t seed = 4321) noexcept {
|
||||||
|
ox::UUID::seedGenerator({1234, seed});
|
||||||
|
Map map;
|
||||||
|
// setup test map
|
||||||
|
for (int i = 0; i < elemCnt; ++i) {
|
||||||
|
auto const uuid = ox::UUID::generate().unwrap();
|
||||||
|
map[uuid] = uuid.toString();
|
||||||
|
}
|
||||||
|
auto const keys = map.keys();
|
||||||
|
ox::Random rand;
|
||||||
|
// start
|
||||||
|
auto const startTime = nowMs();
|
||||||
|
for (int i = 0; i < lookups; ++i) {
|
||||||
|
auto const&k = keys[rand.gen() % keys.size()];
|
||||||
|
oxExpect(map[k], k.toString());
|
||||||
|
}
|
||||||
|
return nowMs() - startTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ox::Error compareMaps(int lookupCnt = 1'000'000) {
|
||||||
|
auto const seed = nowMs();
|
||||||
|
uint64_t hashTime{};
|
||||||
|
uint64_t smallTime{};
|
||||||
|
int elemCnt = 1;
|
||||||
|
oxOut("UUIDStr to UUID:\n\n");
|
||||||
|
while (hashTime >= smallTime) {
|
||||||
|
smallTime = timeMapStrToUuid<ox::SmallMap<ox::UUIDStr, ox::UUID>>(elemCnt, lookupCnt, seed);
|
||||||
|
hashTime = timeMapStrToUuid<ox::HashMap<ox::UUIDStr, ox::UUID>>(elemCnt, lookupCnt, seed);
|
||||||
|
oxOutf(
|
||||||
|
"UUIDStr to UUID: elemCnt: {}, lookupCnt: {} - hash map time: {}ms, small map time: {}ms\n",
|
||||||
|
elemCnt, lookupCnt, hashTime, smallTime);
|
||||||
|
++elemCnt;
|
||||||
|
}
|
||||||
|
oxOut("\n\nString to UUID:\n\n");
|
||||||
|
hashTime = 0;
|
||||||
|
smallTime = 0;
|
||||||
|
elemCnt = 1;
|
||||||
|
while (hashTime >= smallTime) {
|
||||||
|
smallTime = timeMapStrToUuid<ox::SmallMap<ox::String, ox::UUID>>(elemCnt, lookupCnt, seed);
|
||||||
|
hashTime = timeMapStrToUuid<ox::HashMap<ox::String, ox::UUID>>(elemCnt, lookupCnt, seed);
|
||||||
|
oxOutf(
|
||||||
|
"String to UUID: elemCnt: {}, lookupCnt: {} - hash map time: {}ms, small map time: {}ms\n",
|
||||||
|
elemCnt, lookupCnt, hashTime, smallTime);
|
||||||
|
++elemCnt;
|
||||||
|
}
|
||||||
|
oxOut("\n\nUUID to UUIDStr:\n\n");
|
||||||
|
hashTime = 0;
|
||||||
|
smallTime = 0;
|
||||||
|
elemCnt = 1;
|
||||||
|
while (hashTime >= smallTime) {
|
||||||
|
smallTime = timeMapUuidToStr<ox::SmallMap<ox::UUID, ox::UUIDStr>>(elemCnt, lookupCnt, seed);
|
||||||
|
hashTime = timeMapUuidToStr<ox::HashMap<ox::UUID, ox::UUIDStr>>(elemCnt, lookupCnt, seed);
|
||||||
|
oxOutf(
|
||||||
|
"UUID to UUIDStr: elemCnt: {}, lookupCnt: {} - hash map time: {}ms, small map time: {}ms\n",
|
||||||
|
elemCnt, lookupCnt, hashTime, smallTime);
|
||||||
|
++elemCnt;
|
||||||
|
}
|
||||||
|
oxOut("\n");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
static std::map<ox::StringView, ox::Error(*)()> tests = {
|
static std::map<ox::StringView, ox::Error(*)()> tests = {
|
||||||
{
|
{
|
||||||
"malloc",
|
"malloc",
|
||||||
@ -23,6 +121,8 @@ static std::map<ox::StringView, ox::Error(*)()> tests = {
|
|||||||
auto a2 = static_cast<char*>(ox::heapmgr::malloc(5));
|
auto a2 = static_cast<char*>(ox::heapmgr::malloc(5));
|
||||||
oxAssert(a1 >= buff.front().unwrap() && a1 < buff.back().unwrap(), "malloc is broken");
|
oxAssert(a1 >= buff.front().unwrap() && a1 < buff.back().unwrap(), "malloc is broken");
|
||||||
oxAssert(a2 >= buff.front().unwrap() && a2 < buff.back().unwrap() && a2 > a1 + 5, "malloc is broken");
|
oxAssert(a2 >= buff.front().unwrap() && a2 < buff.back().unwrap() && a2 > a1 + 5, "malloc is broken");
|
||||||
|
ox::heapmgr::free(a1);
|
||||||
|
ox::heapmgr::free(a2);
|
||||||
return OxError(0);
|
return OxError(0);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -67,14 +167,14 @@ static std::map<ox::StringView, ox::Error(*)()> tests = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"BString",
|
"IString",
|
||||||
[]() {
|
[]() {
|
||||||
ox::IString<5> s;
|
ox::IString<5> s;
|
||||||
oxReturnError(s.append("A"));
|
oxReturnError(s.append("A"));
|
||||||
oxReturnError(s.append("B"));
|
oxReturnError(s.append("B"));
|
||||||
oxReturnError(s.append("9"));
|
oxReturnError(s.append("9"));
|
||||||
oxReturnError(s.append("C"));
|
oxReturnError(s.append("C"));
|
||||||
oxAssert(s == "AB9C", "BString append broken");
|
oxAssert(s == "AB9C", "IString append broken");
|
||||||
s = "asdf";
|
s = "asdf";
|
||||||
oxAssert(s == "asdf", "String assign broken");
|
oxAssert(s == "asdf", "String assign broken");
|
||||||
oxAssert(s != "aoeu", "String assign broken");
|
oxAssert(s != "aoeu", "String assign broken");
|
||||||
@ -134,10 +234,38 @@ static std::map<ox::StringView, ox::Error(*)()> tests = {
|
|||||||
return OxError(0);
|
return OxError(0);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"SmallMap",
|
||||||
|
[] {
|
||||||
|
ox::SmallMap<ox::String, ox::String> map;
|
||||||
|
map["asdf"] = "aoeu";
|
||||||
|
oxExpect(map["asdf"], "aoeu");
|
||||||
|
oxExpect(map.size(), 1u);
|
||||||
|
oxExpect(map["aoeu"], "");
|
||||||
|
oxExpect(map.size(), 2u);
|
||||||
|
return OxError(0);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"SmallMap2",
|
||||||
|
[] {
|
||||||
|
ox::SmallMap<ox::String, int> si;
|
||||||
|
si["asdf"] = 42;
|
||||||
|
si["aoeu"] = 100;
|
||||||
|
oxAssert(si["asdf"] == 42, "asdf != 42");
|
||||||
|
oxAssert(si["aoeu"] == 100, "aoeu != 100");
|
||||||
|
ox::SmallMap<int, int> ii;
|
||||||
|
ii[4] = 42;
|
||||||
|
ii[5] = 100;
|
||||||
|
oxAssert(ii[4] == 42, "4 != 42");
|
||||||
|
oxAssert(ii[5] == 100, "5 != 100");
|
||||||
|
return OxError(0);
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"HashMap",
|
"HashMap",
|
||||||
[] {
|
[] {
|
||||||
ox::HashMap<const char*, int> si;
|
ox::HashMap<ox::String, int> si;
|
||||||
si["asdf"] = 42;
|
si["asdf"] = 42;
|
||||||
si["aoeu"] = 100;
|
si["aoeu"] = 100;
|
||||||
oxAssert(si["asdf"] == 42, "asdf != 42");
|
oxAssert(si["asdf"] == 42, "asdf != 42");
|
||||||
@ -150,6 +278,26 @@ static std::map<ox::StringView, ox::Error(*)()> tests = {
|
|||||||
return OxError(0);
|
return OxError(0);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"TimeSmallMapMillion",
|
||||||
|
[] {
|
||||||
|
timeMapStrToUuid<ox::SmallMap<ox::String, ox::UUID>>(1'000, 1'000'000);
|
||||||
|
return ox::Error{};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"TimeHashMapMillion",
|
||||||
|
[] {
|
||||||
|
timeMapStrToUuid<ox::HashMap<ox::String, ox::UUID>>(1'000, 1'000'000);
|
||||||
|
return ox::Error{};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"CompareMaps",
|
||||||
|
[] {
|
||||||
|
return compareMaps();
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"Serialize-Int",
|
"Serialize-Int",
|
||||||
[] {
|
[] {
|
||||||
|
26
deps/ox/src/ox/std/uuid.hpp
vendored
26
deps/ox/src/ox/std/uuid.hpp
vendored
@ -8,9 +8,11 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "bit.hpp"
|
||||||
#include "ignore.hpp"
|
#include "ignore.hpp"
|
||||||
#include "istring.hpp"
|
#include "istring.hpp"
|
||||||
#include "buffer.hpp"
|
#include "buffer.hpp"
|
||||||
|
#include "hash.hpp"
|
||||||
#include "random.hpp"
|
#include "random.hpp"
|
||||||
#include "ranges.hpp"
|
#include "ranges.hpp"
|
||||||
#include "stringview.hpp"
|
#include "stringview.hpp"
|
||||||
@ -105,7 +107,7 @@ class UUID {
|
|||||||
static ox::Result<UUID> generate() noexcept;
|
static ox::Result<UUID> generate() noexcept;
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr auto value() const noexcept {
|
constexpr auto const&value() const noexcept {
|
||||||
return m_value;
|
return m_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,8 +120,8 @@ class UUID {
|
|||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
constexpr uint64_t zero = 0;
|
constexpr uint64_t zero = 0;
|
||||||
return ox::memcmp(&zero, m_value.data() + 0, 8) == 0
|
return memcmp(&zero, m_value.data() + 0, 8) == 0
|
||||||
&& ox::memcmp(&zero, m_value.data() + 8, 8) == 0;
|
&& memcmp(&zero, m_value.data() + 8, 8) == 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,6 +194,24 @@ class UUID {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct hash<ox::UUID> {
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr size_t operator()(ox::UUID v) const noexcept {
|
||||||
|
size_t out{};
|
||||||
|
if (std::is_constant_evaluated()) {
|
||||||
|
for (auto i = 0u; i < sizeof(out); ++i) {
|
||||||
|
out |= static_cast<size_t>(v.value()[i]) << (i * 8);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
memcpy(&out, &v, sizeof(out));
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr Error model(T *io, ox::CommonPtrWith<UUID> auto *obj) noexcept {
|
constexpr Error model(T *io, ox::CommonPtrWith<UUID> auto *obj) noexcept {
|
||||||
oxReturnError(io->template setTypeInfo<UUID>());
|
oxReturnError(io->template setTypeInfo<UUID>());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user