xref: /llvm-project/libcxx/test/std/utilities/expected/expected.expected/assign/emplace.pass.cpp (revision 6a54dfbfe534276d644d7f9c027f0deeb748dd53)
1e356f681SHui Xie //===----------------------------------------------------------------------===//
2*6a54dfbfSLouis Dionne //
3e356f681SHui Xie // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e356f681SHui Xie // See https://llvm.org/LICENSE.txt for license information.
5e356f681SHui Xie // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e356f681SHui Xie //
7e356f681SHui Xie //===----------------------------------------------------------------------===//
8e356f681SHui Xie 
9e356f681SHui Xie // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
10e356f681SHui Xie 
11e356f681SHui Xie // template<class... Args>
12e356f681SHui Xie //   constexpr T& emplace(Args&&... args) noexcept;
13e356f681SHui Xie // Constraints: is_nothrow_constructible_v<T, Args...> is true.
14e356f681SHui Xie //
15e356f681SHui Xie // Effects: Equivalent to:
16e356f681SHui Xie // if (has_value()) {
17e356f681SHui Xie //   destroy_at(addressof(val));
18e356f681SHui Xie // } else {
19e356f681SHui Xie //   destroy_at(addressof(unex));
20e356f681SHui Xie //   has_val = true;
21e356f681SHui Xie // }
22e356f681SHui Xie // return *construct_at(addressof(val), std::forward<Args>(args)...);
23e356f681SHui Xie 
24e356f681SHui Xie #include <cassert>
25e356f681SHui Xie #include <concepts>
26e356f681SHui Xie #include <expected>
27e356f681SHui Xie #include <type_traits>
28e356f681SHui Xie #include <utility>
29e356f681SHui Xie 
30e356f681SHui Xie #include "../../types.h"
31e356f681SHui Xie #include "test_macros.h"
32e356f681SHui Xie 
33e356f681SHui Xie template <class T, class... Args>
34e356f681SHui Xie concept CanEmplace = requires(T t, Args&&... args) { t.emplace(std::forward<Args>(args)...); };
35e356f681SHui Xie 
36e356f681SHui Xie static_assert(CanEmplace<std::expected<int, int>, int>);
37e356f681SHui Xie 
38e356f681SHui Xie template <bool Noexcept>
39e356f681SHui Xie struct CtorFromInt {
40e356f681SHui Xie   CtorFromInt(int) noexcept(Noexcept);
41e356f681SHui Xie   CtorFromInt(int, int) noexcept(Noexcept);
42e356f681SHui Xie };
43e356f681SHui Xie 
44e356f681SHui Xie static_assert(CanEmplace<std::expected<CtorFromInt<true>, int>, int>);
45e356f681SHui Xie static_assert(CanEmplace<std::expected<CtorFromInt<true>, int>, int, int>);
46e356f681SHui Xie static_assert(!CanEmplace<std::expected<CtorFromInt<false>, int>, int>);
47e356f681SHui Xie static_assert(!CanEmplace<std::expected<CtorFromInt<false>, int>, int, int>);
48e356f681SHui Xie 
49e356f681SHui Xie constexpr bool test() {
50e356f681SHui Xie   // has_value
51e356f681SHui Xie   {
52e356f681SHui Xie     BothNoexcept::state oldState{};
53e356f681SHui Xie     BothNoexcept::state newState{};
54e356f681SHui Xie     std::expected<BothNoexcept, int> e(std::in_place, oldState, 5);
55e356f681SHui Xie     decltype(auto) x = e.emplace(newState, 10);
56e356f681SHui Xie     static_assert(std::same_as<decltype(x), BothNoexcept&>);
57e356f681SHui Xie     assert(&x == &(*e));
58e356f681SHui Xie 
59e356f681SHui Xie     assert(oldState.dtorCalled);
60e356f681SHui Xie     assert(e.has_value());
61e356f681SHui Xie     assert(e.value().data_ == 10);
62e356f681SHui Xie   }
63e356f681SHui Xie 
64e356f681SHui Xie   // !has_value
65e356f681SHui Xie   {
66e356f681SHui Xie     BothMayThrow::state oldState{};
67e356f681SHui Xie     std::expected<int, BothMayThrow> e(std::unexpect, oldState, 5);
68e356f681SHui Xie     decltype(auto) x = e.emplace(10);
69e356f681SHui Xie     static_assert(std::same_as<decltype(x), int&>);
70e356f681SHui Xie     assert(&x == &(*e));
71e356f681SHui Xie 
72e356f681SHui Xie     assert(oldState.dtorCalled);
73e356f681SHui Xie     assert(e.has_value());
74e356f681SHui Xie     assert(e.value() == 10);
75e356f681SHui Xie   }
76e356f681SHui Xie 
77134c9159SJan Kokemüller   // TailClobberer
78134c9159SJan Kokemüller   {
79134c9159SJan Kokemüller     std::expected<TailClobberer<0>, bool> e(std::unexpect);
80134c9159SJan Kokemüller     e.emplace();
81134c9159SJan Kokemüller     assert(e.has_value());
82134c9159SJan Kokemüller   }
83134c9159SJan Kokemüller 
844f469053SJan Kokemüller   // CheckForInvalidWrites
854f469053SJan Kokemüller   {
864f469053SJan Kokemüller     {
874f469053SJan Kokemüller       CheckForInvalidWrites<true> e;
884f469053SJan Kokemüller       e.emplace();
894f469053SJan Kokemüller       assert(e.check());
904f469053SJan Kokemüller     }
914f469053SJan Kokemüller     {
924f469053SJan Kokemüller       CheckForInvalidWrites<false> e;
934f469053SJan Kokemüller       e.emplace();
944f469053SJan Kokemüller       assert(e.check());
954f469053SJan Kokemüller     }
964f469053SJan Kokemüller   }
974f469053SJan Kokemüller 
98e356f681SHui Xie   return true;
99e356f681SHui Xie }
100e356f681SHui Xie 
101e356f681SHui Xie int main(int, char**) {
102e356f681SHui Xie   test();
103e356f681SHui Xie   static_assert(test());
104e356f681SHui Xie   return 0;
105e356f681SHui Xie }
106