brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.4 KiB · 8f778f3 Raw
139 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... UTypes>13//   constexpr explicit(see below) tuple<Types>::tuple(const14//   tuple<UTypes...>&&);15//16// Constraints:17//  sizeof...(Types) equals sizeof...(UTypes) &&18//  (is_constructible_v<Types, decltype(get<I>(FWD(u)))> && ...) is true &&19//  (20//    sizeof...(Types) is not 1 ||21//    (22//      !is_convertible_v<decltype(u), T> &&23//      !is_constructible_v<T, decltype(u)> &&24//      !is_same_v<T, U>25//    )26//  )27 28// UNSUPPORTED: c++03, c++11, c++14, c++17, c++2029 30#include <cassert>31#include <tuple>32 33#include "copy_move_types.h"34#include "test_macros.h"35 36// test: The expression inside explicit is equivalent to:37// !(is_convertible_v<decltype(get<I>(FWD(u))), Types> && ...)38static_assert(std::is_convertible_v<const std::tuple<ConstMove>&&, std::tuple<ConvertibleFrom<ConstMove>>>);39 40static_assert(std::is_convertible_v<const std::tuple<ConstMove, ConstMove>&&,41                                    std::tuple<ConvertibleFrom<ConstMove>, ConvertibleFrom<ConstMove>>>);42 43static_assert(44    !std::is_convertible_v<const std::tuple<MutableCopy>&&, std::tuple<ExplicitConstructibleFrom<ConstMove>>>);45 46static_assert(!std::is_convertible_v<const std::tuple<ConstMove, ConstMove>&&,47                                     std::tuple<ConvertibleFrom<ConstMove>, ExplicitConstructibleFrom<ConstMove>>>);48 49constexpr bool test() {50  // test implicit conversions.51  // sizeof...(Types) == 152  {53    const std::tuple<ConstMove> t1{1};54    std::tuple<ConvertibleFrom<ConstMove>> t2 = std::move(t1);55    assert(std::get<0>(t2).v.val == 1);56  }57 58  // test implicit conversions.59  // sizeof...(Types) > 160  {61    const std::tuple<ConstMove, int> t1{1, 2};62    std::tuple<ConvertibleFrom<ConstMove>, int> t2 = std::move(t1);63    assert(std::get<0>(t2).v.val == 1);64    assert(std::get<1>(t2) == 2);65  }66 67  // test explicit conversions.68  // sizeof...(Types) == 169  {70    const std::tuple<ConstMove> t1{1};71    std::tuple<ExplicitConstructibleFrom<ConstMove>> t2{std::move(t1)};72    assert(std::get<0>(t2).v.val == 1);73  }74 75  // test explicit conversions.76  // sizeof...(Types) > 177  {78    const std::tuple<ConstMove, int> t1{1, 2};79    std::tuple<ExplicitConstructibleFrom<ConstMove>, int> t2{std::move(t1)};80    assert(std::get<0>(t2).v.val == 1);81    assert(std::get<1>(t2) == 2);82  }83 84  // test constraints85 86  // sizeof...(Types) != sizeof...(UTypes)87  static_assert(!std::is_constructible_v<std::tuple<int, int>, const std::tuple<int>&&>);88  static_assert(!std::is_constructible_v<std::tuple<int, int, int>, const std::tuple<int, int>&&>);89 90  // !(is_constructible_v<Types, decltype(get<I>(FWD(u)))> && ...)91  static_assert(!std::is_constructible_v<std::tuple<int, NoConstructorFromInt>, const std::tuple<int, int>&&>);92 93  // sizeof...(Types) == 1 && other branch of "||" satisfied94  {95    const std::tuple<TracedCopyMove> t1{};96    std::tuple<ConvertibleFrom<TracedCopyMove>> t2{std::move(t1)};97    assert(constMoveCtrCalled(std::get<0>(t2).v));98  }99 100  // sizeof...(Types) == 1 && is_same_v<T, U>101  {102    const std::tuple<TracedCopyMove> t1{};103    std::tuple<TracedCopyMove> t2{t1};104    assert(!constMoveCtrCalled(std::get<0>(t2)));105  }106 107  // sizeof...(Types) != 1108  {109    const std::tuple<TracedCopyMove, TracedCopyMove> t1{};110    std::tuple<TracedCopyMove, TracedCopyMove> t2{std::move(t1)};111    assert(constMoveCtrCalled(std::get<0>(t2)));112  }113 114  // These two test points cause gcc to ICE115#if !defined(TEST_COMPILER_GCC)116  // sizeof...(Types) == 1 && is_convertible_v<decltype(u), T>117  {118    const std::tuple<CvtFromConstTupleRefRef> t1{};119    std::tuple<ConvertibleFrom<CvtFromConstTupleRefRef>> t2{std::move(t1)};120    assert(!constMoveCtrCalled(std::get<0>(t2).v));121  }122 123  // sizeof...(Types) == 1 && is_constructible_v<decltype(u), T>124  {125    const std::tuple<ExplicitCtrFromConstTupleRefRef> t1{};126    std::tuple<ConvertibleFrom<ExplicitCtrFromConstTupleRefRef>> t2{std::move(t1)};127    assert(!constMoveCtrCalled(std::get<0>(t2).v));128  }129#endif130 131  return true;132}133 134int main(int, char**) {135  test();136  static_assert(test());137  return 0;138}139