//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 // template // constexpr T& emplace(Args&&... args) noexcept; // Constraints: is_nothrow_constructible_v is true. // // Effects: Equivalent to: // if (has_value()) { // destroy_at(addressof(val)); // } else { // destroy_at(addressof(unex)); // has_val = true; // } // return *construct_at(addressof(val), std::forward(args)...); #include #include #include #include #include #include "../../types.h" #include "test_macros.h" template concept CanEmplace = requires(T t, Args&&... args) { t.emplace(std::forward(args)...); }; static_assert(CanEmplace, int>); template struct CtorFromInt { CtorFromInt(int) noexcept(Noexcept); CtorFromInt(int, int) noexcept(Noexcept); }; static_assert(CanEmplace, int>, int>); static_assert(CanEmplace, int>, int, int>); static_assert(!CanEmplace, int>, int>); static_assert(!CanEmplace, int>, int, int>); constexpr bool test() { // has_value { BothNoexcept::state oldState{}; BothNoexcept::state newState{}; std::expected e(std::in_place, oldState, 5); decltype(auto) x = e.emplace(newState, 10); static_assert(std::same_as); assert(&x == &(*e)); assert(oldState.dtorCalled); assert(e.has_value()); assert(e.value().data_ == 10); } // !has_value { BothMayThrow::state oldState{}; std::expected e(std::unexpect, oldState, 5); decltype(auto) x = e.emplace(10); static_assert(std::same_as); assert(&x == &(*e)); assert(oldState.dtorCalled); assert(e.has_value()); assert(e.value() == 10); } // TailClobberer { std::expected, bool> e(std::unexpect); e.emplace(); assert(e.has_value()); } // CheckForInvalidWrites { { CheckForInvalidWrites e; e.emplace(); assert(e.check()); } { CheckForInvalidWrites e; e.emplace(); assert(e.check()); } } return true; } int main(int, char**) { test(); static_assert(test()); return 0; }