3#if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
12 explicit constexpr nullopt_t(
int)
noexcept {}
14inline constexpr nullopt_t nullopt{0};
16class bad_optional_access :
public exception {
18 bad_optional_access() =
default;
19 virtual ~bad_optional_access() =
default;
21 const char *what() const noexcept
override {
22 return "bad optional access";
35 constexpr optional() noexcept : dummy(0), engaged(false) {}
36 constexpr optional(nullopt_t) noexcept : dummy(0), engaged(
false) {}
38 optional(
const optional &other) {
39 engaged = other.engaged;
46 optional(optional &&other)
noexcept(is_nothrow_move_constructible_v<T>) {
47 engaged = other.engaged;
54 optional(T &&u) : val(std::forward<T>(u)), engaged(true) {}
56 optional(
const T &t) : val(t), engaged(true) {}
58 optional &operator=(
const optional &other) {
59 engaged = other.engaged;
67 optional &operator=(
const T &other) {
75 optional &operator=(T &&other) {
90 constexpr operator bool()
const {
93 constexpr bool has_value()
const {
97 constexpr T &operator*() & {
100 constexpr const T &operator*() const & {
103 constexpr T &&operator*() && {
104 return std::move(val);
106 constexpr const T &&operator*() const && {
107 return std::move(val);
111 return engaged ? val :
throw bad_optional_access();
113 const T &value() const & {
114 return engaged ? val :
throw bad_optional_access();
117 return engaged ? std::move(val) : throw bad_optional_access();
119 const T &&value() const && {
120 return engaged ? std::move(val) : throw bad_optional_access();
124 T value_or(U &&u)
const {
125 return engaged ? val :
static_cast<T
>(std::forward<U>(u));