optional.hpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. #ifndef __XRCU_OPTIONAL_HPP__
  2. #define __XRCU_OPTIONAL_HPP__ 1
  3. #include <utility>
  4. namespace xrcu
  5. {
  6. template <class T>
  7. struct optional
  8. {
  9. T *xptr;
  10. alignas (alignof (T)) char buf[sizeof (T)];
  11. T* _Ptr ()
  12. {
  13. return ((T *)&this->buf[0]);
  14. }
  15. const T* _Ptr () const
  16. {
  17. return ((const T *)&this->buf[0]);
  18. }
  19. void _Init (const T& value)
  20. {
  21. new (this->_Ptr ()) T (value);
  22. this->xptr = this->_Ptr ();
  23. }
  24. void _Init (T&& value)
  25. {
  26. new (this->_Ptr ()) T (std::forward<T&&> (value));
  27. this->xptr = this->_Ptr ();
  28. }
  29. optional () : xptr (nullptr)
  30. {
  31. }
  32. optional (const T& value)
  33. {
  34. this->_Init (value);
  35. }
  36. optional (const optional<T>& right) : xptr (nullptr)
  37. {
  38. if (right.xptr)
  39. this->_Init (*right);
  40. }
  41. optional (T&& value)
  42. {
  43. this->_Init (std::forward<T&&> (value));
  44. }
  45. optional (optional<T>&& right) : xptr (nullptr)
  46. {
  47. if (right.xptr)
  48. {
  49. this->_Init (std::forward<T&&> (*right));
  50. right.xptr = nullptr;
  51. }
  52. }
  53. T& operator* ()
  54. {
  55. return (*this->xptr);
  56. }
  57. const T& operator* () const
  58. {
  59. return (*this->xptr);
  60. }
  61. T* operator-> ()
  62. {
  63. return (this->xptr);
  64. }
  65. const T* operator-> () const
  66. {
  67. return (this->xptr);
  68. }
  69. bool has_value () const
  70. {
  71. return (this->xptr != nullptr);
  72. }
  73. void reset ()
  74. {
  75. if (!this->xptr)
  76. return;
  77. this->xptr->~T ();
  78. this->xptr = nullptr;
  79. }
  80. optional<T>& operator= (const optional<T>& right)
  81. {
  82. if (&right == this)
  83. ;
  84. else if (!right.xptr)
  85. this->reset ();
  86. else if (!this->xptr)
  87. this->_Init (*right);
  88. else
  89. **this = *right;
  90. return (*this);
  91. }
  92. optional<T>& operator= (optional<T>&& right)
  93. {
  94. if (&right == this)
  95. return (*this);
  96. if (!right.xptr)
  97. this->reset ();
  98. else if (!this->xptr)
  99. this->_Init (std::forward<T&&> (*right));
  100. else
  101. **this = std::forward<T&&> (*right);
  102. right.xptr = nullptr;
  103. return (*this);
  104. }
  105. optional<T>& operator= (const T& value)
  106. {
  107. if (!this->xptr)
  108. this->_Init (value);
  109. else
  110. **this = value;
  111. return (*this);
  112. }
  113. optional<T>& operator= (T&& value)
  114. {
  115. if (!this->xptr)
  116. this->_Init (std::forward<T&&> (value));
  117. else
  118. **this = std::forward<T&&> (value);
  119. return (*this);
  120. }
  121. ~optional ()
  122. {
  123. this->reset ();
  124. }
  125. };
  126. } // namespace xrcu
  127. #endif