3#if __cplusplus
>= 201703L
17 explicit constexpr nullopt_t(
int) {}
19constexpr nullopt_t nullopt{0};
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
44 bool has_value_ =
false;
45 alignas(T)
unsigned char storage_[
sizeof(T)];
48 optional()
noexcept =
default;
49 optional(nullopt_t)
noexcept {}
50 optional(
const T& value) {
new (storage_) T(value); has_value_ =
true; }
51 optional(T&& value) {
new (storage_) T(std::move(value)); has_value_ =
true; }
52 optional(
const optional& other) {
53 if (other.has_value_) {
54 new (storage_) T(other.value());
58 optional(optional&& other)
noexcept {
59 if (other.has_value_) {
60 new (storage_) T(std::move(other.value()));
65 ~optional() { reset(); }
67 optional& operator=(nullopt_t)
noexcept {
71 optional& operator=(
const optional& other) {
74 if (other.has_value_) {
75 new (storage_) T(other.value());
81 optional& operator=(optional&& other)
noexcept {
84 if (other.has_value_) {
85 new (storage_) T(std::move(other.value()));
93 bool has_value()
const noexcept {
return has_value_; }
94 explicit operator
bool()
const noexcept {
return has_value_; }
97 if (!has_value_)
throw std::runtime_error(
"Bad optional access");
98 return *
reinterpret_cast<T*>(storage_);
100 const T& value()
const {
101 if (!has_value_)
throw std::runtime_error(
"Bad optional access");
102 return *
reinterpret_cast<
const T*>(storage_);
104 T value_or(
const T& default_value)
const {
105 return has_value_ ? value() : default_value;
109 reinterpret_cast<T*>(storage_)->~T();