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