Skip to content

Instantly share code, notes, and snippets.

@xzhong86
Last active April 18, 2024 12:06
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 xzhong86/c8b9ba1f4789f14d1615d9172eaaf127 to your computer and use it in GitHub Desktop.
Save xzhong86/c8b9ba1f4789f14d1615d9172eaaf127 to your computer and use it in GitHub Desktop.
Simple Any implementation in C++ 11.

Simple Any Implementation

A simple implementation of 'any' type in c++11.

refer to cnblogs.com/qiconmos/p/3420095.html

#include <memory> // for unique_ptr
#include <utility> // for forward
#include <typeindex> // for type_index
//Any, refere to cnblogs.com/qiconmos/p/3420095.html, keyword: c++11 any
class Any {
struct Base;
typedef std::unique_ptr<Base> BasePtr;
struct Base {
virtual ~Base() {}
virtual BasePtr clone() const = 0;
};
template <typename T>
struct Derived : Base {
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) return m_ptr->clone();
return nullptr;
}
BasePtr m_ptr;
std::type_index m_tpIndex;
public:
Any(void) : m_tpIndex(std::type_index(typeid(void))) {}
Any(const Any &a) : m_ptr(a.clone()), m_tpIndex(a.m_tpIndex) {}
Any(Any &&a) : m_ptr(std::move(a.m_ptr)), m_tpIndex(a.m_tpIndex) {}
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_tpIndex(std::type_index(typeid(typename std::decay<U>::type)))
{ }
bool isNull() const { return !bool(m_ptr); }
bool isValid() const { return bool(m_ptr); }
template <class U> bool is() const {
return m_tpIndex == std::type_index(typeid(U));
}
template <class U>
U & cast() {
if (!is<U>()) throw std::bad_cast();
auto derived = dynamic_cast<Derived<U>*>(m_ptr.get());
return derived->m_value;
}
Any & operator = (const Any & a) {
if (m_ptr == a.m_ptr) return *this;
m_ptr = a.clone();
m_tpIndex = a.m_tpIndex;
return *this;
}
const char* typeName() const { return m_tpIndex.name(); }
};
#include <string>
#include <iostream>
int main() {
int int_aa = 11;
std::string hello("hello");
Any aa(int_aa);
Any bb(hello);
Any cc(&hello);
std::cout << "any of int = " << aa.cast<int>() << std::endl;
std::cout << "any of string = " << bb.cast<std::string>() << std::endl;
std::cout << "any of string* = " << *(cc.cast<std::string*>()) << std::endl;
}
// g++ -Wall -std=c++11 simple-any.cpp
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment