[ox/std] Add ox::find(...) and HashMap::erase(K)

This commit is contained in:
Gary Talent 2021-11-01 18:44:59 -05:00
parent ad743565b2
commit e3a48d0045
3 changed files with 48 additions and 2 deletions

View File

@ -63,6 +63,7 @@ target_link_libraries(
install( install(
FILES FILES
algorithm.hpp
assert.hpp assert.hpp
bit.hpp bit.hpp
bstring.hpp bstring.hpp

23
deps/ox/src/ox/std/algorithm.hpp vendored Normal file
View File

@ -0,0 +1,23 @@
/*
* Copyright 2015 - 2021 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
namespace ox {
template<typename It, typename T>
constexpr It find(It begin, It end, const T &value) {
for (; begin != end; ++begin) {
if (*begin == value) {
return begin;
}
}
return end;
}
}

View File

@ -8,6 +8,7 @@
#pragma once #pragma once
#include "algorithm.hpp"
#include "strops.hpp" #include "strops.hpp"
#include "vector.hpp" #include "vector.hpp"
@ -57,6 +58,8 @@ class HashMap {
*/ */
Result<const T&> at(K key) const noexcept; Result<const T&> at(K key) const noexcept;
void erase(const K &key);
bool contains(K key) const noexcept; bool contains(K key) const noexcept;
std::size_t size() const noexcept; std::size_t size() const noexcept;
@ -163,6 +166,25 @@ Result<T&> HashMap<K, T>::at(K k) noexcept {
return p->value; return p->value;
} }
template<typename K, typename T>
void HashMap<K, T>::erase(const K &k) {
if (!contains(k)) {
return;
}
auto h = hash(k) % m_pairs.size();
auto hashStr = reinterpret_cast<char*>(&h);
while (true) {
const auto &p = m_pairs[h];
if (p == nullptr || ox_strcmp(p->key, k) == 0) {
m_pairs.erase(h);
break;
} else {
h = hash(hashStr, 8) % m_pairs.size();
}
}
m_keys.erase(ox::find(m_keys.cbegin(), m_keys.cend(), k));
}
template<typename K, typename T> template<typename K, typename T>
Result<const T&> HashMap<K, T>::at(K k) const noexcept { Result<const T&> HashMap<K, T>::at(K k) const noexcept {
auto p = access(m_pairs, k); auto p = access(m_pairs, k);
@ -211,7 +233,7 @@ template<typename K, typename T>
typename HashMap<K, T>::Pair *const&HashMap<K, T>::access(const Vector<Pair*> &pairs, K k) const { typename HashMap<K, T>::Pair *const&HashMap<K, T>::access(const Vector<Pair*> &pairs, K k) const {
auto h = hash(k) % pairs.size(); auto h = hash(k) % pairs.size();
auto hashStr = reinterpret_cast<char*>(&h); auto hashStr = reinterpret_cast<char*>(&h);
while (1) { while (true) {
const auto &p = pairs[h]; const auto &p = pairs[h];
if (p == nullptr || ox_strcmp(p->key, k) == 0) { if (p == nullptr || ox_strcmp(p->key, k) == 0) {
return p; return p;
@ -225,7 +247,7 @@ template<typename K, typename T>
typename HashMap<K, T>::Pair *&HashMap<K, T>::access(Vector<Pair*> &pairs, K k) { typename HashMap<K, T>::Pair *&HashMap<K, T>::access(Vector<Pair*> &pairs, K k) {
auto h = hash(k) % pairs.size(); auto h = hash(k) % pairs.size();
auto hashStr = reinterpret_cast<char*>(&h); auto hashStr = reinterpret_cast<char*>(&h);
while (1) { while (true) {
auto &p = pairs[h]; auto &p = pairs[h];
if (p == nullptr || ox_strcmp(p->key, k) == 0) { if (p == nullptr || ox_strcmp(p->key, k) == 0) {
return p; return p;