Skip to content

Instantly share code, notes, and snippets.

@estshorter
Last active April 17, 2021 00:18
Show Gist options
  • Save estshorter/33d7fabd5cfa5dcaf6ff8997133715eb to your computer and use it in GitHub Desktop.
Save estshorter/33d7fabd5cfa5dcaf6ff8997133715eb to your computer and use it in GitHub Desktop.
c++ any implementation
// 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