From addc2233e7f47bb9f0a99529b71261f4cc31a69f Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sat, 28 May 2022 03:18:10 -0500 Subject: [PATCH] [ox/std] Make HashMap::at return a pointer instead of reference --- deps/ox/src/ox/clargs/clargs.cpp | 12 ++-- deps/ox/src/ox/std/hashmap.hpp | 113 ++++++++++++++++--------------- 2 files changed, 65 insertions(+), 60 deletions(-) diff --git a/deps/ox/src/ox/clargs/clargs.cpp b/deps/ox/src/ox/clargs/clargs.cpp index ec233984..a8c3a03e 100644 --- a/deps/ox/src/ox/clargs/clargs.cpp +++ b/deps/ox/src/ox/clargs/clargs.cpp @@ -39,32 +39,32 @@ ClArgs::ClArgs(int argc, const char **args) noexcept { bool ClArgs::getBool(const char *arg, bool defaultValue) const noexcept { auto [value, err] = m_ints.at(arg); - return !err ? value : defaultValue; + return !err ? *value : defaultValue; } String ClArgs::getString(const char *arg, const char *defaultValue) const noexcept { auto [value, err] = m_strings.at(arg); - return !err ? value : defaultValue; + return !err ? *value : defaultValue; } int ClArgs::getInt(const char *arg, int defaultValue) const noexcept { auto [value, err] = m_ints.at(arg); - return !err ? value : defaultValue; + return !err ? *value : defaultValue; } Result ClArgs::getBool(const char *arg) const noexcept { oxRequire(out, m_bools.at(arg)); - return out; + return *out; } Result ClArgs::getString(const char *argName) const noexcept { oxRequire(out, m_strings.at(argName)); - return out; + return *out; } Result ClArgs::getInt(const char *arg) const noexcept { oxRequire(out, m_ints.at(arg)); - return out; + return *out; } } diff --git a/deps/ox/src/ox/std/hashmap.hpp b/deps/ox/src/ox/std/hashmap.hpp index 00622bc2..ac2b1f23 100644 --- a/deps/ox/src/ox/std/hashmap.hpp +++ b/deps/ox/src/ox/std/hashmap.hpp @@ -29,87 +29,89 @@ class HashMap { Vector m_pairs; public: - explicit HashMap(std::size_t size = 100); + explicit constexpr HashMap(std::size_t size = 100); - HashMap(const HashMap &other); + constexpr HashMap(const HashMap &other); - HashMap(HashMap &&other); + constexpr HashMap(HashMap &&other) noexcept; - ~HashMap(); + constexpr ~HashMap(); - bool operator==(const HashMap &other) const; + constexpr bool operator==(const HashMap &other) const; - HashMap &operator=(const HashMap &other); + constexpr HashMap &operator=(const HashMap &other); - HashMap &operator=(HashMap &&other); + constexpr HashMap &operator=(HashMap &&other); /** * K is assumed to be a null terminated string. */ - T &operator[](K key); + constexpr T &operator[](K key); /** * K is assumed to be a null terminated string. */ - Result at(K key) noexcept; + constexpr Result at(K key) noexcept; /** * K is assumed to be a null terminated string. */ - Result at(K key) const noexcept; + constexpr Result at(K key) const noexcept; - void erase(const K &key); + constexpr void erase(const K &key); - bool contains(K key) const noexcept; + constexpr bool contains(K key) const noexcept; - std::size_t size() const noexcept; + [[nodiscard]] + constexpr std::size_t size() const noexcept; - const Vector &keys() const noexcept; + [[nodiscard]] + constexpr const Vector &keys() const noexcept; private: - void expand(); + constexpr void expand(); /** * K is assumed to be a null terminated string. */ - static uint64_t hash(K, int len = 0xFFFF) noexcept; + constexpr static uint64_t hash(K, int len = 0xFFFF) noexcept; /** * K is assumed to be a null terminated string. */ - Pair *const&access(const Vector &pairs, K key) const; + constexpr Pair *const&access(const Vector &pairs, K key) const; /** * K is assumed to be a null terminated string. */ - Pair *&access(Vector &pairs, K key); + constexpr Pair *&access(Vector &pairs, K key); - void clear(); + constexpr void clear(); }; template -HashMap::HashMap(std::size_t size): m_pairs(size) { +constexpr HashMap::HashMap(std::size_t size): m_pairs(size) { } template -HashMap::HashMap(const HashMap &other) { +constexpr HashMap::HashMap(const HashMap &other) { m_pairs = other.m_pairs; } template -HashMap::HashMap(HashMap &&other) { +constexpr HashMap::HashMap(HashMap &&other) noexcept { m_keys = std::move(other.m_keys); m_pairs = std::move(other.m_pairs); } template -HashMap::~HashMap() { +constexpr HashMap::~HashMap() { clear(); } template -bool HashMap::operator==(const HashMap &other) const { +constexpr bool HashMap::operator==(const HashMap &other) const { if (m_keys != other.m_keys) { return false; } @@ -123,7 +125,7 @@ bool HashMap::operator==(const HashMap &other) const { } template -HashMap &HashMap::operator=(const HashMap &other) { +constexpr HashMap &HashMap::operator=(const HashMap &other) { if (this != &other) { clear(); m_keys = other.m_keys; @@ -133,7 +135,7 @@ HashMap &HashMap::operator=(const HashMap &other) { } template -HashMap &HashMap::operator=(HashMap &&other) { +constexpr HashMap &HashMap::operator=(HashMap &&other) { if (this != &other) { clear(); m_keys = std::move(other.m_keys); @@ -143,7 +145,7 @@ HashMap &HashMap::operator=(HashMap &&other) { } template -T &HashMap::operator[](K k) { +constexpr T &HashMap::operator[](K k) { auto &p = access(m_pairs, k); if (p == nullptr) { if (m_pairs.size() * 0.7 < m_keys.size()) { @@ -157,22 +159,32 @@ T &HashMap::operator[](K k) { } template -Result HashMap::at(K k) noexcept { +constexpr Result HashMap::at(K k) noexcept { auto p = access(m_pairs, k); if (!p) { - AllocAlias v; - return {*reinterpret_cast(&v), OxError(1)}; + return {nullptr, OxError(1)}; } - return p->value; + return &p->value; } template -void HashMap::erase(const K &k) { +constexpr Result HashMap::at(K k) const noexcept { + auto p = access(m_pairs, k); + if (!p) { + return {nullptr, OxError(1)}; + } + return &p->value; +} + +template +constexpr void HashMap::erase(const K &k) { if (!contains(k)) { return; } auto h = hash(k) % m_pairs.size(); - auto hashStr = reinterpret_cast(&h); + char hashStr[sizeof(h) + 1]; + ox_memcpy(hashStr, &h, sizeof(h)); + hashStr[sizeof(h)] = 0; while (true) { const auto &p = m_pairs[h]; if (p == nullptr || ox_strcmp(p->key, k) == 0) { @@ -184,34 +196,23 @@ void HashMap::erase(const K &k) { } oxIgnoreError(m_keys.erase(ox::find(m_keys.begin(), m_keys.end(), k))); } - template -Result HashMap::at(K k) const noexcept { - auto p = access(m_pairs, k); - if (!p) { - AllocAlias v; - return {*reinterpret_cast(&v), OxError(1)}; - } - return p->value; -} - -template -bool HashMap::contains(K k) const noexcept { +constexpr bool HashMap::contains(K k) const noexcept { return access(m_pairs, k) != nullptr; } template -std::size_t HashMap::size() const noexcept { +constexpr std::size_t HashMap::size() const noexcept { return m_keys.size(); } template -const Vector &HashMap::keys() const noexcept { +constexpr const Vector &HashMap::keys() const noexcept { return m_keys; } template -void HashMap::expand() { +constexpr void HashMap::expand() { Vector r; for (std::size_t i = 0; i < m_keys.size(); ++i) { auto k = m_keys[i]; @@ -221,7 +222,7 @@ void HashMap::expand() { } template -uint64_t HashMap::hash(K k, int len) noexcept { +constexpr uint64_t HashMap::hash(K k, int len) noexcept { uint64_t sum = 1; for (auto i = 0u; i < static_cast(len) && k[i]; ++i) { sum += ((sum + static_cast(k[i])) * 7) * sum; @@ -230,9 +231,11 @@ uint64_t HashMap::hash(K k, int len) noexcept { } template -typename HashMap::Pair *const&HashMap::access(const Vector &pairs, K k) const { +constexpr typename HashMap::Pair *const&HashMap::access(const Vector &pairs, K k) const { auto h = hash(k) % pairs.size(); - auto hashStr = reinterpret_cast(&h); + 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) { @@ -244,9 +247,11 @@ typename HashMap::Pair *const&HashMap::access(const Vector &p } template -typename HashMap::Pair *&HashMap::access(Vector &pairs, K k) { +constexpr typename HashMap::Pair *&HashMap::access(Vector &pairs, K k) { auto h = hash(k) % pairs.size(); - auto hashStr = reinterpret_cast(&h); + 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) { @@ -258,7 +263,7 @@ typename HashMap::Pair *&HashMap::access(Vector &pairs, K k) } template -void HashMap::clear() { +constexpr void HashMap::clear() { for (std::size_t i = 0; i < m_pairs.size(); i++) { delete m_pairs[i]; }