xref: /llvm-project/libcxx/test/std/utilities/expected/expected.expected/dtor.pass.cpp (revision 6a54dfbfe534276d644d7f9c027f0deeb748dd53)
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, c++17, c++20
10 
11 // constexpr ~expected();
12 //
13 // Effects: If has_value() is true, destroys val, otherwise destroys unex.
14 //
15 // Remarks: If is_trivially_destructible_v<T> is true, and is_trivially_destructible_v<E> is true,
16 // then this destructor is a trivial destructor.
17 
18 #include <cassert>
19 #include <expected>
20 #include <type_traits>
21 #include <utility>
22 #include <memory>
23 
24 #include "test_macros.h"
25 
26 // Test Remarks: If is_trivially_destructible_v<T> is true, and is_trivially_destructible_v<E> is true,
27 // then this destructor is a trivial destructor.
28 struct NonTrivial {
29   ~NonTrivial() {}
30 };
31 
32 static_assert(std::is_trivially_destructible_v<std::expected<int, int>>);
33 static_assert(!std::is_trivially_destructible_v<std::expected<NonTrivial, int>>);
34 static_assert(!std::is_trivially_destructible_v<std::expected<int, NonTrivial>>);
35 static_assert(!std::is_trivially_destructible_v<std::expected<NonTrivial, NonTrivial>>);
36 
37 struct TrackedDestroy {
38   bool& destroyed;
39   constexpr TrackedDestroy(bool& b) : destroyed(b) {}
40   constexpr ~TrackedDestroy() { destroyed = true; }
41 };
42 
43 constexpr bool test() {
44   // has value
45   {
46     bool valueDestroyed = false;
47     { [[maybe_unused]] std::expected<TrackedDestroy, TrackedDestroy> e(std::in_place, valueDestroyed); }
48     assert(valueDestroyed);
49   }
50 
51   // has error
52   {
53     bool errorDestroyed = false;
54     { [[maybe_unused]] std::expected<TrackedDestroy, TrackedDestroy> e(std::unexpect, errorDestroyed); }
55     assert(errorDestroyed);
56   }
57 
58   return true;
59 }
60 
61 int main(int, char**) {
62   std::expected<std::unique_ptr<int>, int> a = std::make_unique<int>(42);
63 
64   test();
65   static_assert(test());
66   return 0;
67 }
68