Add type-save any-type container
This commit is contained in:
parent
e80d831d10
commit
1d35ed2abb
1 changed files with 83 additions and 0 deletions
83
libs/util/include/psemek/util/any_set.hpp
Normal file
83
libs/util/include/psemek/util/any_set.hpp
Normal 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));
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue