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 10 11 // FIXME: Why does this start to fail with GCC 14? 12 // XFAIL: !(c++11 || c++14) && gcc-14 13 14 // See https://llvm.org/PR31384. 15 16 #include <tuple> 17 #include <cassert> 18 19 #include "test_macros.h" 20 21 int count = 0; 22 23 struct Explicit { 24 Explicit() = default; ExplicitExplicit25 explicit Explicit(int) {} 26 }; 27 28 struct Implicit { 29 Implicit() = default; ImplicitImplicit30 Implicit(int) {} 31 }; 32 33 template<class T> 34 struct Derived : std::tuple<T> { 35 using std::tuple<T>::tuple; 36 template<class U> operator std::tuple<U>Derived37 operator std::tuple<U>() && { ++count; return {}; } 38 }; 39 40 41 template<class T> 42 struct ExplicitDerived : std::tuple<T> { 43 using std::tuple<T>::tuple; 44 template<class U> operator std::tuple<U>ExplicitDerived45 explicit operator std::tuple<U>() && { ++count; return {}; } 46 }; 47 main(int,char **)48int main(int, char**) { 49 { 50 std::tuple<Explicit> foo = Derived<int>{42}; ((void)foo); 51 assert(count == 1); 52 Derived<int> d{42}; 53 std::tuple<Explicit> bar(std::move(d)); ((void)bar); 54 #if TEST_STD_VER < 17 55 assert(count == 1); 56 #else 57 assert(count == 2); 58 #endif 59 } 60 count = 0; 61 { 62 std::tuple<Implicit> foo = Derived<int>{42}; ((void)foo); 63 assert(count == 1); 64 Derived<int> d{42}; 65 std::tuple<Implicit> bar(std::move(d)); ((void)bar); 66 #if TEST_STD_VER < 17 67 assert(count == 1); 68 #else 69 assert(count == 2); 70 #endif 71 } 72 count = 0; 73 { 74 static_assert(!std::is_convertible<ExplicitDerived<int>, std::tuple<Explicit>>::value, ""); 75 ExplicitDerived<int> d{42}; 76 std::tuple<Explicit> bar(std::move(d)); ((void)bar); 77 #if TEST_STD_VER < 17 78 assert(count == 0); 79 #else 80 assert(count == 1); 81 #endif 82 } 83 count = 0; 84 { 85 std::tuple<Implicit> foo = ExplicitDerived<int>{42}; ((void)foo); 86 static_assert(std::is_convertible<ExplicitDerived<int>, std::tuple<Implicit>>::value, ""); 87 assert(count == 0); 88 ExplicitDerived<int> d{42}; 89 std::tuple<Implicit> bar(std::move(d)); ((void)bar); 90 #if TEST_STD_VER < 17 91 assert(count == 0); 92 #else 93 assert(count == 1); 94 #endif 95 } 96 count = 0; 97 98 return 0; 99 } 100