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 // <tuple> 10 11 // template <class... Types> 12 // template <class U1, class U2> 13 // constexpr explicit(see below) tuple<Types...>::tuple(pair<U1, U2>& u); 14 15 // Constraints: 16 // - sizeof...(Types) is 2 and 17 // - is_constructible_v<T0, decltype(get<0>(FWD(u)))> is true and 18 // - is_constructible_v<T1, decltype(get<1>(FWD(u)))> is true. 19 20 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 21 22 #include <cassert> 23 #include <tuple> 24 #include <utility> 25 26 #include "convert_types.h" 27 28 // test constraints 29 // sizeof...(Types) == 2 30 static_assert(std::is_constructible_v<std::tuple<MutableCopy, int>, std::pair<MutableCopy, int>&>); 31 32 static_assert(!std::is_constructible_v<std::tuple<MutableCopy>, std::pair<MutableCopy, int>&>); 33 34 static_assert(!std::is_constructible_v<std::tuple<MutableCopy, int, int>, std::pair<MutableCopy, int>&>); 35 36 // test constraints 37 // is_constructible_v<T0, decltype(get<0>(FWD(u)))> is true and 38 // is_constructible_v<T1, decltype(get<1>(FWD(u)))> is true. 39 static_assert(std::is_constructible_v<std::tuple<int, int>, std::pair<int, int>&>); 40 41 static_assert(!std::is_constructible_v<std::tuple<NoConstructorFromInt, int>, std::pair<int, int>&>); 42 43 static_assert(!std::is_constructible_v<std::tuple<int, NoConstructorFromInt>, std::pair<int, int>&>); 44 45 static_assert(!std::is_constructible_v< std::tuple<NoConstructorFromInt, NoConstructorFromInt>, std::pair<int, int>&>); 46 47 // test: The expression inside explicit is equivalent to: 48 // !is_convertible_v<decltype(get<0>(FWD(u))), T0> || 49 // !is_convertible_v<decltype(get<1>(FWD(u))), T1> 50 static_assert(std::is_convertible_v<std::pair<MutableCopy, MutableCopy>&, 51 std::tuple<ConvertibleFrom<MutableCopy>, ConvertibleFrom<MutableCopy>>>); 52 53 static_assert(!std::is_convertible_v<std::pair<MutableCopy, MutableCopy>&, 54 std::tuple<ExplicitConstructibleFrom<MutableCopy>, ConvertibleFrom<MutableCopy>>>); 55 56 static_assert(!std::is_convertible_v<std::pair<MutableCopy, MutableCopy>&, 57 std::tuple<ConvertibleFrom<MutableCopy>, ExplicitConstructibleFrom<MutableCopy>>>); 58 59 constexpr bool test() { 60 // test implicit conversions. 61 { 62 std::pair<MutableCopy, int> p{1, 2}; 63 std::tuple<ConvertibleFrom<MutableCopy>, ConvertibleFrom<int>> t = p; 64 assert(std::get<0>(t).v.val == 1); 65 assert(std::get<1>(t).v == 2); 66 } 67 68 // test explicit conversions. 69 { 70 std::pair<MutableCopy, int> p{1, 2}; 71 std::tuple<ExplicitConstructibleFrom<MutableCopy>, ExplicitConstructibleFrom<int>> t{p}; 72 assert(std::get<0>(t).v.val == 1); 73 assert(std::get<1>(t).v == 2); 74 } 75 76 // non const overload should be called 77 { 78 std::pair<TracedCopyMove, TracedCopyMove> p; 79 std::tuple<ConvertibleFrom<TracedCopyMove>, TracedCopyMove> t = p; 80 assert(nonConstCopyCtrCalled(std::get<0>(t).v)); 81 assert(nonConstCopyCtrCalled(std::get<1>(t))); 82 } 83 84 return true; 85 } 86 87 int main(int, char**) { 88 test(); 89 static_assert(test()); 90 91 return 0; 92 } 93