154 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// tuple& operator=(const tuple& u);14 15// UNSUPPORTED: c++0316 17#include <tuple>18#include <memory>19#include <string>20#include <cassert>21 22#include "test_macros.h"23 24struct NonAssignable {25 NonAssignable& operator=(NonAssignable const&) = delete;26 NonAssignable& operator=(NonAssignable&&) = delete;27};28struct CopyAssignable {29 CopyAssignable& operator=(CopyAssignable const&) = default;30 CopyAssignable& operator=(CopyAssignable &&) = delete;31};32static_assert(std::is_copy_assignable<CopyAssignable>::value, "");33struct MoveAssignable {34 MoveAssignable& operator=(MoveAssignable const&) = delete;35 MoveAssignable& operator=(MoveAssignable&&) = default;36};37struct NothrowCopyAssignable {38 NothrowCopyAssignable& operator=(NothrowCopyAssignable const&) noexcept { return *this; }39};40struct PotentiallyThrowingCopyAssignable {41 PotentiallyThrowingCopyAssignable& operator=(PotentiallyThrowingCopyAssignable const&) { return *this; }42};43 44struct CopyAssignableInt {45 CopyAssignableInt& operator=(int&) { return *this; }46};47 48TEST_CONSTEXPR_CXX2049bool test()50{51 {52 typedef std::tuple<> T;53 T t0;54 T t;55 t = t0;56 }57 {58 typedef std::tuple<int> T;59 T t0(2);60 T t;61 t = t0;62 assert(std::get<0>(t) == 2);63 }64 {65 typedef std::tuple<int, char> T;66 T t0(2, 'a');67 T t;68 t = t0;69 assert(std::get<0>(t) == 2);70 assert(std::get<1>(t) == 'a');71 }72 {73 // test reference assignment.74 using T = std::tuple<int&, int&&>;75 int x = 42;76 int y = 100;77 int x2 = -1;78 int y2 = 500;79 T t(x, std::move(y));80 T t2(x2, std::move(y2));81 t = t2;82 assert(std::get<0>(t) == x2);83 assert(&std::get<0>(t) == &x);84 assert(std::get<1>(t) == y2);85 assert(&std::get<1>(t) == &y);86 }87 88 return true;89}90 91int main(int, char**)92{93 test();94#if TEST_STD_VER >= 2095 static_assert(test());96#endif97 98 {99 // cannot be constexpr because of std::string100 typedef std::tuple<int, char, std::string> T;101 const T t0(2, 'a', "some text");102 T t;103 t = t0;104 assert(std::get<0>(t) == 2);105 assert(std::get<1>(t) == 'a');106 assert(std::get<2>(t) == "some text");107 }108 {109 // test that the implicitly generated copy assignment operator110 // is properly deleted111 using T = std::tuple<std::unique_ptr<int>>;112 static_assert(!std::is_copy_assignable<T>::value, "");113 }114 {115 using T = std::tuple<int, NonAssignable>;116 static_assert(!std::is_copy_assignable<T>::value, "");117 }118 {119 using T = std::tuple<int, CopyAssignable>;120 static_assert(std::is_copy_assignable<T>::value, "");121 }122 {123 using T = std::tuple<int, MoveAssignable>;124 static_assert(!std::is_copy_assignable<T>::value, "");125 }126 {127 using T = std::tuple<int, int, int>;128 using P = std::pair<int, int>;129 static_assert(!std::is_assignable<T&, P>::value, "");130 }131 {132 // test const requirement133 using T = std::tuple<CopyAssignableInt, CopyAssignableInt>;134 using P = std::pair<int, int>;135 static_assert(!std::is_assignable<T&, P const>::value, "");136 }137 {138 using T = std::tuple<int, MoveAssignable>;139 using P = std::pair<int, MoveAssignable>;140 static_assert(!std::is_assignable<T&, P&>::value, "");141 }142 {143 using T = std::tuple<NothrowCopyAssignable, int>;144 static_assert(std::is_nothrow_copy_assignable<T>::value, "");145 }146 {147 using T = std::tuple<PotentiallyThrowingCopyAssignable, int>;148 static_assert(std::is_copy_assignable<T>::value, "");149 static_assert(!std::is_nothrow_copy_assignable<T>::value, "");150 }151 152 return 0;153}154