brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.7 KiB · 409352e Raw
133 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 expected& operator=(const unexpected<G>& e);13//14// Let GF be const G&15//16// Constraints: is_constructible_v<E, GF> is true and is_assignable_v<E&, GF> is true.17//18// Effects:19// - If has_value() is true, equivalent to:20//   construct_at(addressof(unex), std::forward<GF>(e.error()));21//   has_val = false;22// - Otherwise, equivalent to: unex = std::forward<GF>(e.error());23//24// Returns: *this.25 26#include <cassert>27#include <concepts>28#include <expected>29#include <type_traits>30#include <utility>31 32#include "../../types.h"33#include "test_macros.h"34 35struct NotCopyConstructible {36  NotCopyConstructible(const NotCopyConstructible&)            = delete;37  NotCopyConstructible& operator=(const NotCopyConstructible&) = default;38};39 40struct NotCopyAssignable {41  NotCopyAssignable(const NotCopyAssignable&)            = default;42  NotCopyAssignable& operator=(const NotCopyAssignable&) = delete;43};44 45struct MoveMayThrow {46  MoveMayThrow(MoveMayThrow const&)            = default;47  MoveMayThrow& operator=(const MoveMayThrow&) = default;48  MoveMayThrow(MoveMayThrow&&) noexcept(false) {}49  MoveMayThrow& operator=(MoveMayThrow&&) noexcept(false) { return *this; }50};51 52// Test constraints53static_assert(std::is_assignable_v<std::expected<void, int>&, const std::unexpected<int>&>);54 55// !is_constructible_v<E, GF>56static_assert(57    !std::is_assignable_v<std::expected<void, NotCopyConstructible>&, const std::unexpected<NotCopyConstructible>&>);58 59// !is_assignable_v<E&, GF>60static_assert(61    !std::is_assignable_v<std::expected<void, NotCopyAssignable>&, const std::unexpected<NotCopyAssignable>&>);62 63constexpr bool test() {64  // - If has_value() is true, equivalent to:65  //   construct_at(addressof(unex), std::forward<GF>(e.error()));66  //   has_val = false;67  {68    Traced::state state{};69    std::expected<void, Traced> e;70    std::unexpected<Traced> un(std::in_place, state, 5);71    decltype(auto) x = (e = un);72    static_assert(std::same_as<decltype(x), std::expected<void, Traced>&>);73    assert(&x == &e);74    assert(!e.has_value());75    assert(e.error().data_ == 5);76 77    assert(state.copyCtorCalled);78  }79 80  // - Otherwise, equivalent to: unex = std::forward<GF>(e.error());81  {82    Traced::state state1{};83    Traced::state state2{};84    std::expected<void, Traced> e(std::unexpect, state1, 5);85    std::unexpected<Traced> un(std::in_place, state2, 10);86    decltype(auto) x = (e = un);87    static_assert(std::same_as<decltype(x), std::expected<void, Traced>&>);88    assert(&x == &e);89    assert(!e.has_value());90    assert(e.error().data_ == 10);91 92    assert(state1.copyAssignCalled);93  }94 95  // CheckForInvalidWrites96  {97    {98      CheckForInvalidWrites<true, true> e;99      std::unexpected<int> un(std::in_place, 42);100      e = un;101      assert(e.check());102    }103    {104      CheckForInvalidWrites<false, true> e;105      std::unexpected<bool> un(std::in_place, true);106      e = un;107      assert(e.check());108    }109  }110 111  return true;112}113 114void testException() {115#ifndef TEST_HAS_NO_EXCEPTIONS116  std::expected<void, ThrowOnCopyConstruct> e1(std::in_place);117  std::unexpected<ThrowOnCopyConstruct> un(std::in_place);118  try {119    e1 = un;120    assert(false);121  } catch (Except) {122    assert(e1.has_value());123  }124#endif // TEST_HAS_NO_EXCEPTIONS125}126 127int main(int, char**) {128  test();129  static_assert(test());130  testException();131  return 0;132}133