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