brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.3 KiB · 6e7e431 Raw
325 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> class tuple;12 13// template <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls);14 15// UNSUPPORTED: c++0316 17#include <tuple>18#include <utility>19#include <array>20#include <string>21#include <cassert>22 23#include "test_macros.h"24#include "MoveOnly.h"25 26namespace NS {27struct Namespaced {28  int i;29};30template<typename ...Ts>31void forward_as_tuple(Ts...) = delete;32}33 34// https://llvm.org/PR4168935struct Unconstrained {36  int data;37  template <typename Arg>38  TEST_CONSTEXPR_CXX14 Unconstrained(Arg arg) : data(arg) {}39};40 41TEST_CONSTEXPR_CXX14 bool test_tuple_cat_with_unconstrained_constructor() {42  {43    auto tup_src = std::tuple<Unconstrained>(Unconstrained(5));44    auto tup     = std::tuple_cat(tup_src);45    assert(std::get<0>(tup).data == 5);46  }47  {48    auto tup = std::tuple_cat(std::tuple<Unconstrained>(Unconstrained(6)));49    assert(std::get<0>(tup).data == 6);50  }51  {52    auto tup = std::tuple_cat(std::tuple<Unconstrained>(Unconstrained(7)), std::tuple<>());53    assert(std::get<0>(tup).data == 7);54  }55#if TEST_STD_VER >= 1756  {57    auto tup_src = std::tuple(Unconstrained(8));58    auto tup     = std::tuple_cat(tup_src);59    ASSERT_SAME_TYPE(decltype(tup), std::tuple<Unconstrained>);60    assert(std::get<0>(tup).data == 8);61  }62  {63    auto tup = std::tuple_cat(std::tuple(Unconstrained(9)));64    ASSERT_SAME_TYPE(decltype(tup), std::tuple<Unconstrained>);65    assert(std::get<0>(tup).data == 9);66  }67  {68    auto tup = std::tuple_cat(std::tuple(Unconstrained(10)), std::tuple());69    ASSERT_SAME_TYPE(decltype(tup), std::tuple<Unconstrained>);70    assert(std::get<0>(tup).data == 10);71  }72#endif73  return true;74}75 76int main(int, char**)77{78    {79        std::tuple<> t = std::tuple_cat();80        ((void)t); // Prevent unused warning81    }82    {83        std::tuple<> t1;84        std::tuple<> t2 = std::tuple_cat(t1);85        ((void)t2); // Prevent unused warning86    }87    {88        std::tuple<> t = std::tuple_cat(std::tuple<>());89        ((void)t); // Prevent unused warning90    }91    {92        std::tuple<> t = std::tuple_cat(std::array<int, 0>());93        ((void)t); // Prevent unused warning94    }95    {96        std::tuple<int> t1(1);97        std::tuple<int> t = std::tuple_cat(t1);98        assert(std::get<0>(t) == 1);99    }100 101#if TEST_STD_VER > 11102    {103        constexpr std::tuple<> t = std::tuple_cat();104        ((void)t); // Prevent unused warning105    }106    {107        constexpr std::tuple<> t1;108        constexpr std::tuple<> t2 = std::tuple_cat(t1);109        ((void)t2); // Prevent unused warning110    }111    {112        constexpr std::tuple<> t = std::tuple_cat(std::tuple<>());113        ((void)t); // Prevent unused warning114    }115    {116        constexpr std::tuple<> t = std::tuple_cat(std::array<int, 0>());117        ((void)t); // Prevent unused warning118    }119    {120        constexpr std::tuple<int> t1(1);121        constexpr std::tuple<int> t = std::tuple_cat(t1);122        static_assert(std::get<0>(t) == 1, "");123    }124    {125        constexpr std::tuple<int> t1(1);126        constexpr std::tuple<int, int> t = std::tuple_cat(t1, t1);127        static_assert(std::get<0>(t) == 1, "");128        static_assert(std::get<1>(t) == 1, "");129    }130#endif131    {132        std::tuple<int, MoveOnly> t =133                                std::tuple_cat(std::tuple<int, MoveOnly>(1, 2));134        assert(std::get<0>(t) == 1);135        assert(std::get<1>(t) == 2);136    }137    {138        std::tuple<int, int, int> t = std::tuple_cat(std::array<int, 3>());139        assert(std::get<0>(t) == 0);140        assert(std::get<1>(t) == 0);141        assert(std::get<2>(t) == 0);142    }143    {144        std::tuple<int, MoveOnly> t = std::tuple_cat(std::pair<int, MoveOnly>(2, 1));145        assert(std::get<0>(t) == 2);146        assert(std::get<1>(t) == 1);147    }148 149    {150        std::tuple<> t1;151        std::tuple<> t2;152        std::tuple<> t3 = std::tuple_cat(t1, t2);153        ((void)t3); // Prevent unused warning154    }155    {156        std::tuple<> t1;157        std::tuple<int> t2(2);158        std::tuple<int> t3 = std::tuple_cat(t1, t2);159        assert(std::get<0>(t3) == 2);160    }161    {162        std::tuple<> t1;163        std::tuple<int> t2(2);164        std::tuple<int> t3 = std::tuple_cat(t2, t1);165        assert(std::get<0>(t3) == 2);166    }167    {168        std::tuple<int*> t1;169        std::tuple<int> t2(2);170        std::tuple<int*, int> t3 = std::tuple_cat(t1, t2);171        assert(std::get<0>(t3) == nullptr);172        assert(std::get<1>(t3) == 2);173    }174    {175        std::tuple<int*> t1;176        std::tuple<int> t2(2);177        std::tuple<int, int*> t3 = std::tuple_cat(t2, t1);178        assert(std::get<0>(t3) == 2);179        assert(std::get<1>(t3) == nullptr);180    }181    {182        std::tuple<int*> t1;183        std::tuple<int, double> t2(2, 3.5);184        std::tuple<int*, int, double> t3 = std::tuple_cat(t1, t2);185        assert(std::get<0>(t3) == nullptr);186        assert(std::get<1>(t3) == 2);187        assert(std::get<2>(t3) == 3.5);188    }189    {190        std::tuple<int*> t1;191        std::tuple<int, double> t2(2, 3.5);192        std::tuple<int, double, int*> t3 = std::tuple_cat(t2, t1);193        assert(std::get<0>(t3) == 2);194        assert(std::get<1>(t3) == 3.5);195        assert(std::get<2>(t3) == nullptr);196    }197    {198        std::tuple<int*, MoveOnly> t1(nullptr, 1);199        std::tuple<int, double> t2(2, 3.5);200        std::tuple<int*, MoveOnly, int, double> t3 =201                                              std::tuple_cat(std::move(t1), t2);202        assert(std::get<0>(t3) == nullptr);203        assert(std::get<1>(t3) == 1);204        assert(std::get<2>(t3) == 2);205        assert(std::get<3>(t3) == 3.5);206    }207    {208        std::tuple<int*, MoveOnly> t1(nullptr, 1);209        std::tuple<int, double> t2(2, 3.5);210        std::tuple<int, double, int*, MoveOnly> t3 =211                                              std::tuple_cat(t2, std::move(t1));212        assert(std::get<0>(t3) == 2);213        assert(std::get<1>(t3) == 3.5);214        assert(std::get<2>(t3) == nullptr);215        assert(std::get<3>(t3) == 1);216    }217    {218        std::tuple<MoveOnly, MoveOnly> t1(1, 2);219        std::tuple<int*, MoveOnly> t2(nullptr, 4);220        std::tuple<MoveOnly, MoveOnly, int*, MoveOnly> t3 =221                                   std::tuple_cat(std::move(t1), std::move(t2));222        assert(std::get<0>(t3) == 1);223        assert(std::get<1>(t3) == 2);224        assert(std::get<2>(t3) == nullptr);225        assert(std::get<3>(t3) == 4);226    }227 228    {229        std::tuple<MoveOnly, MoveOnly> t1(1, 2);230        std::tuple<int*, MoveOnly> t2(nullptr, 4);231        std::tuple<MoveOnly, MoveOnly, int*, MoveOnly> t3 =232                                   std::tuple_cat(std::tuple<>(),233                                                  std::move(t1),234                                                  std::move(t2));235        assert(std::get<0>(t3) == 1);236        assert(std::get<1>(t3) == 2);237        assert(std::get<2>(t3) == nullptr);238        assert(std::get<3>(t3) == 4);239    }240    {241        std::tuple<MoveOnly, MoveOnly> t1(1, 2);242        std::tuple<int*, MoveOnly> t2(nullptr, 4);243        std::tuple<MoveOnly, MoveOnly, int*, MoveOnly> t3 =244                                   std::tuple_cat(std::move(t1),245                                                  std::tuple<>(),246                                                  std::move(t2));247        assert(std::get<0>(t3) == 1);248        assert(std::get<1>(t3) == 2);249        assert(std::get<2>(t3) == nullptr);250        assert(std::get<3>(t3) == 4);251    }252    {253        std::tuple<MoveOnly, MoveOnly> t1(1, 2);254        std::tuple<int*, MoveOnly> t2(nullptr, 4);255        std::tuple<MoveOnly, MoveOnly, int*, MoveOnly> t3 =256                                   std::tuple_cat(std::move(t1),257                                                  std::move(t2),258                                                  std::tuple<>());259        assert(std::get<0>(t3) == 1);260        assert(std::get<1>(t3) == 2);261        assert(std::get<2>(t3) == nullptr);262        assert(std::get<3>(t3) == 4);263    }264    {265        std::tuple<MoveOnly, MoveOnly> t1(1, 2);266        std::tuple<int*, MoveOnly> t2(nullptr, 4);267        std::tuple<MoveOnly, MoveOnly, int*, MoveOnly, int> t3 =268                                   std::tuple_cat(std::move(t1),269                                                  std::move(t2),270                                                  std::tuple<int>(5));271        assert(std::get<0>(t3) == 1);272        assert(std::get<1>(t3) == 2);273        assert(std::get<2>(t3) == nullptr);274        assert(std::get<3>(t3) == 4);275        assert(std::get<4>(t3) == 5);276    }277    {278        // See bug #19616.279        auto t1 = std::tuple_cat(280            std::make_tuple(std::make_tuple(1)),281            std::make_tuple()282        );283        assert(t1 == std::make_tuple(std::make_tuple(1)));284 285        auto t2 = std::tuple_cat(286            std::make_tuple(std::make_tuple(1)),287            std::make_tuple(std::make_tuple(2))288        );289        assert(t2 == std::make_tuple(std::make_tuple(1), std::make_tuple(2)));290    }291    {292        int x = 101;293        std::tuple<int, const int, int&, const int&, int&&> t(42, 101, x, x, std::move(x));294        const auto& ct = t;295        std::tuple<int, const int, int&, const int&> t2(42, 101, x, x);296        const auto& ct2 = t2;297 298        auto r = std::tuple_cat(std::move(t), std::move(ct), t2, ct2);299 300        ASSERT_SAME_TYPE(decltype(r), std::tuple<301            int, const int, int&, const int&, int&&,302            int, const int, int&, const int&, int&&,303            int, const int, int&, const int&,304            int, const int, int&, const int&>);305        ((void)r);306    }307    {308        std::tuple<NS::Namespaced> t1(NS::Namespaced{1});309        std::tuple<NS::Namespaced> t = std::tuple_cat(t1);310        std::tuple<NS::Namespaced, NS::Namespaced> t2 =311            std::tuple_cat(t1, t1);312        assert(std::get<0>(t).i == 1);313        assert(std::get<0>(t2).i == 1);314    }315    // See https://llvm.org/PR41689316    {317      test_tuple_cat_with_unconstrained_constructor();318#if TEST_STD_VER >= 14319      static_assert(test_tuple_cat_with_unconstrained_constructor(), "");320#endif321    }322 323    return 0;324}325