[ox] Overhaul serialization/model system and add ModelValue/ModelObject/ModelUnion variant system

This commit is contained in:
2022-06-21 21:43:49 -05:00
parent bc391b45fc
commit ca64f95be3
47 changed files with 2696 additions and 973 deletions

View File

@@ -3,7 +3,7 @@
*
* 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
@@ -46,21 +46,21 @@ class HashMap {
/**
* K is assumed to be a null terminated string.
*/
constexpr T &operator[](K key);
constexpr T &operator[](const K &key);
/**
* K is assumed to be a null terminated string.
*/
constexpr Result<T*> at(K key) noexcept;
constexpr Result<T*> at(const K &key) noexcept;
/**
* K is assumed to be a null terminated string.
*/
constexpr Result<const T*> at(K key) const noexcept;
constexpr Result<const T*> at(const K &key) const noexcept;
constexpr void erase(const K &key);
constexpr bool contains(K key) const noexcept;
constexpr bool contains(const K &key) const noexcept;
[[nodiscard]]
constexpr std::size_t size() const noexcept;
@@ -68,6 +68,8 @@ class HashMap {
[[nodiscard]]
constexpr const Vector<K> &keys() const noexcept;
constexpr void clear();
private:
constexpr void expand();
@@ -79,14 +81,12 @@ class HashMap {
/**
* K is assumed to be a null terminated string.
*/
constexpr Pair *const&access(const Vector<Pair*> &pairs, K key) const;
constexpr Pair *const&access(const Vector<Pair*> &pairs, const K &key) const;
/**
* K is assumed to be a null terminated string.
*/
constexpr Pair *&access(Vector<Pair*> &pairs, K key);
constexpr void clear();
constexpr Pair *&access(Vector<Pair*> &pairs, const K &key);
};
@@ -145,7 +145,7 @@ constexpr HashMap<K, T> &HashMap<K, T>::operator=(HashMap<K, T> &&other) {
}
template<typename K, typename T>
constexpr T &HashMap<K, T>::operator[](K k) {
constexpr T &HashMap<K, T>::operator[](const K &k) {
auto &p = access(m_pairs, k);
if (p == nullptr) {
if (m_pairs.size() * 0.7 < m_keys.size()) {
@@ -159,19 +159,19 @@ constexpr T &HashMap<K, T>::operator[](K k) {
}
template<typename K, typename T>
constexpr Result<T*> HashMap<K, T>::at(K k) noexcept {
constexpr Result<T*> HashMap<K, T>::at(const K &k) noexcept {
auto p = access(m_pairs, k);
if (!p) {
return {nullptr, OxError(1)};
return {nullptr, OxError(1, "value not found for given key")};
}
return &p->value;
}
template<typename K, typename T>
constexpr Result<const T*> HashMap<K, T>::at(K k) const noexcept {
constexpr Result<const T*> HashMap<K, T>::at(const K &k) const noexcept {
auto p = access(m_pairs, k);
if (!p) {
return {nullptr, OxError(1)};
return {nullptr, OxError(1, "value not found for given key")};
}
return &p->value;
}
@@ -196,8 +196,9 @@ constexpr void HashMap<K, T>::erase(const K &k) {
}
oxIgnoreError(m_keys.erase(ox::find(m_keys.begin(), m_keys.end(), k)));
}
template<typename K, typename T>
constexpr bool HashMap<K, T>::contains(K k) const noexcept {
constexpr bool HashMap<K, T>::contains(const K &k) const noexcept {
return access(m_pairs, k) != nullptr;
}
@@ -211,12 +212,21 @@ constexpr const Vector<K> &HashMap<K, T>::keys() const noexcept {
return m_keys;
}
template<typename K, typename T>
constexpr void HashMap<K, T>::clear() {
for (std::size_t i = 0; i < m_pairs.size(); i++) {
delete m_pairs[i];
}
m_pairs.clear();
m_pairs.resize(100);
}
template<typename K, typename T>
constexpr void HashMap<K, T>::expand() {
Vector<Pair*> r;
for (std::size_t i = 0; i < m_keys.size(); ++i) {
auto k = m_keys[i];
access(r, k) = access(m_pairs, k);
access(r, k) = std::move(access(m_pairs, k));
}
m_pairs = std::move(r);
}
@@ -231,43 +241,29 @@ constexpr uint64_t HashMap<K, T>::hash(K k, int len) noexcept {
}
template<typename K, typename T>
constexpr typename HashMap<K, T>::Pair *const&HashMap<K, T>::access(const Vector<Pair*> &pairs, K k) const {
constexpr typename HashMap<K, T>::Pair *const&HashMap<K, T>::access(const Vector<Pair*> &pairs, const K &k) const {
auto h = hash(k) % pairs.size();
char hashStr[sizeof(h) + 1];
ox_memcpy(hashStr, &h, sizeof(h));
hashStr[sizeof(h)] = 0;
while (true) {
const auto &p = pairs[h];
if (p == nullptr || ox_strcmp(p->key, k) == 0) {
return p;
} else {
h = hash(hashStr, 8) % pairs.size();
h = (h + 1) % pairs.size();
}
}
}
template<typename K, typename T>
constexpr typename HashMap<K, T>::Pair *&HashMap<K, T>::access(Vector<Pair*> &pairs, K k) {
constexpr typename HashMap<K, T>::Pair *&HashMap<K, T>::access(Vector<Pair*> &pairs, const K &k) {
auto h = hash(k) % pairs.size();
char hashStr[sizeof(h) + 1];
ox_memcpy(hashStr, &h, sizeof(h));
hashStr[sizeof(h)] = 0;
while (true) {
auto &p = pairs[h];
if (p == nullptr || ox_strcmp(p->key, k) == 0) {
return p;
} else {
h = hash(hashStr, 8) % pairs.size();
h = (h + 1) % pairs.size();
}
}
}
template<typename K, typename T>
constexpr void HashMap<K, T>::clear() {
for (std::size_t i = 0; i < m_pairs.size(); i++) {
delete m_pairs[i];
}
m_pairs.clear();
}
}