optional.hpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. #ifndef BOOST_LEAF_DETAIL_OPTIONAL_HPP_INCLUDED
  2. #define BOOST_LEAF_DETAIL_OPTIONAL_HPP_INCLUDED
  3. /// Copyright (c) 2018-2021 Emil Dotchevski and Reverge Studios, Inc.
  4. /// Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. /// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #ifndef BOOST_LEAF_ENABLE_WARNINGS ///
  7. # if defined(_MSC_VER) ///
  8. # pragma warning(push,1) ///
  9. # elif defined(__clang__) ///
  10. # pragma clang system_header ///
  11. # elif (__GNUC__*100+__GNUC_MINOR__>301) ///
  12. # pragma GCC system_header ///
  13. # endif ///
  14. #endif ///
  15. #include <boost/leaf/detail/config.hpp>
  16. #include <utility>
  17. #include <new>
  18. namespace boost { namespace leaf {
  19. namespace leaf_detail
  20. {
  21. template <class T>
  22. class optional
  23. {
  24. int key_;
  25. union { T value_; };
  26. public:
  27. typedef T value_type;
  28. BOOST_LEAF_CONSTEXPR optional() noexcept:
  29. key_(0)
  30. {
  31. }
  32. BOOST_LEAF_CONSTEXPR optional( optional const & x ):
  33. key_(x.key_)
  34. {
  35. if( x.key_ )
  36. (void) new (&value_) T( x.value_ );
  37. }
  38. BOOST_LEAF_CONSTEXPR optional( optional && x ) noexcept:
  39. key_(x.key_)
  40. {
  41. if( x.key_ )
  42. {
  43. (void) new (&value_) T( std::move(x.value_) );
  44. x.reset();
  45. }
  46. }
  47. BOOST_LEAF_CONSTEXPR optional( int key, T const & v ):
  48. key_(key),
  49. value_(v)
  50. {
  51. BOOST_LEAF_ASSERT(!empty());
  52. }
  53. BOOST_LEAF_CONSTEXPR optional( int key, T && v ) noexcept:
  54. key_(key),
  55. value_(std::move(v))
  56. {
  57. BOOST_LEAF_ASSERT(!empty());
  58. }
  59. BOOST_LEAF_CONSTEXPR optional & operator=( optional const & x )
  60. {
  61. reset();
  62. if( int key = x.key() )
  63. {
  64. put(key, x.value_);
  65. key_ = key;
  66. }
  67. return *this;
  68. }
  69. BOOST_LEAF_CONSTEXPR optional & operator=( optional && x ) noexcept
  70. {
  71. reset();
  72. if( int key = x.key() )
  73. {
  74. put(key, std::move(x.value_));
  75. x.reset();
  76. }
  77. return *this;
  78. }
  79. ~optional() noexcept
  80. {
  81. reset();
  82. }
  83. BOOST_LEAF_CONSTEXPR bool empty() const noexcept
  84. {
  85. return key_==0;
  86. }
  87. BOOST_LEAF_CONSTEXPR int key() const noexcept
  88. {
  89. return key_;
  90. }
  91. BOOST_LEAF_CONSTEXPR void reset() noexcept
  92. {
  93. if( key_ )
  94. {
  95. value_.~T();
  96. key_=0;
  97. }
  98. }
  99. BOOST_LEAF_CONSTEXPR T & put( int key, T const & v )
  100. {
  101. BOOST_LEAF_ASSERT(key);
  102. reset();
  103. (void) new(&value_) T(v);
  104. key_=key;
  105. return value_;
  106. }
  107. BOOST_LEAF_CONSTEXPR T & put( int key, T && v ) noexcept
  108. {
  109. BOOST_LEAF_ASSERT(key);
  110. reset();
  111. (void) new(&value_) T(std::move(v));
  112. key_=key;
  113. return value_;
  114. }
  115. BOOST_LEAF_CONSTEXPR T const * has_value(int key) const noexcept
  116. {
  117. BOOST_LEAF_ASSERT(key);
  118. return key_==key ? &value_ : 0;
  119. }
  120. BOOST_LEAF_CONSTEXPR T * has_value(int key) noexcept
  121. {
  122. BOOST_LEAF_ASSERT(key);
  123. return key_==key ? &value_ : 0;
  124. }
  125. BOOST_LEAF_CONSTEXPR T const & value(int key) const & noexcept
  126. {
  127. BOOST_LEAF_ASSERT(has_value(key) != 0);
  128. return value_;
  129. }
  130. BOOST_LEAF_CONSTEXPR T & value(int key) & noexcept
  131. {
  132. BOOST_LEAF_ASSERT(has_value(key) != 0);
  133. return value_;
  134. }
  135. BOOST_LEAF_CONSTEXPR T const && value(int key) const && noexcept
  136. {
  137. BOOST_LEAF_ASSERT(has_value(key) != 0);
  138. return value_;
  139. }
  140. BOOST_LEAF_CONSTEXPR T value(int key) && noexcept
  141. {
  142. BOOST_LEAF_ASSERT(has_value(key) != 0);
  143. T tmp(std::move(value_));
  144. reset();
  145. return tmp;
  146. }
  147. };
  148. }
  149. } }
  150. #if defined(_MSC_VER) && !defined(BOOST_LEAF_ENABLE_WARNINGS) ///
  151. #pragma warning(pop) ///
  152. #endif ///
  153. #endif