brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.7 KiB · d2b5551 Raw
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