93 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++17, c++2010 11// template<class G>12// constexpr explicit(!is_convertible_v<const G&, E>) expected(const unexpected<G>& e);13//14// Let GF be const G&15//16// Constraints: is_constructible_v<E, GF> is true.17//18// Effects: Direct-non-list-initializes unex with std::forward<GF>(e.error()).19//20// Postconditions: has_value() is false.21//22// Throws: Any exception thrown by the initialization of unex.23 24#include <cassert>25#include <expected>26#include <type_traits>27#include <utility>28 29#include "MoveOnly.h"30#include "test_macros.h"31#include "../../types.h"32 33// Test Constraints34static_assert(std::is_constructible_v<std::expected<void, int>, const std::unexpected<int>&>);35 36// !is_constructible_v<E, GF>37struct foo {};38static_assert(!std::is_constructible_v<std::expected<void, int>, const std::unexpected<foo>&>);39static_assert(!std::is_constructible_v<std::expected<void, MoveOnly>, const std::unexpected<MoveOnly>&>);40 41// explicit(!is_convertible_v<const G&, E>)42struct NotConvertible {43 explicit NotConvertible(int);44};45static_assert(std::is_convertible_v<const std::unexpected<int>&, std::expected<void, int>>);46static_assert(!std::is_convertible_v<const std::unexpected<int>&, std::expected<void, NotConvertible>>);47 48struct MyInt {49 int i;50 constexpr MyInt(int ii) : i(ii) {}51 friend constexpr bool operator==(const MyInt&, const MyInt&) = default;52};53 54template <class T>55constexpr void testUnexpected() {56 const std::unexpected<int> u(5);57 std::expected<void, T> e(u);58 assert(!e.has_value());59 assert(e.error() == 5);60}61 62constexpr bool test() {63 testUnexpected<int>();64 testUnexpected<MyInt>();65 testUnexpected<TailClobberer<1>>();66 return true;67}68 69void testException() {70#ifndef TEST_HAS_NO_EXCEPTIONS71 struct Throwing {72 Throwing(int) { throw Except{}; }73 };74 75 {76 const std::unexpected<int> u(5);77 try {78 [[maybe_unused]] std::expected<void, Throwing> e(u);79 assert(false);80 } catch (Except) {81 }82 }83 84#endif // TEST_HAS_NO_EXCEPTIONS85}86 87int main(int, char**) {88 test();89 static_assert(test());90 testException();91 return 0;92}93