Compare commits

...

2 Commits

Author SHA1 Message Date
7233da75ea [ox/std] Remove dedicated keys array from SmallMap
All checks were successful
Build / build (push) Successful in 2m31s
2024-05-11 01:59:40 -05:00
30797c710b [ox/std] Add small sz option to SmallMap 2024-05-11 00:53:31 -05:00

View File

@ -17,20 +17,19 @@
namespace ox { namespace ox {
template<typename K, typename T> template<typename K, typename T, size_t SmallSz = 0>
class SmallMap { class SmallMap {
public: public:
using key_t = K; using key_t = K;
using value_t = T; using value_t = T;
private:
struct Pair { struct Pair {
K key = {}; K key = {};
T value{}; T value{};
}; };
using PairVector = Vector<Pair>;
Vector<K> m_keys; private:
using PairVector = Vector<Pair, SmallSz>;
PairVector m_pairs; PairVector m_pairs;
public: public:
@ -63,7 +62,22 @@ class SmallMap {
constexpr std::size_t size() const noexcept; constexpr std::size_t size() const noexcept;
[[nodiscard]] [[nodiscard]]
constexpr Vector<K> const&keys() const noexcept; constexpr Vector<K> keys() const noexcept;
[[nodiscard]]
constexpr K const&key(size_t i) const noexcept;
[[nodiscard]]
constexpr T const&value(size_t i) const noexcept;
[[nodiscard]]
constexpr T &value(size_t i) noexcept;
[[nodiscard]]
constexpr Pair const&get(size_t i) const noexcept;
[[nodiscard]]
constexpr Pair &get(size_t i) noexcept;
constexpr void clear(); constexpr void clear();
@ -76,58 +90,46 @@ class SmallMap {
}; };
template<typename K, typename T> template<typename K, typename T, size_t SmallSz>
constexpr SmallMap<K, T>::SmallMap(SmallMap<K, T> const&other) { constexpr SmallMap<K, T, SmallSz>::SmallMap(SmallMap<K, T, SmallSz> const&other) {
m_pairs = other.m_pairs; m_pairs = other.m_pairs;
} }
template<typename K, typename T> template<typename K, typename T, size_t SmallSz>
constexpr SmallMap<K, T>::SmallMap(SmallMap<K, T> &&other) noexcept { constexpr SmallMap<K, T, SmallSz>::SmallMap(SmallMap<K, T, SmallSz> &&other) noexcept {
m_keys = std::move(other.m_keys);
m_pairs = std::move(other.m_pairs); m_pairs = std::move(other.m_pairs);
} }
template<typename K, typename T> template<typename K, typename T, size_t SmallSz>
constexpr SmallMap<K, T>::~SmallMap() { constexpr SmallMap<K, T, SmallSz>::~SmallMap() {
clear(); clear();
} }
template<typename K, typename T> template<typename K, typename T, size_t SmallSz>
constexpr bool SmallMap<K, T>::operator==(SmallMap const&other) const { constexpr bool SmallMap<K, T, SmallSz>::operator==(SmallMap const&other) const {
if (m_keys != other.m_keys) { return m_pairs == other.m_pairs;
return false;
}
for (int i = 0; i < m_keys.size(); ++i) {
auto &k = m_keys[i];
if (at(k) != other.at(k)) {
return false;
}
}
return true;
} }
template<typename K, typename T> template<typename K, typename T, size_t SmallSz>
constexpr SmallMap<K, T> &SmallMap<K, T>::operator=(SmallMap<K, T> const&other) { constexpr SmallMap<K, T, SmallSz> &SmallMap<K, T, SmallSz>::operator=(SmallMap<K, T, SmallSz> const&other) {
if (this != &other) { if (this != &other) {
clear(); clear();
m_keys = other.m_keys;
m_pairs = other.m_pairs; m_pairs = other.m_pairs;
} }
return *this; return *this;
} }
template<typename K, typename T> template<typename K, typename T, size_t SmallSz>
constexpr SmallMap<K, T> &SmallMap<K, T>::operator=(SmallMap<K, T> &&other) noexcept { constexpr SmallMap<K, T, SmallSz> &SmallMap<K, T, SmallSz>::operator=(SmallMap<K, T, SmallSz> &&other) noexcept {
if (this != &other) { if (this != &other) {
clear(); clear();
m_keys = std::move(other.m_keys);
m_pairs = std::move(other.m_pairs); m_pairs = std::move(other.m_pairs);
} }
return *this; return *this;
} }
template<typename K, typename T> template<typename K, typename T, size_t SmallSz>
constexpr T &SmallMap<K, T>::operator[](MaybeView_t<K> const&k) { constexpr T &SmallMap<K, T, SmallSz>::operator[](MaybeView_t<K> const&k) {
bool isNew{}; bool isNew{};
auto p = &access(m_pairs, k, isNew); auto p = &access(m_pairs, k, isNew);
if (isNew) { if (isNew) {
@ -136,8 +138,8 @@ constexpr T &SmallMap<K, T>::operator[](MaybeView_t<K> const&k) {
return p->value; return p->value;
} }
template<typename K, typename T> template<typename K, typename T, size_t SmallSz>
constexpr Result<T*> SmallMap<K, T>::at(MaybeView_t<K> const&k) noexcept { constexpr Result<T*> SmallMap<K, T, SmallSz>::at(MaybeView_t<K> const&k) noexcept {
auto p = access(m_pairs, k); auto p = access(m_pairs, k);
if (!p) { if (!p) {
return {nullptr, OxError(1, "value not found for given key")}; return {nullptr, OxError(1, "value not found for given key")};
@ -145,8 +147,8 @@ constexpr Result<T*> SmallMap<K, T>::at(MaybeView_t<K> const&k) noexcept {
return &p->value; return &p->value;
} }
template<typename K, typename T> template<typename K, typename T, size_t SmallSz>
constexpr Result<const T*> SmallMap<K, T>::at(MaybeView_t<K> const&k) const noexcept { constexpr Result<const T*> SmallMap<K, T, SmallSz>::at(MaybeView_t<K> const&k) const noexcept {
auto p = access(m_pairs, k); auto p = access(m_pairs, k);
if (!p) { if (!p) {
return {nullptr, OxError(1, "value not found for given key")}; return {nullptr, OxError(1, "value not found for given key")};
@ -154,8 +156,8 @@ constexpr Result<const T*> SmallMap<K, T>::at(MaybeView_t<K> const&k) const noex
return &p->value; return &p->value;
} }
template<typename K, typename T> template<typename K, typename T, size_t SmallSz>
constexpr void SmallMap<K, T>::erase(MaybeView_t<K> const&k) { constexpr void SmallMap<K, T, SmallSz>::erase(MaybeView_t<K> const&k) {
size_t i{}; size_t i{};
for (auto const&p : m_pairs) { for (auto const&p : m_pairs) {
if (k == p.key) { if (k == p.key) {
@ -164,32 +166,61 @@ constexpr void SmallMap<K, T>::erase(MaybeView_t<K> const&k) {
++i; ++i;
} }
std::ignore = m_pairs.erase(i); std::ignore = m_pairs.erase(i);
std::ignore = m_keys.erase(i);
} }
template<typename K, typename T> template<typename K, typename T, size_t SmallSz>
constexpr bool SmallMap<K, T>::contains(MaybeView_t<K> const&k) const noexcept { constexpr bool SmallMap<K, T, SmallSz>::contains(MaybeView_t<K> const&k) const noexcept {
return access(m_pairs, k) != nullptr; return access(m_pairs, k) != nullptr;
} }
template<typename K, typename T> template<typename K, typename T, size_t SmallSz>
constexpr std::size_t SmallMap<K, T>::size() const noexcept { constexpr std::size_t SmallMap<K, T, SmallSz>::size() const noexcept {
return m_keys.size(); return m_pairs.size();
} }
template<typename K, typename T> template<typename K, typename T, size_t SmallSz>
constexpr Vector<K> const&SmallMap<K, T>::keys() const noexcept { constexpr Vector<K> SmallMap<K, T, SmallSz>::keys() const noexcept {
return m_keys; ox::Vector<K> keys;
keys.reserve(m_pairs.size());
for (auto const&p : m_pairs) {
keys.emplace_back(p.key);
}
return keys;
} }
template<typename K, typename T> template<typename K, typename T, size_t SmallSz>
constexpr void SmallMap<K, T>::clear() { constexpr K const&SmallMap<K, T, SmallSz>::key(size_t i) const noexcept {
return m_pairs[i].key;
}
template<typename K, typename T, size_t SmallSz>
constexpr T const&SmallMap<K, T, SmallSz>::value(size_t i) const noexcept {
return m_pairs[i].value;
}
template<typename K, typename T, size_t SmallSz>
constexpr T &SmallMap<K, T, SmallSz>::value(size_t i) noexcept {
return m_pairs[i].value;
}
template<typename K, typename T, size_t SmallSz>
constexpr SmallMap<K, T, SmallSz>::Pair const&SmallMap<K, T, SmallSz>::get(size_t i) const noexcept {
return m_pairs[i];
}
template<typename K, typename T, size_t SmallSz>
constexpr SmallMap<K, T, SmallSz>::Pair &SmallMap<K, T, SmallSz>::get(size_t i) noexcept {
return m_pairs[i];
}
template<typename K, typename T, size_t SmallSz>
constexpr void SmallMap<K, T, SmallSz>::clear() {
m_pairs.clear(); m_pairs.clear();
} }
template<typename K, typename T> template<typename K, typename T, size_t SmallSz>
template<typename KK> template<typename KK>
constexpr typename SmallMap<K, T>::Pair const&SmallMap<K, T>::access( constexpr typename SmallMap<K, T, SmallSz>::Pair const&SmallMap<K, T, SmallSz>::access(
PairVector 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) {
@ -198,13 +229,12 @@ constexpr typename SmallMap<K, T>::Pair const&SmallMap<K, T>::access(
} }
} }
isNew = true; isNew = true;
m_keys.emplace_back(K(k));
return pairs.emplace_back(); return pairs.emplace_back();
} }
template<typename K, typename T> template<typename K, typename T, size_t SmallSz>
template<typename KK> template<typename KK>
constexpr typename SmallMap<K, T>::Pair &SmallMap<K, T>::access( constexpr typename SmallMap<K, T, SmallSz>::Pair &SmallMap<K, T, SmallSz>::access(
PairVector &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) {
@ -213,7 +243,6 @@ constexpr typename SmallMap<K, T>::Pair &SmallMap<K, T>::access(
} }
} }
isNew = true; isNew = true;
m_keys.emplace_back(K(k));
return pairs.emplace_back(); return pairs.emplace_back();
} }