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