93 lines · cpp
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-exception6//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 and17// - is_constructible_v<T0, decltype(get<0>(FWD(u)))> is true and18// - is_constructible_v<T1, decltype(get<1>(FWD(u)))> is true.19 20// UNSUPPORTED: c++03, c++11, c++14, c++17, c++2021 22#include <cassert>23#include <tuple>24#include <utility>25 26#include "copy_move_types.h"27 28// test constraints29// sizeof...(Types) == 230static_assert(std::is_constructible_v<std::tuple<MutableCopy, int>, std::pair<MutableCopy, int>&>);31 32static_assert(!std::is_constructible_v<std::tuple<MutableCopy>, std::pair<MutableCopy, int>&>);33 34static_assert(!std::is_constructible_v<std::tuple<MutableCopy, int, int>, std::pair<MutableCopy, int>&>);35 36// test constraints37// is_constructible_v<T0, decltype(get<0>(FWD(u)))> is true and38// is_constructible_v<T1, decltype(get<1>(FWD(u)))> is true.39static_assert(std::is_constructible_v<std::tuple<int, int>, std::pair<int, int>&>);40 41static_assert(!std::is_constructible_v<std::tuple<NoConstructorFromInt, int>, std::pair<int, int>&>);42 43static_assert(!std::is_constructible_v<std::tuple<int, NoConstructorFromInt>, std::pair<int, int>&>);44 45static_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>50static_assert(std::is_convertible_v<std::pair<MutableCopy, MutableCopy>&,51 std::tuple<ConvertibleFrom<MutableCopy>, ConvertibleFrom<MutableCopy>>>);52 53static_assert(!std::is_convertible_v<std::pair<MutableCopy, MutableCopy>&,54 std::tuple<ExplicitConstructibleFrom<MutableCopy>, ConvertibleFrom<MutableCopy>>>);55 56static_assert(!std::is_convertible_v<std::pair<MutableCopy, MutableCopy>&,57 std::tuple<ConvertibleFrom<MutableCopy>, ExplicitConstructibleFrom<MutableCopy>>>);58 59constexpr 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 called77 {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 87int main(int, char**) {88 test();89 static_assert(test());90 91 return 0;92}93