File indexing completed on 2025-01-18 09:39:11
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 put(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 put(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 & put( 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 & put( 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 & put( 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(int key) const noexcept
0138 {
0139 BOOST_LEAF_ASSERT(key);
0140 return key_==key ? &value_ : nullptr;
0141 }
0142
0143 BOOST_LEAF_CONSTEXPR T * has_value(int key) noexcept
0144 {
0145 BOOST_LEAF_ASSERT(key);
0146 return key_==key ? &value_ : nullptr;
0147 }
0148
0149 BOOST_LEAF_CONSTEXPR T const & value(int key) const & noexcept
0150 {
0151 BOOST_LEAF_ASSERT(has_value(key) != 0);
0152 (void) key;
0153 return value_;
0154 }
0155
0156 BOOST_LEAF_CONSTEXPR T & value(int key) & noexcept
0157 {
0158 BOOST_LEAF_ASSERT(has_value(key) != 0);
0159 (void) key;
0160 return value_;
0161 }
0162
0163 BOOST_LEAF_CONSTEXPR T const && value(int key) const && noexcept
0164 {
0165 BOOST_LEAF_ASSERT(has_value(key) != 0);
0166 (void) key;
0167 return value_;
0168 }
0169
0170 BOOST_LEAF_CONSTEXPR T value(int key) && noexcept
0171 {
0172 BOOST_LEAF_ASSERT(has_value(key) != 0);
0173 (void) key;
0174 T tmp(std::move(value_));
0175 reset();
0176 return tmp;
0177 }
0178 };
0179
0180 }
0181
0182 } }
0183
0184 #endif