Advertisement
Guest User

Untitled

a guest
Oct 23rd, 2019
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.42 KB | None | 0 0
  1. class Some {
  2.  
  3. template <typename T> struct type {
  4. static void id() {}
  5. };
  6.  
  7. template <typename T> static size_t type_id() {
  8. return reinterpret_cast<size_t>(&type<T>::id);
  9. }
  10.  
  11. template <typename T> using decay = typename std::decay<T>::type;
  12.  
  13. template <typename T>
  14. using none = typename std::enable_if<!std::is_same<Some, T>::value>::type;
  15.  
  16. struct base {
  17. virtual ~base() {}
  18. virtual bool is(size_t) const = 0;
  19. virtual base *copy() const = 0;
  20. } *p = nullptr;
  21.  
  22. template <typename T> struct data : base, std::tuple<T> {
  23. using std::tuple<T>::tuple;
  24.  
  25. T &get() & { return std::get<0>(*this); }
  26. T const &get() const & { return std::get<0>(*this); }
  27.  
  28. bool is(size_t i) const override { return i == type_id<T>(); }
  29. base *copy() const override { return new data{get()}; }
  30. };
  31.  
  32. template <typename T> T &stat() { return static_cast<data<T> &>(*p).get(); }
  33.  
  34. template <typename T> T const &stat() const {
  35. return static_cast<data<T> const &>(*p).get();
  36. }
  37.  
  38. template <typename T> T &dyn() { return dynamic_cast<data<T> &>(*p).get(); }
  39.  
  40. template <typename T> T const &dyn() const {
  41. return dynamic_cast<data<T> const &>(*p).get();
  42. }
  43.  
  44. size_t size_ = 0;
  45.  
  46. public:
  47. Some() {}
  48. ~Some() { delete p; }
  49.  
  50. Some(Some &&s) : p{s.p} {
  51. s.p = nullptr;
  52. size_ = s.size();
  53. }
  54. Some(Some const &s) : p{s.p->copy()} {}
  55.  
  56. template <typename T, typename U = decay<T>, typename = none<U>>
  57. Some(T &&x) : p{new data<U>{std::forward<T>(x)}} {
  58. size_ = sizeof(U);
  59. }
  60.  
  61. Some &operator=(Some s) {
  62. swap(*this, s);
  63. return *this;
  64. }
  65.  
  66. friend void swap(Some &s, Some &r) { std::swap(s.p, r.p); }
  67.  
  68. void clear() {
  69. delete p;
  70. p = nullptr;
  71. }
  72.  
  73. bool empty() const { return p; }
  74.  
  75. template <typename T> bool is() const {
  76. return p ? p->is(type_id<T>()) : false;
  77. }
  78.  
  79. size_t size() const { return size_;}
  80.  
  81. template <typename T> T &&get() && { return std::move(stat<T>()); }
  82. template <typename T> T &get() & { return stat<T>(); }
  83. template <typename T> T const &get() const & { return stat<T>(); }
  84.  
  85. template <typename T> T &&cast() && { return std::move(dyn<T>()); }
  86. template <typename T> T &cast() & { return dyn<T>(); }
  87. template <typename T> T const &cast() const & { return dyn<T>(); }
  88.  
  89. template <typename T> operator T &&() && { return std::move(get<T>()); }
  90. template <typename T> operator T &() & { return get<T>(); }
  91. template <typename T> operator T const &() const & { return get<T>(); }
  92. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement