aboutsummaryrefslogtreecommitdiff
path: root/src/any_map.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/any_map.hpp')
-rw-r--r--src/any_map.hpp103
1 files changed, 0 insertions, 103 deletions
diff --git a/src/any_map.hpp b/src/any_map.hpp
deleted file mode 100644
index dfc54f3f..00000000
--- a/src/any_map.hpp
+++ /dev/null
@@ -1,103 +0,0 @@
-#pragma once
-
-// ReSharper disable once CppUnusedIncludeDirective
-#include "pre.hpp"
-
-#include <any>
-#include <unordered_map>
-#include <functional>
-#include <optional>
-#include <typeinfo>
-
-#include "base.hpp"
-#include "format.hpp"
-
-
-namespace cru
-{
- // A map with String as key and any type as value.
- // It also has notification when value with specified key changed.
- class AnyMap : public Object
- {
- public:
- using ListenerToken = long;
- using Listener = std::function<void(const std::any&)>;
-
- AnyMap() = default;
- AnyMap(const AnyMap& other) = delete;
- AnyMap(AnyMap&& other) = delete;
- AnyMap& operator=(const AnyMap& other) = delete;
- AnyMap& operator=(AnyMap&& other) = delete;
- ~AnyMap() override = default;
-
-
- // return the value if the value exists and the type of value is T.
- // return a null optional if value doesn't exists.
- // throw std::runtime_error if type is mismatch.
- template <typename T>
- std::optional<T> GetOptionalValue(const String& key) const
- {
- try
- {
- const auto find_result = map_.find(key);
- if (find_result != map_.cend())
- {
- const auto& value = find_result->second.first;
- if (value.has_value())
- return std::any_cast<T>(value);
- return std::nullopt;
- }
- return std::nullopt;
- }
- catch (const std::bad_any_cast&)
- {
- throw std::runtime_error(Format("Value of key \"{}\" in AnyMap is not of the type {}.", ToUtf8String(key), typeid(T).name()));
- }
- }
-
- // return the value if the value exists and the type of value is T.
- // throw if value doesn't exists. (different from "GetOptionalValue").
- // throw std::runtime_error if type is mismatch.
- template <typename T>
- T GetValue(const String& key) const
- {
- const auto optional_value = GetOptionalValue<T>(key);
- if (optional_value.has_value())
- return optional_value.value();
- else
- throw std::runtime_error(Format("Key \"{}\" does not exists in AnyMap.", ToUtf8String(key)));
- }
-
- // Set the value of key, and trigger all related listeners.
- template <typename T>
- void SetValue(const String& key, T&& value)
- {
- auto& p = map_[key];
- p.first = std::make_any<T>(std::forward<T>(value));
- InvokeListeners(p.second, p.first);
- }
-
- // Remove the value of the key.
- void ClearValue(const String& key)
- {
- auto& p = map_[key];
- p.first = std::any{};
- InvokeListeners(p.second, std::any{});
- }
-
- // Add a listener which is called when value of key is changed.
- // Return a token used to remove the listener.
- ListenerToken RegisterValueChangeListener(const String& key, const Listener& listener);
-
- // Remove a listener by token.
- void UnregisterValueChangeListener(ListenerToken token);
-
- private:
- void InvokeListeners(std::list<ListenerToken>& listener_list, const std::any& value);
-
- private:
- std::unordered_map<String, std::pair<std::any, std::list<ListenerToken>>> map_{};
- std::unordered_map<ListenerToken, Listener> listeners_{};
- ListenerToken current_listener_token_ = 0;
- };
-}