brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.9 KiB · 1e951eb Raw
158 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 11// <optional>12 13// template <class U>14//   constexpr EXPLICIT optional(U&& u);15 16#include <cassert>17#include <optional>18#include <type_traits>19 20#include "test_macros.h"21#include "archetypes.h"22#include "test_convertible.h"23 24using std::optional;25 26struct ImplicitThrow {27  constexpr ImplicitThrow(int x) {28    if (x != -1)29      TEST_THROW(6);30  }31};32 33struct ExplicitThrow {34  constexpr explicit ExplicitThrow(int x) {35    if (x != -1)36      TEST_THROW(6);37  }38};39 40struct ImplicitAny {41  template <class U>42  constexpr ImplicitAny(U&&) {}43};44 45template <class To, class From>46constexpr bool implicit_conversion(optional<To>&& opt, const From& v) {47  using O = optional<To>;48  static_assert(test_convertible<O, From>(), "");49  static_assert(!test_convertible<O, void*>(), "");50  static_assert(!test_convertible<O, From, int>(), "");51  return opt && *opt == static_cast<To>(v);52}53 54template <class To, class Input, class Expect>55constexpr bool explicit_conversion(Input&& in, const Expect& v) {56  using O = optional<To>;57  static_assert(std::is_constructible<O, Input>::value, "");58  static_assert(!std::is_convertible<Input, O>::value, "");59  static_assert(!std::is_constructible<O, void*>::value, "");60  static_assert(!std::is_constructible<O, Input, int>::value, "");61  optional<To> opt(std::forward<Input>(in));62  optional<To> opt2{std::forward<Input>(in)};63  return opt && *opt == static_cast<To>(v) && (opt2 && *opt2 == static_cast<To>(v));64}65 66void test_implicit() {67  {68    static_assert(implicit_conversion<long long>(42, 42), "");69  }70  {71    static_assert(implicit_conversion<long double>(3.14, 3.14), "");72  }73  {74    int x = 42;75    optional<void* const> o(&x);76    assert(*o == &x);77  }78  {79    using T = TrivialTestTypes::TestType;80    static_assert(implicit_conversion<T>(42, 42), "");81  }82  {83    using T = TestTypes::TestType;84    assert(implicit_conversion<T>(3, T(3)));85  }86  {87    using T = TestTypes::TestType;88    optional<T> opt({3});89    assert(opt && *opt == static_cast<T>(3));90  }91  {92    using O = optional<ImplicitAny>;93    static_assert(!test_convertible<O, std::in_place_t>(), "");94    static_assert(!test_convertible<O, std::in_place_t&>(), "");95    static_assert(!test_convertible<O, const std::in_place_t&>(), "");96    static_assert(!test_convertible<O, std::in_place_t&&>(), "");97    static_assert(!test_convertible<O, const std::in_place_t&&>(), "");98  }99#ifndef TEST_HAS_NO_EXCEPTIONS100  {101    try {102      using T       = ImplicitThrow;103      optional<T> t = 42;104      assert(false);105      ((void)t);106    } catch (int) {107    }108  }109#endif110}111 112void test_explicit() {113  {114    using T = ExplicitTrivialTestTypes::TestType;115    static_assert(explicit_conversion<T>(42, 42), "");116  }117  {118    using T = ExplicitConstexprTestTypes::TestType;119    static_assert(explicit_conversion<T>(42, 42), "");120    static_assert(!std::is_convertible<int, T>::value, "");121  }122  {123    using T = ExplicitTestTypes::TestType;124    T::reset();125    {126      assert(explicit_conversion<T>(42, 42));127      assert(T::alive == 0);128    }129    T::reset();130    {131      optional<T> t(42);132      assert(T::alive == 1);133      assert(T::value_constructed == 1);134      assert(T::move_constructed == 0);135      assert(T::copy_constructed == 0);136      assert(t.value().value == 42);137    }138    assert(T::alive == 0);139  }140#ifndef TEST_HAS_NO_EXCEPTIONS141  {142    try {143      using T = ExplicitThrow;144      optional<T> t(42);145      assert(false);146    } catch (int) {147    }148  }149#endif150}151 152int main(int, char**) {153  test_implicit();154  test_explicit();155 156  return 0;157}158