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

source code of libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/PR31384.pass.cpp