Add type-save any-type container

This commit is contained in:
Nikita Lisitsa 2023-05-29 16:38:16 +03:00
parent e80d831d10
commit 1d35ed2abb

View file

@ -0,0 +1,83 @@
#pragma once
#include <typeindex>
#include <any>
#include <unordered_map>
namespace psemek::util
{
struct any_set
{
template <typename T, typename ... Args>
T & emplace(Args && ... args);
template <typename T>
T const & get() const;
template <typename T>
T & get();
template <typename T>
T const * get_if() const;
template <typename T>
T * get_if();
template <typename T>
bool contains() const;
template <typename T>
void remove();
private:
std::unordered_map<std::type_index, std::any> storage_;
};
template <typename T, typename ... Args>
T & any_set::emplace(Args && ... args)
{
return std::any_cast<T &>(storage_[typeid(T)] = T(std::forward<Args>(args)...));
}
template <typename T>
T const & any_set::get() const
{
return std::any_cast<T const &>(storage_.at(typeid(T)));
}
template <typename T>
T & any_set::get()
{
return std::any_cast<T &>(storage_.at(typeid(T)));
}
template <typename T>
T const * any_set::get_if() const
{
if (auto it = storage_.find(typeid(T)); it != storage_.end())
return std::addressof(std::any_cast<T const &>(it->second));
return nullptr;
}
template <typename T>
T * any_set::get_if()
{
if (auto it = storage_.find(typeid(T)); it != storage_.end())
return std::addressof(std::any_cast<T &>(it->second));
return nullptr;
}
template <typename T>
bool any_set::contains() const
{
return storage_.contains(typeid(T));
}
template <typename T>
void any_set::remove()
{
storage_.erase(typeid(T));
}
}