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 T, class U> struct pair;
     15 
     16 // pair(pair const&) = default;
     17 // pair(pair &&) = default;
     18 // pair& operator=(pair const&);
     19 // pair& operator=(pair&&);
     20 
     21 // Test that the copy/move constructors and assignment operators are
     22 // correctly defined or deleted based on the properties of `T` and `U`.
     23 
     24 #include <cassert>
     25 #include <string>
     26 #include <tuple>
     27 
     28 #include "archetypes.hpp"
     29 using namespace ImplicitTypes; // Get implicitly archetypes
     30 
     31 namespace ConstructorTest {
     32 
     33 template <class T1, bool CanCopy = true, bool CanMove = CanCopy> void test() {
     34   using P1 = std::pair<T1, int>;
     35   using P2 = std::pair<int, T1>;
     36   static_assert(std::is_copy_constructible<P1>::value == CanCopy, "");
     37   static_assert(std::is_move_constructible<P1>::value == CanMove, "");
     38   static_assert(std::is_copy_constructible<P2>::value == CanCopy, "");
     39   static_assert(std::is_move_constructible<P2>::value == CanMove, "");
     40 };
     41 
     42 } // namespace ConstructorTest
     43 
     44 void test_constructors_exist() {
     45   using namespace ConstructorTest;
     46   {
     47     test<int>();
     48     test<int &>();
     49     test<int &&, false, true>();
     50     test<const int>();
     51     test<const int &>();
     52     test<const int &&, false, true>();
     53   }
     54   {
     55     test<Copyable>();
     56     test<Copyable &>();
     57     test<Copyable &&, false, true>();
     58   }
     59   {
     60     test<NonCopyable, false>();
     61     test<NonCopyable &, true>();
     62     test<NonCopyable &&, false, true>();
     63   }
     64   {
     65     // Even though CopyOnly has an explicitly deleted move constructor
     66     // pair's move constructor is only implicitly deleted and therefore
     67     // it doesn't participate in overload resolution.
     68     test<CopyOnly, true, true>();
     69     test<CopyOnly &, true>();
     70     test<CopyOnly &&, false, true>();
     71   }
     72   {
     73     test<MoveOnly, false, true>();
     74     test<MoveOnly &, true>();
     75     test<MoveOnly &&, false, true>();
     76   }
     77 }
     78 
     79 namespace AssignmentOperatorTest {
     80 
     81 template <class T1, bool CanCopy = true, bool CanMove = CanCopy> void test() {
     82   using P1 = std::pair<T1, int>;
     83   using P2 = std::pair<int, T1>;
     84   static_assert(std::is_copy_assignable<P1>::value == CanCopy, "");
     85   static_assert(std::is_move_assignable<P1>::value == CanMove, "");
     86   static_assert(std::is_copy_assignable<P2>::value == CanCopy, "");
     87   static_assert(std::is_move_assignable<P2>::value == CanMove, "");
     88 };
     89 
     90 } // namespace AssignmentOperatorTest
     91 
     92 void test_assignment_operator_exists() {
     93   using namespace AssignmentOperatorTest;
     94   {
     95     test<int>();
     96     test<int &>();
     97     test<int &&>();
     98     test<const int, false>();
     99     test<const int &, false>();
    100     test<const int &&, false>();
    101   }
    102   {
    103     test<Copyable>();
    104     test<Copyable &>();
    105     test<Copyable &&>();
    106   }
    107   {
    108     test<NonCopyable, false>();
    109     test<NonCopyable &, false>();
    110     test<NonCopyable &&, false>();
    111   }
    112   {
    113     test<CopyOnly, true>();
    114     test<CopyOnly &, true>();
    115     test<CopyOnly &&, true>();
    116   }
    117   {
    118     test<MoveOnly, false, true>();
    119     test<MoveOnly &, false, false>();
    120     test<MoveOnly &&, false, true>();
    121   }
    122 }
    123 
    124 int main() {
    125   test_constructors_exist();
    126   test_assignment_operator_exists();
    127 }
    128