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

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