brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.2 KiB · f61a22c Raw
176 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++1410// <optional>11 12// constexpr optional(const optional<T>& rhs);13 14#include <cassert>15#include <optional>16#include <type_traits>17 18#include "test_macros.h"19#include "archetypes.h"20 21using std::optional;22 23template <class T, class... InitArgs>24void test(InitArgs&&... args) {25  const optional<T> rhs(std::forward<InitArgs>(args)...);26  bool rhs_engaged = static_cast<bool>(rhs);27  optional<T> lhs  = rhs;28  assert(static_cast<bool>(lhs) == rhs_engaged);29  if (rhs_engaged)30    assert(*lhs == *rhs);31}32 33template <class T, class... InitArgs>34constexpr bool constexpr_test(InitArgs&&... args) {35  static_assert(std::is_trivially_copy_constructible_v<T>, ""); // requirement36  const optional<T> rhs(std::forward<InitArgs>(args)...);37  optional<T> lhs = rhs;38  return (lhs.has_value() == rhs.has_value()) && (lhs.has_value() ? *lhs == *rhs : true);39}40 41void test_throwing_ctor() {42#ifndef TEST_HAS_NO_EXCEPTIONS43  struct Z {44    Z() : count(0) {}45    Z(Z const& o) : count(o.count + 1) {46      if (count == 2)47        throw 6;48    }49    int count;50  };51  const Z z;52  const optional<Z> rhs(z);53  try {54    optional<Z> lhs(rhs);55    assert(false);56  } catch (int i) {57    assert(i == 6);58  }59#endif60}61 62template <class T, class... InitArgs>63void test_ref(InitArgs&&... args) {64  const optional<T> rhs(std::forward<InitArgs>(args)...);65  bool rhs_engaged = static_cast<bool>(rhs);66  optional<T> lhs  = rhs;67  assert(static_cast<bool>(lhs) == rhs_engaged);68  if (rhs_engaged)69    assert(&(*lhs) == &(*rhs));70}71 72void test_reference_extension() {73#if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently disabled.74  using T = TestTypes::TestType;75  T::reset();76  {77    T t;78    T::reset_constructors();79    test_ref<T&>();80    test_ref<T&>(t);81    assert(T::alive == 1);82    assert(T::constructed == 0);83    assert(T::assigned == 0);84    assert(T::destroyed == 0);85  }86  assert(T::destroyed == 1);87  assert(T::alive == 0);88  {89    T t;90    const T& ct = t;91    T::reset_constructors();92    test_ref<T const&>();93    test_ref<T const&>(t);94    test_ref<T const&>(ct);95    assert(T::alive == 1);96    assert(T::constructed == 0);97    assert(T::assigned == 0);98    assert(T::destroyed == 0);99  }100  assert(T::alive == 0);101  assert(T::destroyed == 1);102  {103    static_assert(!std::is_copy_constructible<std::optional<T&&>>::value, "");104    static_assert(!std::is_copy_constructible<std::optional<T const&&>>::value, "");105  }106#endif107}108 109int main(int, char**) {110  test<int>();111  test<int>(3);112  static_assert(constexpr_test<int>(), "");113  static_assert(constexpr_test<int>(3), "");114 115  {116    const optional<const int> o(42);117    optional<const int> o2(o);118    assert(*o2 == 42);119  }120  {121    using T = TestTypes::TestType;122    T::reset();123    const optional<T> rhs;124    assert(T::alive == 0);125    const optional<T> lhs(rhs);126    assert(lhs.has_value() == false);127    assert(T::alive == 0);128  }129  TestTypes::TestType::reset();130  {131    using T = TestTypes::TestType;132    T::reset();133    const optional<T> rhs(42);134    assert(T::alive == 1);135    assert(T::value_constructed == 1);136    assert(T::copy_constructed == 0);137    const optional<T> lhs(rhs);138    assert(lhs.has_value());139    assert(T::copy_constructed == 1);140    assert(T::alive == 2);141  }142  TestTypes::TestType::reset();143  {144    using namespace ConstexprTestTypes;145    test<TestType>();146    test<TestType>(42);147  }148  {149    using namespace TrivialTestTypes;150    test<TestType>();151    test<TestType>(42);152  }153  {154    test_throwing_ctor();155  }156  {157    test_reference_extension();158  }159  {160    constexpr std::optional<int> o1{4};161    constexpr std::optional<int> o2 = o1;162    static_assert(*o2 == 4, "");163  }164 165  // LWG3836 https://wg21.link/LWG3836166  // std::optional<bool> conversion constructor optional(const optional<U>&)167  // should take precedence over optional(U&&) with operator bool168  {169    std::optional<bool> o1(false);170    std::optional<bool> o2(o1);171    assert(!o2.value());172  }173 174  return 0;175}176