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