103 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<G, E>) expected(unexpected<G>&& e);13//14// Let GF be G15//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>, std::unexpected<int>>);35static_assert(std::is_constructible_v<std::expected<void, MoveOnly>, std::unexpected<MoveOnly>>);36 37// !is_constructible_v<E, GF>38struct foo {};39static_assert(!std::is_constructible_v<std::expected<void, int>, std::unexpected<foo>>);40 41// explicit(!is_convertible_v<G, E>)42struct NotConvertible {43 explicit NotConvertible(int);44};45static_assert(std::is_convertible_v<std::unexpected<int>&&, std::expected<void, int>>);46static_assert(!std::is_convertible_v<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 Err>55constexpr void testInt() {56 std::unexpected<int> u(5);57 std::expected<void, Err> e(std::move(u));58 assert(!e.has_value());59 assert(e.error() == 5);60}61 62constexpr void testMoveOnly() {63 std::unexpected<MoveOnly> u(MoveOnly(5));64 std::expected<void, MoveOnly> e(std::move(u));65 assert(!e.has_value());66 assert(e.error() == 5);67 assert(u.error() == 0);68}69 70constexpr bool test() {71 testInt<int>();72 testInt<MyInt>();73 testInt<MoveOnly>();74 testInt<TailClobberer<1>>();75 testMoveOnly();76 return true;77}78 79void testException() {80#ifndef TEST_HAS_NO_EXCEPTIONS81 struct Throwing {82 Throwing(int) { throw Except{}; }83 };84 85 {86 std::unexpected<int> u(5);87 try {88 [[maybe_unused]] std::expected<void, Throwing> e(std::move(u));89 assert(false);90 } catch (Except) {91 }92 }93 94#endif // TEST_HAS_NO_EXCEPTIONS95}96 97int main(int, char**) {98 test();99 static_assert(test());100 testException();101 return 0;102}103