Created
May 10, 2018 17:58
-
-
Save goldsborough/3125d3dd844f909cabffa454f10a0a1f to your computer and use it in GitHub Desktop.
Basic implementation of Any
This file contains hidden or 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
class Any { | |
public: | |
template<typename T> | |
explicit Any(T&& value) : content_(new Holder<T>(std::forward<T>(value))) {} | |
Any(const Any& other) : content_(other.content_->clone()) {} | |
Any(Any&& other) { swap(other); } | |
Any& operator=(Any other) { | |
swap(other); | |
return *this; | |
} | |
void swap(Any& other) { | |
using std::swap; | |
swap(this->content_, other.content_); | |
} | |
friend void swap(Any& first, Any& second) { | |
first.swap(second); | |
} | |
template<typename T> | |
T& get() { | |
if (typeid(T) != content_->type_info) { | |
throw std::bad_cast(); | |
} | |
return static_cast<Holder<T>&>(*content_).value_; | |
} | |
private: | |
struct Placeholder { | |
Placeholder(const std::type_info& type_info_) : type_info(type_info_) {} | |
virtual ~Placeholder() = default; | |
virtual std::unique_ptr<Placeholder> clone() const = 0; | |
const std::type_info& type_info; | |
}; | |
template<typename T> | |
struct Holder : public Placeholder { | |
template<typename U> | |
explicit Holder(U&& value) : Placeholder(typeid(T)), value_(std::forward<U>(value)) {} | |
std::unique_ptr<Placeholder> clone() const override { | |
return std::unique_ptr<Holder<T>>(new Holder<T>(value_)); | |
} | |
T value_; | |
}; | |
std::unique_ptr<Placeholder> content_; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment