//===----------------------------------------------------------------------===// // // 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 explicit unexpected(in_place_t, Args&&... args); // // Constraints: is_constructible_v is true. // // Effects: Direct-non-list-initializes unex with std::forward(args).... // // Throws: Any exception thrown by the initialization of unex. #include #include #include #include #include "test_macros.h" // Test Constraints: static_assert(std::constructible_from, std::in_place_t, int>); // !is_constructible_v struct Foo {}; static_assert(!std::constructible_from, std::in_place_t, int>); // test explicit template void conversion_test(T); template concept ImplicitlyConstructible = requires(Args&&... args) { conversion_test({std::forward(args)...}); }; static_assert(ImplicitlyConstructible); static_assert(!ImplicitlyConstructible, std::in_place_t, int>); struct Arg { int i; constexpr Arg(int ii) : i(ii) {} constexpr Arg(const Arg& other) : i(other.i) {} constexpr Arg(Arg&& other) : i(other.i) { other.i = 0; } }; struct Error { Arg arg; constexpr explicit Error(const Arg& a) : arg(a) {} constexpr explicit Error(Arg&& a) : arg(std::move(a)) {} Error(std::initializer_list) :arg(0){ assert(false); } }; constexpr bool test() { // lvalue { Arg a{5}; std::unexpected unex(std::in_place, a); assert(unex.error().arg.i == 5); assert(a.i == 5); } // rvalue { Arg a{5}; std::unexpected unex(std::in_place, std::move(a)); assert(unex.error().arg.i == 5); assert(a.i == 0); } // Direct-non-list-initializes: does not trigger initializer_list overload { Error e(5); [[maybe_unused]] std::unexpected unex(std::in_place, e); } return true; } void testException() { #ifndef TEST_HAS_NO_EXCEPTIONS struct Except {}; struct Throwing { Throwing(int) { throw Except{}; } }; try { std::unexpected u(std::in_place, 5); assert(false); } catch (Except) { } #endif // TEST_HAS_NO_EXCEPTIONS } int main(int, char**) { test(); static_assert(test()); testException(); return 0; }