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 // 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;
     41   static void reset() { copied = moved = 0; }
     42   CountAssign() = default;
     43   CountAssign& operator=(CountAssign const&) { ++copied; return *this; }
     44   CountAssign& operator=(CountAssign&&) { ++moved; return *this; }
     45 };
     46 int CountAssign::copied = 0;
     47 int CountAssign::moved = 0;
     48 
     49 int main()
     50 {
     51     {
     52         typedef std::pair<std::unique_ptr<int>, short> 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