File indexing completed on 2025-07-01 08:18:46
0001 #ifndef BOOST_LEAF_DETAIL_OPTIONAL_HPP_INCLUDED
0002 #define BOOST_LEAF_DETAIL_OPTIONAL_HPP_INCLUDED
0003
0004
0005
0006
0007
0008
0009 #include <boost/leaf/config.hpp>
0010
0011 #include <utility>
0012 #include <new>
0013
0014 namespace boost { namespace leaf {
0015
0016 namespace leaf_detail
0017 {
0018 template <class T>
0019 class optional
0020 {
0021 int key_;
0022 union { T value_; };
0023
0024 public:
0025
0026 typedef T value_type;
0027
0028 BOOST_LEAF_CONSTEXPR optional() noexcept:
0029 key_(0)
0030 {
0031 }
0032
0033 BOOST_LEAF_CONSTEXPR optional( optional const & x ):
0034 key_(x.key_)
0035 {
0036 if( x.key_ )
0037 (void) new (&value_) T( x.value_ );
0038 }
0039
0040 BOOST_LEAF_CONSTEXPR optional( optional && x ) noexcept:
0041 key_(x.key_)
0042 {
0043 if( x.key_ )
0044 {
0045 (void) new (&value_) T( std::move(x.value_) );
0046 x.reset();
0047 }
0048 }
0049
0050 BOOST_LEAF_CONSTEXPR optional( int key, T const & v ):
0051 key_(key),
0052 value_(v)
0053 {
0054 BOOST_LEAF_ASSERT(!empty());
0055 }
0056
0057 BOOST_LEAF_CONSTEXPR optional( int key, T && v ) noexcept:
0058 key_(key),
0059 value_(std::move(v))
0060 {
0061 BOOST_LEAF_ASSERT(!empty());
0062 }
0063
0064 BOOST_LEAF_CONSTEXPR optional & operator=( optional const & x )
0065 {
0066 reset();
0067 if( int key = x.key() )
0068 {
0069 load(key, x.value_);
0070 key_ = key;
0071 }
0072 return *this;
0073 }
0074
0075 BOOST_LEAF_CONSTEXPR optional & operator=( optional && x ) noexcept
0076 {
0077 reset();
0078 if( int key = x.key() )
0079 {
0080 load(key, std::move(x.value_));
0081 x.reset();
0082 }
0083 return *this;
0084 }
0085
0086 ~optional() noexcept
0087 {
0088 reset();
0089 }
0090
0091 BOOST_LEAF_CONSTEXPR bool empty() const noexcept
0092 {
0093 return key_==0;
0094 }
0095
0096 BOOST_LEAF_CONSTEXPR int key() const noexcept
0097 {
0098 return key_;
0099 }
0100
0101 BOOST_LEAF_CONSTEXPR void reset() noexcept
0102 {
0103 if( key_ )
0104 {
0105 value_.~T();
0106 key_=0;
0107 }
0108 }
0109
0110 BOOST_LEAF_CONSTEXPR T & load( int key )
0111 {
0112 BOOST_LEAF_ASSERT(key);
0113 reset();
0114 (void) new(&value_) T;
0115 key_=key;
0116 return value_;
0117 }
0118
0119 BOOST_LEAF_CONSTEXPR T & load( int key, T const & v )
0120 {
0121 BOOST_LEAF_ASSERT(key);
0122 reset();
0123 (void) new(&value_) T(v);
0124 key_=key;
0125 return value_;
0126 }
0127
0128 BOOST_LEAF_CONSTEXPR T & load( int key, T && v ) noexcept
0129 {
0130 BOOST_LEAF_ASSERT(key);
0131 reset();
0132 (void) new(&value_) T(std::move(v));
0133 key_=key;
0134 return value_;
0135 }
0136
0137 BOOST_LEAF_CONSTEXPR T const * has_value() const noexcept
0138 {
0139 return key_ ? &value_ : nullptr;
0140 }
0141
0142 BOOST_LEAF_CONSTEXPR T * has_value() noexcept
0143 {
0144 return key_ ? &value_ : nullptr;
0145 }
0146
0147 BOOST_LEAF_CONSTEXPR T const * has_value(int key) const noexcept
0148 {
0149 BOOST_LEAF_ASSERT(key);
0150 return key_==key ? &value_ : nullptr;
0151 }
0152
0153 BOOST_LEAF_CONSTEXPR T * has_value(int key) noexcept
0154 {
0155 BOOST_LEAF_ASSERT(key);
0156 return key_==key ? &value_ : nullptr;
0157 }
0158
0159 BOOST_LEAF_CONSTEXPR T const & value(int key) const & noexcept
0160 {
0161 BOOST_LEAF_ASSERT(has_value(key) != 0);
0162 (void) key;
0163 return value_;
0164 }
0165
0166 BOOST_LEAF_CONSTEXPR T & value(int key) & noexcept
0167 {
0168 BOOST_LEAF_ASSERT(has_value(key) != 0);
0169 (void) key;
0170 return value_;
0171 }
0172
0173 BOOST_LEAF_CONSTEXPR T const && value(int key) const && noexcept
0174 {
0175 BOOST_LEAF_ASSERT(has_value(key) != 0);
0176 (void) key;
0177 return value_;
0178 }
0179
0180 BOOST_LEAF_CONSTEXPR T value(int key) && noexcept
0181 {
0182 BOOST_LEAF_ASSERT(has_value(key) != 0);
0183 (void) key;
0184 T tmp(std::move(value_));
0185 reset();
0186 return tmp;
0187 }
0188 };
0189
0190 }
0191
0192 } }
0193
0194 #endif