in_chainz

Untitled

Mar 20th, 2019
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.36 KB | None | 0 0
  1. #include<iostream>
  2. #include <memory>
  3. #include <cstddef>
  4.  
  5.  
  6. struct BadOptionalAccess {
  7. };
  8.  
  9. template <typename T>
  10. class Optional {
  11. private:
  12.     // alignas нужен для правильного выравнивания блока памяти
  13.     alignas(T) unsigned char data[sizeof(T)];
  14.     bool defined = false;
  15.  
  16. public:
  17.     Optional() = default;
  18.     Optional(const T& elem) {
  19.         new (data) T(elem);
  20.         defined = true;
  21.     }
  22.     Optional(T&& elem) {
  23.         new (data) T(std::move(elem));
  24.         defined = true;
  25.     }
  26.     Optional(const Optional& other) {
  27.         new (data) T(*reinterpret_cast<T*>(other.data));
  28.         defined = other.defined;
  29.     }
  30.  
  31.     Optional& operator=(const Optional& other) {
  32.         if (defined)
  33.             reinterpret_cast<T*>(data)->~T();
  34.  
  35.         new (data) T(*reinterpret_cast<const T*>(other.data));
  36.         defined = other.defined;
  37.         return *this;
  38.     }
  39.  
  40.     Optional& operator=(const T& elem) {
  41.         if (defined) {
  42.             *reinterpret_cast<T*>(data) = elem;
  43.             return *this;
  44.         }
  45.  
  46.         new (data) T(elem);
  47.         defined = true;
  48.         return *this;
  49.     }
  50.  
  51.     Optional& operator=(T&& elem) {
  52.         if (defined) {
  53.             *reinterpret_cast<T*>(data) = std::move(elem);
  54.             return *this;
  55.         }
  56.  
  57.         new (data) T(std::move(elem));
  58.         defined = true;
  59.         return *this;
  60.     }
  61.  
  62.     bool has_value() const {
  63.         return defined;
  64.     }
  65.  
  66.     T& operator*() {
  67.         return *reinterpret_cast<T*>(data);
  68.     }
  69.     const T& operator*() const {
  70.         return *reinterpret_cast<const T*>(data);
  71.     }
  72.  
  73.     T* operator->() {
  74.         return reinterpret_cast<T*>(data);
  75.     }
  76.     const T* operator->() const {
  77.         return reinterpret_cast<const T*>(data);
  78.     }
  79.  
  80.     T& value() {
  81.         if (!defined) {
  82.             throw BadOptionalAccess();
  83.         }
  84.         return *reinterpret_cast<T*>(data);
  85.     }
  86.     const T& value() const {
  87.         if (!defined) {
  88.             throw BadOptionalAccess();
  89.         }
  90.         return *reinterpret_cast<const T*>(data);
  91.  
  92.     }
  93.  
  94.     void reset() {
  95.         if (defined) {
  96.             reinterpret_cast<T *>(data)->~T();
  97.             defined = false;
  98.         }
  99.     }
  100.  
  101.     ~Optional() {
  102.         if (defined) {
  103.             reinterpret_cast<T*>(data)->~T();
  104.         }
  105.     }
  106. };
Advertisement
Add Comment
Please, Sign In to add comment