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(const 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 "copy_move_types.h"
27
28// test constraints
29// sizeof...(Types) == 2
30static_assert(std::is_constructible_v<std::tuple<ConstMove, int>, const std::pair<ConstMove, int>&&>);
31
32static_assert(!std::is_constructible_v<std::tuple<ConstMove>, const std::pair<ConstMove, int>&&>);
33
34static_assert(!std::is_constructible_v<std::tuple<ConstMove, int, int>, const std::pair<ConstMove, 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.
39static_assert(std::is_constructible_v<std::tuple<int, int>, const std::pair<int, int>&&>);
40
41static_assert(!std::is_constructible_v<std::tuple<NoConstructorFromInt, int>, const std::pair<int, int>&&>);
42
43static_assert(!std::is_constructible_v<std::tuple<int, NoConstructorFromInt>, const std::pair<int, int>&&>);
44
45static_assert(
46 !std::is_constructible_v< std::tuple<NoConstructorFromInt, NoConstructorFromInt>, const std::pair<int, int>&&>);
47
48// test: The expression inside explicit is equivalent to:
49// !is_convertible_v<decltype(get<0>(FWD(u))), T0> ||
50// !is_convertible_v<decltype(get<1>(FWD(u))), T1>
51static_assert(std::is_convertible_v<const std::pair<ConstMove, ConstMove>&&,
52 std::tuple<ConvertibleFrom<ConstMove>, ConvertibleFrom<ConstMove>>>);
53
54static_assert(!std::is_convertible_v<const std::pair<ConstMove, ConstMove>&&,
55 std::tuple<ExplicitConstructibleFrom<ConstMove>, ConvertibleFrom<ConstMove>>>);
56
57static_assert(!std::is_convertible_v<const std::pair<ConstMove, ConstMove>&&,
58 std::tuple<ConvertibleFrom<ConstMove>, ExplicitConstructibleFrom<ConstMove>>>);
59
60constexpr bool test() {
61 // test implicit conversions.
62 {
63 const std::pair<ConstMove, int> p{1, 2};
64 std::tuple<ConvertibleFrom<ConstMove>, ConvertibleFrom<int>> t = std::move(p);
65 assert(std::get<0>(t).v.val == 1);
66 assert(std::get<1>(t).v == 2);
67 }
68
69 // test explicit conversions.
70 {
71 const std::pair<ConstMove, int> p{1, 2};
72 std::tuple<ExplicitConstructibleFrom<ConstMove>, ExplicitConstructibleFrom<int>> t{std::move(p)};
73 assert(std::get<0>(t).v.val == 1);
74 assert(std::get<1>(t).v == 2);
75 }
76
77 // non const overload should be called
78 {
79 const std::pair<TracedCopyMove, TracedCopyMove> p;
80 std::tuple<ConvertibleFrom<TracedCopyMove>, TracedCopyMove> t = std::move(p);
81 assert(constMoveCtrCalled(std::get<0>(t).v));
82 assert(constMoveCtrCalled(std::get<1>(t)));
83 }
84
85 return true;
86}
87
88int main(int, char**) {
89 test();
90 static_assert(test());
91
92 return 0;
93}
94

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