U.pass.cpp (4209B)
1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // UNSUPPORTED: c++98, c++03, c++11, c++14 11 12 // XFAIL: availability=macosx10.13 13 // XFAIL: availability=macosx10.12 14 // XFAIL: availability=macosx10.11 15 // XFAIL: availability=macosx10.10 16 // XFAIL: availability=macosx10.9 17 // XFAIL: availability=macosx10.8 18 // XFAIL: availability=macosx10.7 19 20 // <optional> 21 22 // template <class U> 23 // constexpr EXPLICIT optional(U&& u); 24 25 #include <optional> 26 #include <type_traits> 27 #include <cassert> 28 29 #include "test_macros.h" 30 #include "archetypes.hpp" 31 #include "test_convertible.hpp" 32 33 34 using std::optional; 35 36 struct ImplicitThrow 37 { 38 constexpr ImplicitThrow(int x) { if (x != -1) TEST_THROW(6);} 39 }; 40 41 struct ExplicitThrow 42 { 43 constexpr explicit ExplicitThrow(int x) { if (x != -1) TEST_THROW(6);} 44 }; 45 46 struct ImplicitAny { 47 template <class U> 48 constexpr ImplicitAny(U&&) {} 49 }; 50 51 52 template <class To, class From> 53 constexpr bool implicit_conversion(optional<To>&& opt, const From& v) 54 { 55 using O = optional<To>; 56 static_assert(test_convertible<O, From>(), ""); 57 static_assert(!test_convertible<O, void*>(), ""); 58 static_assert(!test_convertible<O, From, int>(), ""); 59 return opt && *opt == static_cast<To>(v); 60 } 61 62 template <class To, class Input, class Expect> 63 constexpr bool explicit_conversion(Input&& in, const Expect& v) 64 { 65 using O = optional<To>; 66 static_assert(std::is_constructible<O, Input>::value, ""); 67 static_assert(!std::is_convertible<Input, O>::value, ""); 68 static_assert(!std::is_constructible<O, void*>::value, ""); 69 static_assert(!std::is_constructible<O, Input, int>::value, ""); 70 optional<To> opt(std::forward<Input>(in)); 71 return opt && *opt == static_cast<To>(v); 72 } 73 74 void test_implicit() 75 { 76 { 77 static_assert(implicit_conversion<long long>(42, 42), ""); 78 } 79 { 80 static_assert(implicit_conversion<long double>(3.14, 3.14), ""); 81 } 82 { 83 int x = 42; 84 optional<void* const> o(&x); 85 assert(*o == &x); 86 } 87 { 88 using T = TrivialTestTypes::TestType; 89 static_assert(implicit_conversion<T>(42, 42), ""); 90 } 91 { 92 using T = TestTypes::TestType; 93 assert(implicit_conversion<T>(3, T(3))); 94 } 95 { 96 using O = optional<ImplicitAny>; 97 static_assert(!test_convertible<O, std::in_place_t>(), ""); 98 static_assert(!test_convertible<O, std::in_place_t&>(), ""); 99 static_assert(!test_convertible<O, const std::in_place_t&>(), ""); 100 static_assert(!test_convertible<O, std::in_place_t&&>(), ""); 101 static_assert(!test_convertible<O, const std::in_place_t&&>(), ""); 102 103 } 104 #ifndef TEST_HAS_NO_EXCEPTIONS 105 { 106 try { 107 using T = ImplicitThrow; 108 optional<T> t = 42; 109 assert(false); 110 ((void)t); 111 } catch (int) { 112 } 113 } 114 #endif 115 } 116 117 void test_explicit() { 118 { 119 using T = ExplicitTrivialTestTypes::TestType; 120 static_assert(explicit_conversion<T>(42, 42), ""); 121 } 122 { 123 using T = ExplicitConstexprTestTypes::TestType; 124 static_assert(explicit_conversion<T>(42, 42), ""); 125 static_assert(!std::is_convertible<int, T>::value, ""); 126 } 127 { 128 using T = ExplicitTestTypes::TestType; 129 T::reset(); 130 { 131 assert(explicit_conversion<T>(42, 42)); 132 assert(T::alive == 0); 133 } 134 T::reset(); 135 { 136 optional<T> t(42); 137 assert(T::alive == 1); 138 assert(T::value_constructed == 1); 139 assert(T::move_constructed == 0); 140 assert(T::copy_constructed == 0); 141 assert(t.value().value == 42); 142 } 143 assert(T::alive == 0); 144 } 145 #ifndef TEST_HAS_NO_EXCEPTIONS 146 { 147 try { 148 using T = ExplicitThrow; 149 optional<T> t(42); 150 assert(false); 151 } catch (int) { 152 } 153 } 154 #endif 155 } 156 157 int main() { 158 test_implicit(); 159 test_explicit(); 160 }