Advertisement
Guest User

Untitled

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