brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.2 KiB · 6ed1a98 Raw
147 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// constexpr expected& operator=(const expected& rhs);12//13// Effects:14// - If this->has_value() && rhs.has_value() is true, no effects.15// - Otherwise, if this->has_value() is true, equivalent to: construct_at(addressof(unex), rhs.unex); has_val = false;16// - Otherwise, if rhs.has_value() is true, destroys unex and sets has_val to true.17// - Otherwise, equivalent to unex = rhs.error().18//19// Returns: *this.20//21// Remarks: This operator is defined as deleted unless is_copy_assignable_v<E> is true and is_copy_constructible_v<E> is true.22 23#include <cassert>24#include <concepts>25#include <expected>26#include <type_traits>27#include <utility>28 29#include "../../types.h"30#include "test_macros.h"31 32struct NotCopyConstructible {33  NotCopyConstructible(const NotCopyConstructible&)            = delete;34  NotCopyConstructible& operator=(const NotCopyConstructible&) = default;35};36 37struct NotCopyAssignable {38  NotCopyAssignable(const NotCopyAssignable&)            = default;39  NotCopyAssignable& operator=(const NotCopyAssignable&) = delete;40};41 42// Test constraints43static_assert(std::is_copy_assignable_v<std::expected<void, int>>);44 45// !is_copy_assignable_v<E>46static_assert(!std::is_copy_assignable_v<std::expected<void, NotCopyAssignable>>);47 48// !is_copy_constructible_v<E>49static_assert(!std::is_copy_assignable_v<std::expected<void, NotCopyConstructible>>);50 51constexpr bool test() {52  // If this->has_value() && rhs.has_value() is true, no effects.53  {54    std::expected<void, int> e1;55    std::expected<void, int> e2;56    decltype(auto) x = (e1 = e2);57    static_assert(std::same_as<decltype(x), std::expected<void, int>&>);58    assert(&x == &e1);59    assert(e1.has_value());60  }61 62  // Otherwise, if this->has_value() is true, equivalent to: construct_at(addressof(unex), rhs.unex); has_val = false;63  {64    Traced::state state{};65    std::expected<void, Traced> e1;66    std::expected<void, Traced> e2(std::unexpect, state, 5);67    decltype(auto) x = (e1 = e2);68    static_assert(std::same_as<decltype(x), std::expected<void, Traced>&>);69    assert(&x == &e1);70    assert(!e1.has_value());71    assert(e1.error().data_ == 5);72 73    assert(state.copyCtorCalled);74  }75 76  // Otherwise, if rhs.has_value() is true, destroys unex and sets has_val to true.77  {78    Traced::state state{};79    std::expected<void, Traced> e1(std::unexpect, state, 5);80    std::expected<void, Traced> e2;81    decltype(auto) x = (e1 = e2);82    static_assert(std::same_as<decltype(x), std::expected<void, Traced>&>);83    assert(&x == &e1);84    assert(e1.has_value());85 86    assert(state.dtorCalled);87  }88 89  // Otherwise, equivalent to unex = rhs.error().90  {91    Traced::state state{};92    std::expected<void, Traced> e1(std::unexpect, state, 5);93    std::expected<void, Traced> e2(std::unexpect, state, 10);94    decltype(auto) x = (e1 = e2);95    static_assert(std::same_as<decltype(x), std::expected<void, Traced>&>);96    assert(&x == &e1);97    assert(!e1.has_value());98    assert(e1.error().data_ == 10);99 100    assert(state.copyAssignCalled);101  }102 103  // CheckForInvalidWrites104  {105    {106      CheckForInvalidWrites<true, true> e1;107      CheckForInvalidWrites<true, true> e2(std::unexpect);108 109      e1 = e2;110 111      assert(e1.check());112      assert(e2.check());113    }114    {115      CheckForInvalidWrites<false, true> e1;116      CheckForInvalidWrites<false, true> e2(std::unexpect);117 118      e1 = e2;119 120      assert(e1.check());121      assert(e2.check());122    }123  }124 125  return true;126}127 128void testException() {129#ifndef TEST_HAS_NO_EXCEPTIONS130  std::expected<void, ThrowOnCopyConstruct> e1(std::in_place);131  std::expected<void, ThrowOnCopyConstruct> e2(std::unexpect);132  try {133    e1 = e2;134    assert(false);135  } catch (Except) {136    assert(e1.has_value());137  }138#endif // TEST_HAS_NO_EXCEPTIONS139}140 141int main(int, char**) {142  test();143  static_assert(test());144  testException();145  return 0;146}147