/** ****************************************************************************** * 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 #include 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 class split_map { using key_vector = std::vector; using value_vector = std::vector; key_vector keys_; value_vector values_; public: using my_type = split_map; uint32_t IndexForKey(const TKey& k) { auto lbound = std::lower_bound(keys_.begin(), keys_.end(), k); return static_cast(lbound - keys_.begin()); } uint32_t size() const { return static_cast(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(new_size)); values_.resize(static_cast(new_size)); } void reserve(uint32_t new_size) { keys_.reserve(static_cast(new_size)); values_.reserve(static_cast(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_