Files
Xenia-Canary/src/xenia/base/split_map.h
2025-07-19 14:42:21 -07:00

86 lines
2.4 KiB
C++

/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2019 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_BASE_SPLIT_MAP_H_
#define XENIA_BASE_SPLIT_MAP_H_
#include <algorithm>
#include <vector>
namespace xe {
/*
a map structure that is optimized for infrequent
reallocation/resizing/erasure and frequent searches by key implemented as 2
std::vectors, one of the keys and one of the values
*/
template <typename TKey, typename TValue>
class split_map {
using key_vector = std::vector<TKey>;
using value_vector = std::vector<TValue>;
key_vector keys_;
value_vector values_;
public:
using my_type = split_map<TKey, TValue>;
uint32_t IndexForKey(const TKey& k) {
auto lbound = std::lower_bound(keys_.begin(), keys_.end(), k);
return static_cast<uint32_t>(lbound - keys_.begin());
}
uint32_t size() const { return static_cast<uint32_t>(keys_.size()); }
key_vector& Keys() { return keys_; }
value_vector& Values() { return values_; }
void clear() {
keys_.clear();
values_.clear();
}
void resize(uint32_t new_size) {
keys_.resize(static_cast<size_t>(new_size));
values_.resize(static_cast<size_t>(new_size));
}
void reserve(uint32_t new_size) {
keys_.reserve(static_cast<size_t>(new_size));
values_.reserve(static_cast<size_t>(new_size));
}
const TKey* KeyAt(uint32_t index) const {
if (index == size()) {
return nullptr;
} else {
return &keys_[index];
}
}
const TValue* ValueAt(uint32_t index) const {
if (index == size()) {
return nullptr;
} else {
return &values_[index];
}
}
void InsertAt(TKey k, TValue v, uint32_t idx) {
uint32_t old_size = size();
values_.insert(values_.begin() + idx, v);
keys_.insert(keys_.begin() + idx, k);
}
void EraseAt(uint32_t idx) {
uint32_t old_size = size();
if (idx == old_size) {
return; // trying to erase nonexistent entry
} else {
values_.erase(values_.begin() + idx);
keys_.erase(keys_.begin() + idx);
}
}
};
} // namespace xe
#endif // XENIA_BASE_SPLIT_MAP_H_