Home | History | Annotate | Download | only in pairs.pair
      1 //===----------------------------------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is dual licensed under the MIT and the University of Illinois Open
      6 // Source Licenses. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 // UNSUPPORTED: c++98, c++03
     11 
     12 // <utility>
     13 
     14 // template <class T1, class T2> struct pair
     15 
     16 // template <class U, class V> pair(pair<U, V>&& p);
     17 
     18 #include <utility>
     19 #include <memory>
     20 #include <cassert>
     21 
     22 #include "archetypes.hpp"
     23 #include "test_convertible.hpp"
     24 using namespace ImplicitTypes; // Get implicitly archetypes
     25 
     26 template <class T1, class U1,
     27           bool CanCopy = true, bool CanConvert = CanCopy>
     28 void test_pair_rv()
     29 {
     30     using P1 = std::pair<T1, int>;
     31     using P2 = std::pair<int, T1>;
     32     using UP1 = std::pair<U1, int>&&;
     33     using UP2 = std::pair<int, U1>&&;
     34     static_assert(std::is_constructible<P1, UP1>::value == CanCopy, "");
     35     static_assert(test_convertible<P1, UP1>() == CanConvert, "");
     36     static_assert(std::is_constructible<P2, UP2>::value == CanCopy, "");
     37     static_assert(test_convertible<P2,  UP2>() == CanConvert, "");
     38 }
     39 
     40 struct Base
     41 {
     42     virtual ~Base() {}
     43 };
     44 
     45 struct Derived
     46     : public Base
     47 {
     48 };
     49 
     50 
     51 template <class T, class U>
     52 struct DPair : public std::pair<T, U> {
     53   using Base = std::pair<T, U>;
     54   using Base::Base;
     55 };
     56 
     57 struct ExplicitT {
     58   constexpr explicit ExplicitT(int x) : value(x) {}
     59   int value;
     60 };
     61 
     62 struct ImplicitT {
     63   constexpr ImplicitT(int x) : value(x) {}
     64   int value;
     65 };
     66 
     67 int main()
     68 {
     69     {
     70         typedef std::pair<std::unique_ptr<Derived>, short> P1;
     71         typedef std::pair<std::unique_ptr<Base>, long> P2;
     72         P1 p1(std::unique_ptr<Derived>(), 4);
     73         P2 p2 = std::move(p1);
     74         assert(p2.first == nullptr);
     75         assert(p2.second == 4);
     76     }
     77     {
     78         // We allow derived types to use this constructor
     79         using P1 = DPair<long, long>;
     80         using P2 = std::pair<int, int>;
     81         P1 p1(42, 101);
     82         P2 p2(std::move(p1));
     83         assert(p2.first == 42);
     84         assert(p2.second = 101);
     85     }
     86     {
     87         test_pair_rv<AllCtors, AllCtors>();
     88         test_pair_rv<AllCtors, AllCtors&>();
     89         test_pair_rv<AllCtors, AllCtors&&>();
     90         test_pair_rv<AllCtors, const AllCtors&>();
     91         test_pair_rv<AllCtors, const AllCtors&&>();
     92 
     93         test_pair_rv<ExplicitTypes::AllCtors, ExplicitTypes::AllCtors>();
     94         test_pair_rv<ExplicitTypes::AllCtors, ExplicitTypes::AllCtors&, true, false>();
     95         test_pair_rv<ExplicitTypes::AllCtors, ExplicitTypes::AllCtors&&, true, false>();
     96         test_pair_rv<ExplicitTypes::AllCtors, const ExplicitTypes::AllCtors&, true, false>();
     97         test_pair_rv<ExplicitTypes::AllCtors, const ExplicitTypes::AllCtors&&, true, false>();
     98 
     99         test_pair_rv<MoveOnly, MoveOnly>();
    100         test_pair_rv<MoveOnly, MoveOnly&, false>();
    101         test_pair_rv<MoveOnly, MoveOnly&&>();
    102 
    103         test_pair_rv<ExplicitTypes::MoveOnly, ExplicitTypes::MoveOnly>(); // copy construction
    104         test_pair_rv<ExplicitTypes::MoveOnly, ExplicitTypes::MoveOnly&, false>();
    105         test_pair_rv<ExplicitTypes::MoveOnly, ExplicitTypes::MoveOnly&&, true, false>();
    106 
    107         test_pair_rv<CopyOnly, CopyOnly>();
    108         test_pair_rv<CopyOnly, CopyOnly&>();
    109         test_pair_rv<CopyOnly, CopyOnly&&>();
    110 
    111         test_pair_rv<ExplicitTypes::CopyOnly, ExplicitTypes::CopyOnly>();
    112         test_pair_rv<ExplicitTypes::CopyOnly, ExplicitTypes::CopyOnly&, true, false>();
    113         test_pair_rv<ExplicitTypes::CopyOnly, ExplicitTypes::CopyOnly&&, true, false>();
    114 
    115         test_pair_rv<NonCopyable, NonCopyable, false>();
    116         test_pair_rv<NonCopyable, NonCopyable&, false>();
    117         test_pair_rv<NonCopyable, NonCopyable&&, false>();
    118         test_pair_rv<NonCopyable, const NonCopyable&, false>();
    119         test_pair_rv<NonCopyable, const NonCopyable&&, false>();
    120     }
    121     { // Test construction of references
    122         test_pair_rv<NonCopyable&, NonCopyable&>();
    123         test_pair_rv<NonCopyable&, NonCopyable&&>();
    124         test_pair_rv<NonCopyable&, NonCopyable const&, false>();
    125         test_pair_rv<NonCopyable const&, NonCopyable&&>();
    126         test_pair_rv<NonCopyable&&, NonCopyable&&>();
    127 
    128         test_pair_rv<ConvertingType&, int, false>();
    129         test_pair_rv<ExplicitTypes::ConvertingType&, int, false>();
    130         // Unfortunately the below conversions are allowed and create dangling
    131         // references.
    132         //test_pair_rv<ConvertingType&&, int>();
    133         //test_pair_rv<ConvertingType const&, int>();
    134         //test_pair_rv<ConvertingType const&&, int>();
    135         // But these are not because the converting constructor is explicit.
    136         test_pair_rv<ExplicitTypes::ConvertingType&&, int, false>();
    137         test_pair_rv<ExplicitTypes::ConvertingType const&, int, false>();
    138         test_pair_rv<ExplicitTypes::ConvertingType const&&, int, false>();
    139     }
    140     {
    141         test_pair_rv<AllCtors, int, false>();
    142         test_pair_rv<ExplicitTypes::AllCtors, int, false>();
    143         test_pair_rv<ConvertingType, int>();
    144         test_pair_rv<ExplicitTypes::ConvertingType, int, true, false>();
    145 
    146         test_pair_rv<ConvertingType, int>();
    147         test_pair_rv<ConvertingType, ConvertingType>();
    148         test_pair_rv<ConvertingType, ConvertingType const&>();
    149         test_pair_rv<ConvertingType, ConvertingType&>();
    150         test_pair_rv<ConvertingType, ConvertingType&&>();
    151 
    152         test_pair_rv<ExplicitTypes::ConvertingType, int, true, false>();
    153         test_pair_rv<ExplicitTypes::ConvertingType, int&, true, false>();
    154         test_pair_rv<ExplicitTypes::ConvertingType, const int&, true, false>();
    155         test_pair_rv<ExplicitTypes::ConvertingType, int&&, true, false>();
    156         test_pair_rv<ExplicitTypes::ConvertingType, const int&&, true, false>();
    157 
    158         test_pair_rv<ExplicitTypes::ConvertingType, ExplicitTypes::ConvertingType>();
    159         test_pair_rv<ExplicitTypes::ConvertingType, ExplicitTypes::ConvertingType const&, true, false>();
    160         test_pair_rv<ExplicitTypes::ConvertingType, ExplicitTypes::ConvertingType&, true, false>();
    161         test_pair_rv<ExplicitTypes::ConvertingType, ExplicitTypes::ConvertingType&&, true, false>();
    162     }
    163 #if TEST_STD_VER > 11
    164     { // explicit constexpr test
    165         constexpr std::pair<int, int> p1(42, 43);
    166         constexpr std::pair<ExplicitT, ExplicitT> p2(std::move(p1));
    167         static_assert(p2.first.value == 42, "");
    168         static_assert(p2.second.value == 43, "");
    169     }
    170     { // implicit constexpr test
    171         constexpr std::pair<int, int> p1(42, 43);
    172         constexpr std::pair<ImplicitT, ImplicitT> p2 = std::move(p1);
    173         static_assert(p2.first.value == 42, "");
    174         static_assert(p2.second.value == 43, "");
    175     }
    176 #endif
    177 }
    178