#include #include #include #include #include #include // Ordered maps can be iterated by key order // Unordered maps have the fastest lookup times (also called a hash map) template class IHMap { public: virtual ~IHMap() = default; virtual void* get(const KeyType& key) = 0; virtual void put(const KeyType& key, void* value) = 0; virtual void erase(const KeyType& key) = 0; virtual void clear() = 0; virtual size_t size() const = 0; virtual void* begin() = 0; virtual void* next() = 0; }; template class HMap final : public IHMap { private: using MapType = typename std::conditional< UseUnordered, std::unordered_map, std::map >::type; public: void* get(const KeyType& key) override { auto it = mMap.find(key); return (it != mMap.end()) ? it->second : nullptr; } void put(const KeyType& key, void* value) override { mMap.insert_or_assign(key, value); } void erase(const KeyType& key) override { mMap.erase(key); } void clear() override { mMap.clear(); } size_t size() const override { return mMap.size(); } void* begin() override { if (mMap.empty()) return nullptr; mIterator = mMap.begin(); return mIterator->second; } void* next() override { if (++mIterator != mMap.end()) { return mIterator->second; } return nullptr; } private: MapType mMap; typename MapType::iterator mIterator; }; extern "C" { void* hmap_create(bool useUnordered) { if (useUnordered) { return new HMap(); } return new HMap(); } void* hmap_get(void* map, int64_t key) { if (!map) { return NULL; } IHMap* hmap = static_cast*>(map); return hmap->get(key); } void hmap_put(void* map, int64_t key, void* value) { if (!map) { return; } IHMap* hmap = static_cast*>(map); hmap->put(key, value); } void hmap_del(void* map, int64_t key) { if (!map) { return; } IHMap* hmap = static_cast*>(map); hmap->erase(key); } void hmap_clear(void* map) { if (!map) { return; } IHMap* hmap = static_cast*>(map); hmap->clear(); } void hmap_destroy(void* map) { if (!map) { return; } delete static_cast*>(map); } size_t hmap_len(void* map) { if (!map) { return 0; } IHMap* hmap = static_cast*>(map); return hmap->size(); } void* hmap_begin(void* map) { if (!map) { return NULL; } IHMap* hmap = static_cast*>(map); return hmap->begin(); } void* hmap_next(void* map) { if (!map) { return NULL; } IHMap* hmap = static_cast*>(map); return hmap->next(); } // Data/String map (for larger keys) void* hmap_data_create(void) { return new HMap(); } void* hmap_data_get(void* map, const char* key, size_t len) { if (!map) { return NULL; } std::string keyString(key, len); return static_cast*>(map)->get(keyString); } void hmap_data_put(void* map, const char* key, size_t len, void* value) { if (!map) { return; } std::string keyString(key, len); static_cast*>(map)->put(keyString, value); } void hmap_data_del(void* map, const char* key, size_t len) { if (!map) { return; } std::string keyString(key, len); static_cast*>(map)->erase(keyString); } void hmap_data_clear(void* map) { if (!map) { return; } static_cast*>(map)->clear(); } void hmap_data_destroy(void* map) { if (!map) { return; } delete static_cast*>(map); } size_t hmap_data_len(void* map) { if (!map) { return 0; } return static_cast*>(map)->size(); } }