SHARE
TWEET

Untitled

a guest Oct 19th, 2019 64 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Это исключение нужно генерировать в функции value
  2. // при обращении к пустому объекту Optional
  3. struct BadOptionalAccess {
  4. };
  5.  
  6. #include <utility>
  7.  
  8. template <typename T>
  9. class Optional {
  10. private:
  11.     // alignas нужен для правильного выравнивания блока памяти
  12.     alignas(T) unsigned char data[sizeof(T)];
  13.     bool defined = false;
  14.  
  15. public:
  16.     Optional() = default;
  17.     Optional(const T& elem) : defined(true) {
  18.         new (data) T(elem);
  19.     }
  20.     Optional(T&& elem) : defined(true) {
  21.         new (data) T(std :: move(elem));
  22.     }
  23.     Optional(const Optional& other) : defined(other.defined) {
  24.         new (data) T(*reinterpret_cast<T*>(other.data));
  25.     }
  26.  
  27.     Optional& operator=(const Optional& other) {
  28.         if (!other.defined) {
  29.             if (defined) {
  30.                 defined = false;
  31.                 reinterpret_cast<T*>(data)->~T();
  32.             }
  33.         } else {
  34.             if (defined) {
  35.                 *reinterpret_cast<T*>(data) = *reinterpret_cast<const T*>(other.data);
  36.             } else {
  37.                 defined = true;
  38.                 new (data) T(*reinterpret_cast<const T*>(other.data));
  39.             }
  40.         }
  41.         return *this;
  42.     }
  43.     Optional& operator=(const T& elem) {
  44.         if (defined) *reinterpret_cast<T*>(data) = elem;
  45.         else {
  46.             defined = true;
  47.             new (data) T(elem);
  48.         }
  49.         return *this;
  50.     }
  51.     Optional& operator=(T&& elem) {
  52.         if (defined) *reinterpret_cast<T*>(data) = std :: move(elem);
  53.         else {
  54.             defined = true;
  55.             new (data) T(elem);
  56.         }
  57.         return *this;
  58.     }
  59.  
  60.     bool has_value() const { return defined; }
  61.  
  62.     T& operator*() {
  63.         if (!defined)
  64.             throw BadOptionalAccess();
  65.         return *reinterpret_cast<T*>(data);
  66.     }
  67.     const T& operator*() const {
  68.         if (!defined)
  69.             throw BadOptionalAccess();
  70.         return *reinterpret_cast<const T*>(data);  
  71.     }
  72.  
  73.     T* operator->() {
  74.         if (!defined)
  75.             throw BadOptionalAccess();
  76.         return reinterpret_cast<T*>(data);
  77.     }
  78.     const T* operator->() const {
  79.         if (!defined)
  80.             throw BadOptionalAccess();
  81.         return reinterpret_cast<const T*>(data);
  82.     }
  83.  
  84.     T& value() {
  85.         if (!defined)
  86.             throw BadOptionalAccess();
  87.         return *reinterpret_cast<T*>(data);
  88.     }
  89.     const T& value() const {
  90.         if (!defined)
  91.             throw BadOptionalAccess();
  92.         return *reinterpret_cast<const T*>(data);
  93.     }
  94.  
  95.     void reset() {
  96.         if (defined)
  97.             reinterpret_cast<T*>(data)->~T();
  98.         defined = false;
  99.     }
  100.  
  101.     ~Optional() {
  102.         if (defined)
  103.             reinterpret_cast<T*>(data)->~T();
  104.     }
  105. };
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top