From 1d35ed2abbb18a372694af6b3bd66854b19d6397 Mon Sep 17 00:00:00 2001 From: lisyarus Date: Mon, 29 May 2023 16:38:16 +0300 Subject: [PATCH] Add type-save any-type container --- libs/util/include/psemek/util/any_set.hpp | 83 +++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 libs/util/include/psemek/util/any_set.hpp diff --git a/libs/util/include/psemek/util/any_set.hpp b/libs/util/include/psemek/util/any_set.hpp new file mode 100644 index 00000000..5ffef7ab --- /dev/null +++ b/libs/util/include/psemek/util/any_set.hpp @@ -0,0 +1,83 @@ +#pragma once + +#include +#include +#include + +namespace psemek::util +{ + + struct any_set + { + template + T & emplace(Args && ... args); + + template + T const & get() const; + + template + T & get(); + + template + T const * get_if() const; + + template + T * get_if(); + + template + bool contains() const; + + template + void remove(); + + private: + std::unordered_map storage_; + }; + + template + T & any_set::emplace(Args && ... args) + { + return std::any_cast(storage_[typeid(T)] = T(std::forward(args)...)); + } + + template + T const & any_set::get() const + { + return std::any_cast(storage_.at(typeid(T))); + } + + template + T & any_set::get() + { + return std::any_cast(storage_.at(typeid(T))); + } + + template + T const * any_set::get_if() const + { + if (auto it = storage_.find(typeid(T)); it != storage_.end()) + return std::addressof(std::any_cast(it->second)); + return nullptr; + } + + template + T * any_set::get_if() + { + if (auto it = storage_.find(typeid(T)); it != storage_.end()) + return std::addressof(std::any_cast(it->second)); + return nullptr; + } + + template + bool any_set::contains() const + { + return storage_.contains(typeid(T)); + } + + template + void any_set::remove() + { + storage_.erase(typeid(T)); + } + +}