Skip to content

Instantly share code, notes, and snippets.

@ay27
Created October 5, 2019 02:52
Show Gist options
  • Save ay27/baee5aeb9a55bbc56a62f92214cf0ed1 to your computer and use it in GitHub Desktop.
Save ay27/baee5aeb9a55bbc56a62f92214cf0ed1 to your computer and use it in GitHub Desktop.
[Any implementation in cpp] #any #cpp
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>(); }
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment