Skip to content

Instantly share code, notes, and snippets.

@lniwn
Created June 14, 2016 02:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lniwn/85fc498e75ab945103eac5f50b669418 to your computer and use it in GitHub Desktop.
Save lniwn/85fc498e75ab945103eac5f50b669418 to your computer and use it in GitHub Desktop.
C++11实现的可以包容所有数据类型的Any容器
#pragma once
#include <memory>
#include <typeindex>
namespace C0xHelper
{
class Any
{
public:
Any(void): m_index(std::type_index(typeid(void))) {}
Any(const Any& that): m_ptr(that.Clone()), m_index(that.m_index) {}
Any(Any&& that): m_ptr(std::move(that.m_ptr)), m_index(that.m_index) {}
template<typename U, class = typename std::enable_if<!std::is_same<typename std::decay<U>::type, Any>::value, U>::type>
Any(U&& value) : m_ptr(new Derived<typename std::decay<U>::type>(std::forward<U>(value))),
m_index(std::type_index(typeid(typename std::decay<U>::type))) {}
bool IsNull() const { return !bool(m_ptr); }
template<typename U>
bool Is() const
{
return m_index == std::type_index(typeid(U));
}
template<typename U>
U& AnyCast()
{
if (!Is<U>())
{
throw std::bad_cast();
}
auto derived = dynamic_cast<Derived<U>*>(m_ptr.get());
return derived->m_value;
}
Any& operator=(const Any& that)
{
if (m_ptr == that.m_ptr)
{
return *this;
}
m_ptr = that.Clone();
m_index = that.m_index;
return *this;
}
private:
class Base;
typedef std::unique_ptr<Base> BasePtr;
class Base
{
public:
virtual ~Base(){}
virtual BasePtr Clone() const = 0;
};
template<typename T>
class Derived: public Base
{
public:
template<typename U>
Derived(U&& value): m_value(std::forward<U>(value)){}
BasePtr Clone() const
{
return BasePtr(new Derived<T>(m_value));
}
T m_value;
};
BasePtr Clone() const
{
if (m_ptr != nullptr)
{
return m_ptr->Clone();
}
return nullptr;
}
BasePtr m_ptr;
std::type_index m_index;
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment