Skip to content

Instantly share code, notes, and snippets.

@LusainKim
Last active May 30, 2019 02:30
Show Gist options
  • Save LusainKim/ef3fd162f48f7f4787c6e13b626cac8b to your computer and use it in GitHub Desktop.
Save LusainKim/ef3fd162f48f7f4787c6e13b626cac8b to your computer and use it in GitHub Desktop.
Implemented a container wrapper class that type and value corresponded 1: 1, used C++17
#include <any>
#include <utility>
#include <typeinfo>
#include <typeindex>
#include <unordered_map>
class type_map
{
public:
using This = type_map;
using key_type = std::type_index;
public:
template<typename Ty>
This& insert(Ty&& value)
{
key_type keyval{ key<Ty>() };
if (exist<Ty>()) container.erase(keyval);
container.insert(std::make_pair(keyval, std::forward<Ty>(value)));
return *this;
}
template<typename Ty>
bool erase()
{
key_type keyval{ key<Ty>() };
if (!exist<Ty>()) return false;
container.erase(keyval);
return true;
}
template<typename Ty>
bool exist() const { return container.count(key<Ty>()) > 0; }
template<typename Ty>
Ty* get()
{
key_type keyval{ key<Ty>() };
if (!exist<Ty>()) return nullptr;
return std::any_cast<Ty>(&container.at(keyval));
}
template<typename Ty>
const Ty* get() const
{
key_type keyval{ key<Ty>() };
if (!exist<Ty>()) return nullptr;
return std::any_cast<Ty>(&container.at(keyval));
}
template<typename Ty> operator Ty*() { return get<Ty>(); }
template<typename Ty> operator const Ty*() const { return get<Ty>(); }
private:
template<typename Ty> key_type key() const { return std::type_index{ typeid(Ty) }; }
private:
std::unordered_map<key_type, std::any> container;
};
// sample structure
struct A { int i = 0; };
// usage
#include <iostream>
int main()
{
type_map m;
m.insert(A{ 1 });
std::cout << "class : " << std::endl;
std::cout << m.get<A>()->i << std::endl;
m.get<A>()->i = 3;
std::cout << m.get<A>()->i << std::endl;
std::cout << static_cast<A*>(m)->i << std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment