133 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... UTypes>14// tuple& operator=(const tuple<UTypes...>& u);15 16// UNSUPPORTED: c++0317 18#include <tuple>19#include <string>20#include <cassert>21 22#include "test_macros.h"23 24struct B {25 int id_;26 27 constexpr explicit B(int i = 0) : id_(i) {}28};29 30struct D : B {31 constexpr explicit D(int i = 0) : B(i) {}32};33 34struct NonAssignable {35 NonAssignable& operator=(NonAssignable const&) = delete;36 NonAssignable& operator=(NonAssignable&&) = delete;37};38 39struct NothrowCopyAssignable {40 NothrowCopyAssignable(NothrowCopyAssignable const&) = delete;41 NothrowCopyAssignable& operator=(NothrowCopyAssignable const&) noexcept { return *this; }42};43 44struct PotentiallyThrowingCopyAssignable {45 PotentiallyThrowingCopyAssignable(PotentiallyThrowingCopyAssignable const&) = delete;46 PotentiallyThrowingCopyAssignable& operator=(PotentiallyThrowingCopyAssignable const&) { return *this; }47};48 49TEST_CONSTEXPR_CXX2050bool test()51{52 {53 typedef std::tuple<long> T0;54 typedef std::tuple<long long> T1;55 T0 t0(2);56 T1 t1;57 t1 = t0;58 assert(std::get<0>(t1) == 2);59 }60 {61 typedef std::tuple<long, char> T0;62 typedef std::tuple<long long, int> T1;63 T0 t0(2, 'a');64 T1 t1;65 t1 = t0;66 assert(std::get<0>(t1) == 2);67 assert(std::get<1>(t1) == int('a'));68 }69 {70 typedef std::tuple<long, char, D> T0;71 typedef std::tuple<long long, int, B> T1;72 T0 t0(2, 'a', D(3));73 T1 t1;74 t1 = t0;75 assert(std::get<0>(t1) == 2);76 assert(std::get<1>(t1) == int('a'));77 assert(std::get<2>(t1).id_ == 3);78 }79 {80 D d(3);81 D d2(2);82 typedef std::tuple<long, char, D&> T0;83 typedef std::tuple<long long, int, B&> T1;84 T0 t0(2, 'a', d2);85 T1 t1(1, 'b', d);86 t1 = t0;87 assert(std::get<0>(t1) == 2);88 assert(std::get<1>(t1) == int('a'));89 assert(std::get<2>(t1).id_ == 2);90 }91 {92 // Test that tuple evaluates correctly applies an lvalue reference93 // before evaluating is_assignable (i.e. 'is_assignable<int&, int&>')94 // instead of evaluating 'is_assignable<int&&, int&>' which is false.95 int x = 42;96 int y = 43;97 std::tuple<int&&> t(std::move(x));98 std::tuple<int&> t2(y);99 t = t2;100 assert(std::get<0>(t) == 43);101 assert(&std::get<0>(t) == &x);102 }103 return true;104}105 106int main(int, char**)107{108 test();109#if TEST_STD_VER >= 20110 static_assert(test());111#endif112 113 {114 using T = std::tuple<int, NonAssignable>;115 using U = std::tuple<NonAssignable, int>;116 static_assert(!std::is_assignable<T&, U const&>::value, "");117 static_assert(!std::is_assignable<U&, T const&>::value, "");118 }119 {120 typedef std::tuple<NothrowCopyAssignable, long> T0;121 typedef std::tuple<NothrowCopyAssignable, int> T1;122 static_assert(std::is_nothrow_assignable<T0&, T1 const&>::value, "");123 }124 {125 typedef std::tuple<PotentiallyThrowingCopyAssignable, long> T0;126 typedef std::tuple<PotentiallyThrowingCopyAssignable, int> T1;127 static_assert(std::is_assignable<T0&, T1 const&>::value, "");128 static_assert(!std::is_nothrow_assignable<T0&, T1 const&>::value, "");129 }130 131 return 0;132}133