Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class Some {
- template <typename T> struct type {
- static void id() {}
- };
- template <typename T> static size_t type_id() {
- return reinterpret_cast<size_t>(&type<T>::id);
- }
- template <typename T> using decay = typename std::decay<T>::type;
- template <typename T>
- using none = typename std::enable_if<!std::is_same<Some, T>::value>::type;
- struct base {
- virtual ~base() {}
- virtual bool is(size_t) const = 0;
- virtual base *copy() const = 0;
- } *p = nullptr;
- template <typename T> struct data : base, std::tuple<T> {
- using std::tuple<T>::tuple;
- T &get() & { return std::get<0>(*this); }
- T const &get() const & { return std::get<0>(*this); }
- bool is(size_t i) const override { return i == type_id<T>(); }
- base *copy() const override { return new data{get()}; }
- };
- template <typename T> T &stat() { return static_cast<data<T> &>(*p).get(); }
- template <typename T> T const &stat() const {
- return static_cast<data<T> const &>(*p).get();
- }
- template <typename T> T &dyn() { return dynamic_cast<data<T> &>(*p).get(); }
- template <typename T> T const &dyn() const {
- return dynamic_cast<data<T> const &>(*p).get();
- }
- size_t size_ = 0;
- public:
- Some() {}
- ~Some() { delete p; }
- Some(Some &&s) : p{s.p} {
- s.p = nullptr;
- size_ = s.size();
- }
- Some(Some const &s) : p{s.p->copy()} {}
- template <typename T, typename U = decay<T>, typename = none<U>>
- Some(T &&x) : p{new data<U>{std::forward<T>(x)}} {
- size_ = sizeof(U);
- }
- Some &operator=(Some s) {
- swap(*this, s);
- return *this;
- }
- friend void swap(Some &s, Some &r) { std::swap(s.p, r.p); }
- void clear() {
- delete p;
- p = nullptr;
- }
- bool empty() const { return p; }
- template <typename T> bool is() const {
- return p ? p->is(type_id<T>()) : false;
- }
- size_t size() const { return size_;}
- template <typename T> T &&get() && { return std::move(stat<T>()); }
- template <typename T> T &get() & { return stat<T>(); }
- template <typename T> T const &get() const & { return stat<T>(); }
- template <typename T> T &&cast() && { return std::move(dyn<T>()); }
- template <typename T> T &cast() & { return dyn<T>(); }
- template <typename T> T const &cast() const & { return dyn<T>(); }
- template <typename T> operator T &&() && { return std::move(get<T>()); }
- template <typename T> operator T &() & { return get<T>(); }
- template <typename T> operator T const &() const & { return get<T>(); }
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement