PR20855_tuple_ref_binding_diagnostics.pass.cpp (4224B)
1 // -*- C++ -*- 2 //===----------------------------------------------------------------------===// 3 // 4 // The LLVM Compiler Infrastructure 5 // 6 // This file is dual licensed under the MIT and the University of Illinois Open 7 // Source Licenses. See LICENSE.TXT for details. 8 // 9 //===----------------------------------------------------------------------===// 10 11 // UNSUPPORTED: c++98, c++03 12 13 // <tuple> 14 15 // See llvm.org/PR20855 16 17 #include <functional> 18 #include <tuple> 19 #include <string> 20 #include <cassert> 21 #include "test_macros.h" 22 23 #if TEST_HAS_BUILTIN_IDENTIFIER(__reference_binds_to_temporary) 24 # define ASSERT_REFERENCE_BINDS_TEMPORARY(...) static_assert(__reference_binds_to_temporary(__VA_ARGS__), "") 25 # define ASSERT_NOT_REFERENCE_BINDS_TEMPORARY(...) static_assert(!__reference_binds_to_temporary(__VA_ARGS__), "") 26 #else 27 # define ASSERT_REFERENCE_BINDS_TEMPORARY(...) static_assert(true, "") 28 # define ASSERT_NOT_REFERENCE_BINDS_TEMPORARY(...) static_assert(true, "") 29 #endif 30 31 template <class Tp> 32 struct ConvertsTo { 33 using RawTp = typename std::remove_cv< typename std::remove_reference<Tp>::type>::type; 34 35 operator Tp() const { 36 return static_cast<Tp>(value); 37 } 38 39 mutable RawTp value; 40 }; 41 42 struct Base {}; 43 struct Derived : Base {}; 44 45 46 static_assert(std::is_same<decltype("abc"), decltype(("abc"))>::value, ""); 47 ASSERT_REFERENCE_BINDS_TEMPORARY(std::string const&, decltype("abc")); 48 ASSERT_REFERENCE_BINDS_TEMPORARY(std::string const&, decltype(("abc"))); 49 ASSERT_REFERENCE_BINDS_TEMPORARY(std::string const&, const char*&&); 50 51 ASSERT_NOT_REFERENCE_BINDS_TEMPORARY(int&, const ConvertsTo<int&>&); 52 ASSERT_NOT_REFERENCE_BINDS_TEMPORARY(const int&, ConvertsTo<int&>&); 53 ASSERT_NOT_REFERENCE_BINDS_TEMPORARY(Base&, Derived&); 54 55 56 static_assert(std::is_constructible<int&, std::reference_wrapper<int>>::value, ""); 57 static_assert(std::is_constructible<int const&, std::reference_wrapper<int>>::value, ""); 58 59 template <class T> struct CannotDeduce { 60 using type = T; 61 }; 62 63 template <class ...Args> 64 void F(typename CannotDeduce<std::tuple<Args...>>::type const&) {} 65 66 void compile_tests() { 67 { 68 F<int, int const&>(std::make_tuple(42, 42)); 69 } 70 { 71 F<int, int const&>(std::make_tuple<const int&, const int&>(42, 42)); 72 std::tuple<int, int const&> t(std::make_tuple<const int&, const int&>(42, 42)); 73 } 74 { 75 auto fn = &F<int, std::string const&>; 76 fn(std::tuple<int, std::string const&>(42, std::string("a"))); 77 fn(std::make_tuple(42, std::string("a"))); 78 } 79 { 80 Derived d; 81 std::tuple<Base&, Base const&> t(d, d); 82 } 83 { 84 ConvertsTo<int&> ct; 85 std::tuple<int, int&> t(42, ct); 86 } 87 } 88 89 void allocator_tests() { 90 std::allocator<void> alloc; 91 int x = 42; 92 { 93 std::tuple<int&> t(std::ref(x)); 94 assert(&std::get<0>(t) == &x); 95 std::tuple<int&> t1(std::allocator_arg, alloc, std::ref(x)); 96 assert(&std::get<0>(t1) == &x); 97 } 98 { 99 auto r = std::ref(x); 100 auto const& cr = r; 101 std::tuple<int&> t(r); 102 assert(&std::get<0>(t) == &x); 103 std::tuple<int&> t1(cr); 104 assert(&std::get<0>(t1) == &x); 105 std::tuple<int&> t2(std::allocator_arg, alloc, r); 106 assert(&std::get<0>(t2) == &x); 107 std::tuple<int&> t3(std::allocator_arg, alloc, cr); 108 assert(&std::get<0>(t3) == &x); 109 } 110 { 111 std::tuple<int const&> t(std::ref(x)); 112 assert(&std::get<0>(t) == &x); 113 std::tuple<int const&> t2(std::cref(x)); 114 assert(&std::get<0>(t2) == &x); 115 std::tuple<int const&> t3(std::allocator_arg, alloc, std::ref(x)); 116 assert(&std::get<0>(t3) == &x); 117 std::tuple<int const&> t4(std::allocator_arg, alloc, std::cref(x)); 118 assert(&std::get<0>(t4) == &x); 119 } 120 { 121 auto r = std::ref(x); 122 auto cr = std::cref(x); 123 std::tuple<int const&> t(r); 124 assert(&std::get<0>(t) == &x); 125 std::tuple<int const&> t2(cr); 126 assert(&std::get<0>(t2) == &x); 127 std::tuple<int const&> t3(std::allocator_arg, alloc, r); 128 assert(&std::get<0>(t3) == &x); 129 std::tuple<int const&> t4(std::allocator_arg, alloc, cr); 130 assert(&std::get<0>(t4) == &x); 131 } 132 } 133 134 135 int main() { 136 compile_tests(); 137 allocator_tests(); 138 }