1 //===----------------------------------------------------------------------===// 2 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 3 // See https://llvm.org/LICENSE.txt for license information. 4 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 5 // 6 //===----------------------------------------------------------------------===// 7 8 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 9 10 // template<class... Args> 11 // constexpr T& emplace(Args&&... args) noexcept; 12 // Constraints: is_nothrow_constructible_v<T, Args...> is true. 13 // 14 // Effects: Equivalent to: 15 // if (has_value()) { 16 // destroy_at(addressof(val)); 17 // } else { 18 // destroy_at(addressof(unex)); 19 // has_val = true; 20 // } 21 // return *construct_at(addressof(val), std::forward<Args>(args)...); 22 23 #include <cassert> 24 #include <concepts> 25 #include <expected> 26 #include <type_traits> 27 #include <utility> 28 29 #include "../../types.h" 30 #include "test_macros.h" 31 32 template <class T, class... Args> 33 concept CanEmplace = requires(T t, Args&&... args) { t.emplace(std::forward<Args>(args)...); }; 34 35 static_assert(CanEmplace<std::expected<int, int>, int>); 36 37 template <bool Noexcept> 38 struct CtorFromInt { 39 CtorFromInt(int) noexcept(Noexcept); 40 CtorFromInt(int, int) noexcept(Noexcept); 41 }; 42 43 static_assert(CanEmplace<std::expected<CtorFromInt<true>, int>, int>); 44 static_assert(CanEmplace<std::expected<CtorFromInt<true>, int>, int, int>); 45 static_assert(!CanEmplace<std::expected<CtorFromInt<false>, int>, int>); 46 static_assert(!CanEmplace<std::expected<CtorFromInt<false>, int>, int, int>); 47 48 constexpr bool test() { 49 // has_value 50 { 51 BothNoexcept::state oldState{}; 52 BothNoexcept::state newState{}; 53 std::expected<BothNoexcept, int> e(std::in_place, oldState, 5); 54 decltype(auto) x = e.emplace(newState, 10); 55 static_assert(std::same_as<decltype(x), BothNoexcept&>); 56 assert(&x == &(*e)); 57 58 assert(oldState.dtorCalled); 59 assert(e.has_value()); 60 assert(e.value().data_ == 10); 61 } 62 63 // !has_value 64 { 65 BothMayThrow::state oldState{}; 66 std::expected<int, BothMayThrow> e(std::unexpect, oldState, 5); 67 decltype(auto) x = e.emplace(10); 68 static_assert(std::same_as<decltype(x), int&>); 69 assert(&x == &(*e)); 70 71 assert(oldState.dtorCalled); 72 assert(e.has_value()); 73 assert(e.value() == 10); 74 } 75 76 return true; 77 } 78 79 int main(int, char**) { 80 test(); 81 static_assert(test()); 82 return 0; 83 } 84