115 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 const T& value() const &;12// constexpr T& value() &;13// constexpr T&& value() &&;14// constexpr const T&& value() const &&;15 16#include <cassert>17#include <concepts>18#include <expected>19#include <type_traits>20#include <utility>21 22#include "test_macros.h"23 24constexpr bool test() {25 // non-const &26 {27 std::expected<int, int> e(5);28 decltype(auto) x = e.value();29 static_assert(std::same_as<decltype(x), int&>);30 assert(&x == &(*e));31 assert(x == 5);32 }33 34 // const &35 {36 const std::expected<int, int> e(5);37 decltype(auto) x = e.value();38 static_assert(std::same_as<decltype(x), const int&>);39 assert(&x == &(*e));40 assert(x == 5);41 }42 43 // non-const &&44 {45 std::expected<int, int> e(5);46 decltype(auto) x = std::move(e).value();47 static_assert(std::same_as<decltype(x), int&&>);48 assert(&x == &(*e));49 assert(x == 5);50 }51 52 // const &&53 {54 const std::expected<int, int> e(5);55 decltype(auto) x = std::move(e).value();56 static_assert(std::same_as<decltype(x), const int&&>);57 assert(&x == &(*e));58 assert(x == 5);59 }60 61 return true;62}63 64void testException() {65#ifndef TEST_HAS_NO_EXCEPTIONS66 67 // int68 {69 const std::expected<int, int> e(std::unexpect, 5);70 try {71 (void) e.value();72 assert(false);73 } catch (const std::bad_expected_access<int>& ex) {74 assert(ex.error() == 5);75 }76 }77 78#endif // TEST_HAS_NO_EXCEPTIONS79}80 81void testAsConst() {82#ifndef TEST_HAS_NO_EXCEPTIONS83 struct Error {84 enum { Default, MutableRefCalled, ConstRefCalled } From = Default;85 Error() = default;86 Error(const Error&) { From = ConstRefCalled; }87 Error(Error&) { From = MutableRefCalled; }88 Error(Error&& e) { From = e.From; }89 };90 91 // Test & overload92 {93 std::expected<int, Error> e(std::unexpect, Error());94 try {95 (void)e.value();96 assert(false);97 } catch (const std::bad_expected_access<Error>& ex) {98 assert(ex.error().From == Error::ConstRefCalled);99 }100 }101 102 // There are no effects for `const &` overload.103 104#endif // TEST_HAS_NO_EXCEPTIONS105}106 107int main(int, char**) {108 test();109 static_assert(test());110 testException();111 testAsConst();112 113 return 0;114}115