1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // UNSUPPORTED: c++03, c++11, c++14
10 // <optional>
11 
12 // optional<T>& operator=(nullopt_t) noexcept;
13 
14 #include <optional>
15 #include <type_traits>
16 #include <cassert>
17 
18 #include "test_macros.h"
19 #include "archetypes.h"
20 
21 using std::optional;
22 using std::nullopt_t;
23 using std::nullopt;
24 
test()25 TEST_CONSTEXPR_CXX20 bool test()
26 {
27     enum class State { inactive, constructed, destroyed };
28     State state = State::inactive;
29 
30     struct StateTracker {
31       TEST_CONSTEXPR_CXX20 StateTracker(State& s)
32       : state_(&s)
33       {
34         s = State::constructed;
35       }
36       TEST_CONSTEXPR_CXX20 ~StateTracker() { *state_ = State::destroyed; }
37 
38       State* state_;
39     };
40     {
41         optional<int> opt;
42         static_assert(noexcept(opt = nullopt) == true, "");
43         opt = nullopt;
44         assert(static_cast<bool>(opt) == false);
45     }
46     {
47         optional<int> opt(3);
48         opt = nullopt;
49         assert(static_cast<bool>(opt) == false);
50     }
51     {
52         optional<StateTracker> opt;
53         opt = nullopt;
54         assert(state == State::inactive);
55         assert(static_cast<bool>(opt) == false);
56     }
57     {
58         optional<StateTracker> opt(state);
59         assert(state == State::constructed);
60         opt = nullopt;
61         assert(state == State::destroyed);
62         assert(static_cast<bool>(opt) == false);
63     }
64     return true;
65 }
66 
67 
main(int,char **)68 int main(int, char**)
69 {
70 #if TEST_STD_VER > 17
71     static_assert(test());
72 #endif
73     test();
74     using TT = TestTypes::TestType;
75     TT::reset();
76     {
77         optional<TT> opt;
78         static_assert(noexcept(opt = nullopt) == true, "");
79         assert(TT::destroyed == 0);
80         opt = nullopt;
81         assert(TT::constructed == 0);
82         assert(TT::alive == 0);
83         assert(TT::destroyed == 0);
84         assert(static_cast<bool>(opt) == false);
85     }
86     assert(TT::alive == 0);
87     assert(TT::destroyed == 0);
88     TT::reset();
89     {
90         optional<TT> opt(42);
91         assert(TT::destroyed == 0);
92         TT::reset_constructors();
93         opt = nullopt;
94         assert(TT::constructed == 0);
95         assert(TT::alive == 0);
96         assert(TT::destroyed == 1);
97         assert(static_cast<bool>(opt) == false);
98     }
99     assert(TT::alive == 0);
100     assert(TT::destroyed == 1);
101     TT::reset();
102 
103   return 0;
104 }
105