mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2025-10-30 08:01:01 +00:00
188 lines
4.8 KiB
C++
188 lines
4.8 KiB
C++
#include <map>
|
|
#include <unordered_map>
|
|
#include <cstdint>
|
|
#include <cstddef>
|
|
#include <memory>
|
|
|
|
enum class MapType {
|
|
Ordered,
|
|
Unordered
|
|
};
|
|
|
|
// Ordered maps can be iterated by key order
|
|
// Unordered maps have the fastest lookup times (also called a hash map)
|
|
|
|
class HMap {
|
|
public:
|
|
HMap(MapType type = MapType::Ordered) : mMapType(type) {
|
|
switch (mMapType) {
|
|
case MapType::Ordered:
|
|
mOrderedMap = std::make_unique<std::map<int64_t, void*>>();
|
|
break;
|
|
case MapType::Unordered:
|
|
mUnorderedMap = std::make_unique<std::unordered_map<int64_t, void*>>();
|
|
break;
|
|
}
|
|
}
|
|
|
|
void* get(int64_t key) {
|
|
switch (mMapType) {
|
|
case MapType::Ordered: {
|
|
auto it = mOrderedMap->find(key);
|
|
if (it != mOrderedMap->end()) {
|
|
return it->second;
|
|
}
|
|
break;
|
|
}
|
|
case MapType::Unordered: {
|
|
auto it = mUnorderedMap->find(key);
|
|
if (it != mUnorderedMap->end()) {
|
|
return it->second;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
void put(int64_t key, void* value) {
|
|
switch (mMapType) {
|
|
case MapType::Ordered:
|
|
mOrderedMap->insert_or_assign(key, value);
|
|
break;
|
|
case MapType::Unordered:
|
|
mUnorderedMap->insert_or_assign(key, value);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void erase(int64_t key) {
|
|
switch (mMapType) {
|
|
case MapType::Ordered:
|
|
mOrderedMap->erase(key);
|
|
break;
|
|
case MapType::Unordered:
|
|
mUnorderedMap->erase(key);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void clear() {
|
|
switch (mMapType) {
|
|
case MapType::Ordered:
|
|
mOrderedMap->clear();
|
|
break;
|
|
case MapType::Unordered:
|
|
mUnorderedMap->clear();
|
|
break;
|
|
}
|
|
}
|
|
|
|
size_t size() const {
|
|
switch (mMapType) {
|
|
case MapType::Ordered:
|
|
return mOrderedMap->size();
|
|
case MapType::Unordered:
|
|
return mUnorderedMap->size();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void* begin() {
|
|
switch (mMapType) {
|
|
case MapType::Ordered: {
|
|
auto& orderedMap = *mOrderedMap;
|
|
if (orderedMap.empty()) { return nullptr; }
|
|
mOrderedIterator = mOrderedMap->begin();
|
|
return mOrderedIterator->second;
|
|
}
|
|
case MapType::Unordered: {
|
|
auto& unorderedMap = *mUnorderedMap;
|
|
if (unorderedMap.empty()) { return nullptr; }
|
|
mUnorderedIterator = mUnorderedMap->begin();
|
|
return mUnorderedIterator->second;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
void* next() {
|
|
switch (mMapType) {
|
|
case MapType::Ordered: {
|
|
if (++mOrderedIterator != mOrderedMap->end()) {
|
|
return mOrderedIterator->second;
|
|
}
|
|
break;
|
|
}
|
|
case MapType::Unordered: {
|
|
if (++mUnorderedIterator != mUnorderedMap->end()) {
|
|
return mUnorderedIterator->second;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
private:
|
|
MapType mMapType;
|
|
|
|
std::unique_ptr<std::map<int64_t, void*>> mOrderedMap;
|
|
typename std::map<int64_t, void*>::iterator mOrderedIterator;
|
|
|
|
std::unique_ptr<std::unordered_map<int64_t, void*>> mUnorderedMap;
|
|
typename std::unordered_map<int64_t, void*>::iterator mUnorderedIterator;
|
|
};
|
|
|
|
extern "C" {
|
|
void* hmap_create(MapType type) {
|
|
return new HMap(type);
|
|
}
|
|
|
|
void* hmap_get(void* map, int64_t key) {
|
|
if (!map) { return NULL; }
|
|
HMap* hmap = reinterpret_cast<HMap*>(map);
|
|
return hmap->get(key);
|
|
}
|
|
|
|
void hmap_put(void* map, int64_t key, void* value) {
|
|
if (!map) { return; }
|
|
HMap* hmap = reinterpret_cast<HMap*>(map);
|
|
hmap->put(key, value);
|
|
}
|
|
|
|
void hmap_del(void* map, int64_t key) {
|
|
if (!map) { return; }
|
|
HMap* hmap = reinterpret_cast<HMap*>(map);
|
|
hmap->erase(key);
|
|
}
|
|
|
|
void hmap_clear(void* map) {
|
|
if (!map) { return; }
|
|
HMap* hmap = reinterpret_cast<HMap*>(map);
|
|
hmap->clear();
|
|
}
|
|
|
|
void hmap_destroy(void* map) {
|
|
if (!map) { return; }
|
|
delete reinterpret_cast<HMap*>(map);
|
|
}
|
|
|
|
size_t hmap_len(void* map) {
|
|
if (!map) { return 0; }
|
|
HMap* hmap = reinterpret_cast<HMap*>(map);
|
|
return hmap->size();
|
|
}
|
|
|
|
void* hmap_begin(void* map) {
|
|
if (!map) { return NULL; }
|
|
HMap* hmap = reinterpret_cast<HMap*>(map);
|
|
return hmap->begin();
|
|
}
|
|
|
|
void* hmap_next(void* map) {
|
|
if (!map) { return NULL; }
|
|
HMap* hmap = reinterpret_cast<HMap*>(map);
|
|
return hmap->next();
|
|
}
|
|
}
|