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 // 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> test(InitArgs &&...args)25void 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 test_throwing_ctor()35void test_throwing_ctor() { 36 #ifndef TEST_HAS_NO_EXCEPTIONS 37 struct Z { 38 Z() : count(0) {} 39 Z(Z const& o) : count(o.count + 1) 40 { if (count == 2) throw 6; } 41 int count; 42 }; 43 const Z z; 44 const optional<Z> rhs(z); 45 try 46 { 47 optional<Z> lhs(rhs); 48 assert(false); 49 } 50 catch (int i) 51 { 52 assert(i == 6); 53 } 54 #endif 55 } 56 57 template <class T, class ...InitArgs> test_ref(InitArgs &&...args)58void test_ref(InitArgs&&... args) 59 { 60 const optional<T> rhs(std::forward<InitArgs>(args)...); 61 bool rhs_engaged = static_cast<bool>(rhs); 62 optional<T> lhs = rhs; 63 assert(static_cast<bool>(lhs) == rhs_engaged); 64 if (rhs_engaged) 65 assert(&(*lhs) == &(*rhs)); 66 } 67 68 test_reference_extension()69void test_reference_extension() 70 { 71 #if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently disabled. 72 using T = TestTypes::TestType; 73 T::reset(); 74 { 75 T t; 76 T::reset_constructors(); 77 test_ref<T&>(); 78 test_ref<T&>(t); 79 assert(T::alive == 1); 80 assert(T::constructed == 0); 81 assert(T::assigned == 0); 82 assert(T::destroyed == 0); 83 } 84 assert(T::destroyed == 1); 85 assert(T::alive == 0); 86 { 87 T t; 88 const T& ct = t; 89 T::reset_constructors(); 90 test_ref<T const&>(); 91 test_ref<T const&>(t); 92 test_ref<T const&>(ct); 93 assert(T::alive == 1); 94 assert(T::constructed == 0); 95 assert(T::assigned == 0); 96 assert(T::destroyed == 0); 97 } 98 assert(T::alive == 0); 99 assert(T::destroyed == 1); 100 { 101 static_assert(!std::is_copy_constructible<std::optional<T&&>>::value, ""); 102 static_assert(!std::is_copy_constructible<std::optional<T const&&>>::value, ""); 103 } 104 #endif 105 } 106 main()107int main() 108 { 109 test<int>(); 110 test<int>(3); 111 { 112 const optional<const int> o(42); 113 optional<const int> o2(o); 114 assert(*o2 == 42); 115 } 116 { 117 using T = TestTypes::TestType; 118 T::reset(); 119 const optional<T> rhs; 120 assert(T::alive == 0); 121 const optional<T> lhs(rhs); 122 assert(lhs.has_value() == false); 123 assert(T::alive == 0); 124 } 125 TestTypes::TestType::reset(); 126 { 127 using T = TestTypes::TestType; 128 T::reset(); 129 const optional<T> rhs(42); 130 assert(T::alive == 1); 131 assert(T::value_constructed == 1); 132 assert(T::copy_constructed == 0); 133 const optional<T> lhs(rhs); 134 assert(lhs.has_value()); 135 assert(T::copy_constructed == 1); 136 assert(T::alive == 2); 137 } 138 TestTypes::TestType::reset(); 139 { 140 using namespace ConstexprTestTypes; 141 test<TestType>(); 142 test<TestType>(42); 143 } 144 { 145 using namespace TrivialTestTypes; 146 test<TestType>(); 147 test<TestType>(42); 148 } 149 { 150 test_throwing_ctor(); 151 } 152 { 153 test_reference_extension(); 154 } 155 } 156