//===----------------------------------------------------------------------===// // 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 expected(unexpect_t, Args&&... args); // // Constraints: is_constructible_v is true. // // Effects: Direct-non-list-initializes unex with std::forward(args).... // // Postconditions: has_value() is false. // // Throws: Any exception thrown by the initialization of unex. #include #include #include #include #include #include "MoveOnly.h" #include "test_macros.h" // Test Constraints: static_assert(std::is_constructible_v, std::unexpect_t>); static_assert(std::is_constructible_v, std::unexpect_t, int>); // !is_constructible_v struct foo {}; static_assert(!std::is_constructible_v, std::unexpect_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::unexpect_t>); static_assert(!ImplicitlyConstructible, std::unexpect_t, int>); struct CopyOnly { int i; constexpr CopyOnly(int ii) : i(ii) {} CopyOnly(const CopyOnly&) = default; CopyOnly(CopyOnly&&) = delete; friend constexpr bool operator==(const CopyOnly& mi, int ii) { return mi.i == ii; } }; template constexpr void testInt() { std::expected e(std::unexpect, 5); assert(!e.has_value()); assert(e.error() == 5); } template constexpr void testLValue() { T t(5); std::expected e(std::unexpect, t); assert(!e.has_value()); assert(e.error() == 5); } template constexpr void testRValue() { std::expected e(std::unexpect, T(5)); assert(!e.has_value()); assert(e.error() == 5); } constexpr bool test() { testInt(); testInt(); testInt(); testLValue(); testLValue(); testRValue(); testRValue(); // no arg { std::expected e(std::unexpect); assert(!e.has_value()); assert(e.error() == 0); } // one arg { std::expected e(std::unexpect, 5); assert(!e.has_value()); assert(e.error() == 5); } // multi args { std::expected> e(std::unexpect, 1, short{2}, MoveOnly(3)); assert(!e.has_value()); assert((e.error() == std::tuple(1, short{2}, MoveOnly(3)))); } return true; } void testException() { #ifndef TEST_HAS_NO_EXCEPTIONS struct Except {}; struct Throwing { Throwing(int) { throw Except{}; }; }; try { std::expected u(std::unexpect, 5); assert(false); } catch (Except) { } #endif // TEST_HAS_NO_EXCEPTIONS } int main(int, char**) { test(); static_assert(test()); testException(); return 0; }