brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.5 KiB · 4e7657c Raw
137 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... Args>12//   constexpr explicit expected(unexpect_t, Args&&... args);13//14// Constraints: is_constructible_v<E, Args...> is true.15//16// Effects: Direct-non-list-initializes unex with std::forward<Args>(args)....17//18// Postconditions: has_value() is false.19//20// Throws: Any exception thrown by the initialization of unex.21 22#include <cassert>23#include <expected>24#include <tuple>25#include <type_traits>26#include <utility>27 28#include "MoveOnly.h"29#include "test_macros.h"30#include "../../types.h"31 32// Test Constraints:33static_assert(std::is_constructible_v<std::expected<void, int>, std::unexpect_t>);34static_assert(std::is_constructible_v<std::expected<void, int>, std::unexpect_t, int>);35 36// !is_constructible_v<T, Args...>37struct foo {};38static_assert(!std::is_constructible_v<std::expected<void, foo>, std::unexpect_t, int>);39 40// test explicit41template <class T>42void conversion_test(T);43 44template <class T, class... Args>45concept ImplicitlyConstructible = requires(Args&&... args) { conversion_test<T>({std::forward<Args>(args)...}); };46static_assert(ImplicitlyConstructible<int, int>);47 48static_assert(!ImplicitlyConstructible<std::expected<void, int>, std::unexpect_t>);49static_assert(!ImplicitlyConstructible<std::expected<void, int>, std::unexpect_t, int>);50 51struct CopyOnly {52  int i;53  constexpr CopyOnly(int ii) : i(ii) {}54  CopyOnly(const CopyOnly&) = default;55  CopyOnly(CopyOnly&&)      = delete;56  friend constexpr bool operator==(const CopyOnly& mi, int ii) { return mi.i == ii; }57};58 59template <class T>60constexpr void testInt() {61  std::expected<void, T> e(std::unexpect, 5);62  assert(!e.has_value());63  assert(e.error() == 5);64}65 66template <class T>67constexpr void testLValue() {68  T t(5);69  std::expected<void, T> e(std::unexpect, t);70  assert(!e.has_value());71  assert(e.error() == 5);72}73 74template <class T>75constexpr void testRValue() {76  std::expected<void, T> e(std::unexpect, T(5));77  assert(!e.has_value());78  assert(e.error() == 5);79}80 81constexpr bool test() {82  testInt<int>();83  testInt<CopyOnly>();84  testInt<MoveOnly>();85  testInt<TailClobberer<1>>();86  testLValue<int>();87  testLValue<CopyOnly>();88  testLValue<TailClobberer<1>>();89  testRValue<int>();90  testRValue<MoveOnly>();91  testRValue<TailClobberer<1>>();92 93  // no arg94  {95    std::expected<void, int> e(std::unexpect);96    assert(!e.has_value());97    assert(e.error() == 0);98  }99 100  // one arg101  {102    std::expected<void, int> e(std::unexpect, 5);103    assert(!e.has_value());104    assert(e.error() == 5);105  }106 107  // multi args108  {109    std::expected<void, std::tuple<int, short, MoveOnly>> e(std::unexpect, 1, short{2}, MoveOnly(3));110    assert(!e.has_value());111    assert((e.error() == std::tuple<int, short, MoveOnly>(1, short{2}, MoveOnly(3))));112  }113 114  return true;115}116 117void testException() {118#ifndef TEST_HAS_NO_EXCEPTIONS119  struct Throwing {120    Throwing(int) { throw Except{}; };121  };122 123  try {124    std::expected<void, Throwing> u(std::unexpect, 5);125    assert(false);126  } catch (Except) {127  }128#endif // TEST_HAS_NO_EXCEPTIONS129}130 131int main(int, char**) {132  test();133  static_assert(test());134  testException();135  return 0;136}137