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