Last active
April 17, 2021 00:18
-
-
Save estshorter/33d7fabd5cfa5dcaf6ff8997133715eb to your computer and use it in GitHub Desktop.
c++ any implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// http://staryoshi.hatenablog.com/entry/2015/10/27/173925 | |
#include <iostream> | |
#include <memory> | |
class Any { | |
private: | |
struct base { | |
virtual std::type_info const& type() const { return typeid(nullptr); } | |
virtual std::unique_ptr<base> clone() const { return nullptr; } | |
}; | |
template<class T> | |
struct derived :public base { | |
T data; | |
derived(T const& it) : data(it) { | |
} | |
template<class ...Args> | |
derived(Args ...args) : data(args) {} | |
std::unique_ptr<base> clone() const override { return std::make_unique < derived<T>>(data); } | |
std::type_info const& type() const override { return typeid(data); } | |
}; | |
public: | |
Any() {}; | |
template<class T> | |
Any(T const& it) : data(new derived<T>(it)) { | |
}; | |
Any(Any const& it) : data(std::make_unique<base>(*it.data)) {} | |
Any(Any&& it) : data(std::move(it.data)) {} | |
Any& operator=(Any const& it) { | |
data = it.data->clone(); | |
return *this; | |
} | |
Any& operator=(Any&& it) { | |
data = std::move(it.data); | |
return *this; | |
} | |
template <typename T> | |
Any& operator = (T const& it) { | |
data = std::make_unique<derived<T>>(it); | |
return *this; | |
} | |
template <class T> | |
T& get() const { | |
auto p = dynamic_cast<derived<T>*>(data.get()); | |
if (p == nullptr) { | |
throw std::bad_cast(); | |
} | |
return p->data; | |
} | |
std::type_info const& type() const { | |
return data->type(); | |
} | |
private: | |
std::unique_ptr<base> data; | |
}; | |
int main(void) { | |
int input = 4; | |
Any any = input; // construct & copy | |
printf("%s\n", any.type().name()); | |
printf("%d\n", any.get<decltype(input)>()); | |
Any any2; | |
any2 = any; // copy | |
printf("%s\n", any2.type().name()); | |
printf("%d\n", any2.get<decltype(input)>()); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment