/** * @file map.hpp * @brief J Library Map ヘッダファイル。 * @copyright 2001 - 2024 Nomura Kei * @depends * j/util/collection.hpp */ #ifndef J_UTIL_HASH_MAP_HPP #define J_UTIL_HASH_MAP_HPP #include <unordered_map> #include <j/util/map.hpp> #include <j/util/collection.hpp> namespace j { namespace util { /** * ハッシュマップ。 * C++17 のハッシュマップ std::unordered_map を内部で利用しています。 * * @code * HashMap<j::lang::String, j::lang::String> map; * map.put("key1", "value1"); * map.put("key2", "value2"); * map.put("key3", "value3"); * * auto value = map.get("key1"); * // ※auto : std::optional<j::lang::String> * if (value) * { * std::cout << value.value() << std::endl; * } * @endcode */ template <typename K, typename V> class HashMap : public Map<K, V> { public: HashMap() = default; HashMap(const HashMap &map) : data(map.data) {} HashMap(HashMap &&map) noexcept : data(std::move(map.data)) {} virtual ~HashMap() = default; HashMap &operator=(const HashMap &map) { if (this != &map) { data = map.data; } return *this; } HashMap &operator=(HashMap &&map) noexcept { if (this != &map) { data = std::move(map.data); } return *this; } /** * このマップ内のキー値マッピングの数を返します。 * * @return このマップ内のキーと値のマッピング数 */ virtual int size() const noexcept { return data.size(); } /** * このマップがキーと値のマッピングを保持しない場合に true を返します。 * * @return このマップがキーと値のマッピングを保持しない場合は true */ virtual bool isEmpty() const noexcept { return data.empty(); } /** * 指定のキーのマッピングが、このマップに含まれている場合に true を返します。 * * @param key このマップ内にあるかどうかが判定されるキー * @return このマップが指定されたキーのマッピングを保持する場合は true */ virtual bool containsKey(const K &key) const { return (data.find(key) != data.end()); } /** * マップが1つまたは複数のキーを指定された値にマッピングしている場合に true を返します。 * * @param value このマップにあるかどうかが判定される値 * @return このマップが1つまたは複数のキーを指定された値にマッピングしている場合は true */ virtual bool containsValue(const V &value) const { for (const auto &pair : data) { if (pair.second == value) { return true; } } return false; } /** * 指定されたキーがマップされている値を返します。 * このマップにそのキーのマッピングが含まれていない場合は、要素を値初期化して参照を返す。 * * @param key 関連付けられた値が返されるキー * @return 指定されたキーがマップされている値。 */ virtual std::optional<V> get(const K &key) const { auto it = data.find(key); if (it != data.end()) { return it->second; } return std::nullopt; } /** * 指定された値と指定されたキーをこのマップで関連付けます。 * * @param key 指定された値が関連付けられるキー * @param value 指定されたキーに関連付けられる値 * @return key に以前関連付けられていた値。 */ virtual std::optional<V> put(const K &key, const V &value) { auto it = data.find(key); if (it != data.end()) { V oldValue = it->second; it->second = value; return oldValue; } else { data[key] = value; return std::nullopt; } } /** * このマップからキーのマッピングを削除します。 * * @param key マッピングがマップから削除されるキー * @return key に以前に関連付けられていた値 */ virtual std::optional<V> remove(const K &key) { auto it = data.find(key); if (it != data.end()) { V value = it->second; data.erase(it); return value; } return std::nullopt; }; /** * マップからマッピングをすべて削除します。 */ virtual void clear() noexcept { data.clear(); }; protected: std::unordered_map<K, V> data; }; } // namespace util } // namespace j #endif // J_UTIL_HASH_MAP_HPP