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