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// template <class TupleLike> tuple(TupleLike&&); // libc++ extension 16 17// See llvm.org/PR31384 18#include <tuple> 19#include <cassert> 20 21int count = 0; 22 23struct Explicit { 24 Explicit() = default; 25 explicit Explicit(int) {} 26}; 27 28struct Implicit { 29 Implicit() = default; 30 Implicit(int) {} 31}; 32 33template<class T> 34struct Derived : std::tuple<T> { 35 using std::tuple<T>::tuple; 36 template<class U> 37 operator std::tuple<U>() && { ++count; return {}; } 38}; 39 40 41template<class T> 42struct ExplicitDerived : std::tuple<T> { 43 using std::tuple<T>::tuple; 44 template<class U> 45 explicit operator std::tuple<U>() && { ++count; return {}; } 46}; 47 48int main() { 49 { 50 std::tuple<Explicit> foo = Derived<int>{42}; ((void)foo); 51 assert(count == 1); 52 std::tuple<Explicit> bar(Derived<int>{42}); ((void)bar); 53 assert(count == 2); 54 } 55 count = 0; 56 { 57 std::tuple<Implicit> foo = Derived<int>{42}; ((void)foo); 58 assert(count == 1); 59 std::tuple<Implicit> bar(Derived<int>{42}); ((void)bar); 60 assert(count == 2); 61 } 62 count = 0; 63 { 64 static_assert(!std::is_convertible< 65 ExplicitDerived<int>, std::tuple<Explicit>>::value, ""); 66 std::tuple<Explicit> bar(ExplicitDerived<int>{42}); ((void)bar); 67 assert(count == 1); 68 } 69 count = 0; 70 { 71 // FIXME: Libc++ incorrectly rejects this code. 72#ifndef _LIBCPP_VERSION 73 std::tuple<Implicit> foo = ExplicitDerived<int>{42}; ((void)foo); 74 static_assert(std::is_convertible< 75 ExplicitDerived<int>, std::tuple<Implicit>>::value, 76 "correct STLs accept this"); 77#else 78 static_assert(!std::is_convertible< 79 ExplicitDerived<int>, std::tuple<Implicit>>::value, 80 "libc++ incorrectly rejects this"); 81#endif 82 assert(count == 0); 83 std::tuple<Implicit> bar(ExplicitDerived<int>{42}); ((void)bar); 84 assert(count == 1); 85 } 86 count = 0; 87 88} 89