• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // pair& operator=(pair&& p);
17 
18 #include <utility>
19 #include <memory>
20 #include <cassert>
21 
22 
23 struct NonAssignable {
24   NonAssignable& operator=(NonAssignable const&) = delete;
25   NonAssignable& operator=(NonAssignable&&) = delete;
26 };
27 struct CopyAssignable {
28   CopyAssignable() = default;
29   CopyAssignable& operator=(CopyAssignable const&) = default;
30   CopyAssignable& operator=(CopyAssignable&&) = delete;
31 };
32 struct MoveAssignable {
33   MoveAssignable() = default;
34   MoveAssignable& operator=(MoveAssignable const&) = delete;
35   MoveAssignable& operator=(MoveAssignable&&) = default;
36 };
37 
38 struct CountAssign {
39   static int copied;
40   static int moved;
resetCountAssign41   static void reset() { copied = moved = 0; }
42   CountAssign() = default;
operator =CountAssign43   CountAssign& operator=(CountAssign const&) { ++copied; return *this; }
operator =CountAssign44   CountAssign& operator=(CountAssign&&) { ++moved; return *this; }
45 };
46 int CountAssign::copied = 0;
47 int CountAssign::moved = 0;
48 
main()49 int main()
50 {
51     {
52         typedef std::pair<std::unique_ptr<int>, int> P;
53         P p1(std::unique_ptr<int>(new int(3)), 4);
54         P p2;
55         p2 = std::move(p1);
56         assert(*p2.first == 3);
57         assert(p2.second == 4);
58     }
59     {
60         using P = std::pair<int&, int&&>;
61         int x = 42;
62         int y = 101;
63         int x2 = -1;
64         int y2 = 300;
65         P p1(x, std::move(y));
66         P p2(x2, std::move(y2));
67         p1 = std::move(p2);
68         assert(p1.first == x2);
69         assert(p1.second == y2);
70     }
71     {
72         using P = std::pair<int, NonAssignable>;
73         static_assert(!std::is_move_assignable<P>::value, "");
74     }
75     {
76         // The move decays to the copy constructor
77         CountAssign::reset();
78         using P = std::pair<CountAssign, CopyAssignable>;
79         static_assert(std::is_move_assignable<P>::value, "");
80         P p;
81         P p2;
82         p = std::move(p2);
83         assert(CountAssign::moved == 0);
84         assert(CountAssign::copied == 1);
85     }
86     {
87         CountAssign::reset();
88         using P = std::pair<CountAssign, MoveAssignable>;
89         static_assert(std::is_move_assignable<P>::value, "");
90         P p;
91         P p2;
92         p = std::move(p2);
93         assert(CountAssign::moved == 1);
94         assert(CountAssign::copied == 0);
95     }
96 }
97