Home | History | Annotate | Download | only in unique.ptr.asgn
      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 // <memory>
     13 
     14 // unique_ptr
     15 
     16 // Test unique_ptr converting move assignment
     17 
     18 #include <memory>
     19 #include <utility>
     20 #include <cassert>
     21 
     22 #include "unique_ptr_test_helper.h"
     23 
     24 template <class APtr, class BPtr>
     25 void testAssign(APtr& aptr, BPtr& bptr) {
     26   A* p = bptr.get();
     27   assert(A::count == 2);
     28   aptr = std::move(bptr);
     29   assert(aptr.get() == p);
     30   assert(bptr.get() == 0);
     31   assert(A::count == 1);
     32   assert(B::count == 1);
     33 }
     34 
     35 template <class LHS, class RHS>
     36 void checkDeleter(LHS& lhs, RHS& rhs, int LHSState, int RHSState) {
     37   assert(lhs.get_deleter().state() == LHSState);
     38   assert(rhs.get_deleter().state() == RHSState);
     39 }
     40 
     41 template <class T>
     42 struct NCConvertingDeleter {
     43   NCConvertingDeleter() = default;
     44   NCConvertingDeleter(NCConvertingDeleter const&) = delete;
     45   NCConvertingDeleter(NCConvertingDeleter&&) = default;
     46 
     47   template <class U>
     48   NCConvertingDeleter(NCConvertingDeleter<U>&&) {}
     49 
     50   void operator()(T*) const {}
     51 };
     52 
     53 template <class T>
     54 struct NCConvertingDeleter<T[]> {
     55   NCConvertingDeleter() = default;
     56   NCConvertingDeleter(NCConvertingDeleter const&) = delete;
     57   NCConvertingDeleter(NCConvertingDeleter&&) = default;
     58 
     59   template <class U>
     60   NCConvertingDeleter(NCConvertingDeleter<U>&&) {}
     61 
     62   void operator()(T*) const {}
     63 };
     64 
     65 struct GenericDeleter {
     66   void operator()(void*) const;
     67 };
     68 
     69 struct NCGenericDeleter {
     70   NCGenericDeleter() = default;
     71   NCGenericDeleter(NCGenericDeleter const&) = delete;
     72   NCGenericDeleter(NCGenericDeleter&&) = default;
     73 
     74   void operator()(void*) const {}
     75 };
     76 
     77 void test_sfinae() {
     78   using DA = NCConvertingDeleter<A[]>;        // non-copyable deleters
     79   using DAC = NCConvertingDeleter<const A[]>; // non-copyable deleters
     80 
     81   using UA = std::unique_ptr<A[]>;
     82   using UAC = std::unique_ptr<const A[]>;
     83   using UAD = std::unique_ptr<A[], DA>;
     84   using UACD = std::unique_ptr<const A[], DAC>;
     85 
     86   { // cannot move from an lvalue
     87     static_assert(std::is_assignable<UAC, UA&&>::value, "");
     88     static_assert(!std::is_assignable<UAC, UA&>::value, "");
     89     static_assert(!std::is_assignable<UAC, const UA&>::value, "");
     90   }
     91   { // cannot move if the deleter-types cannot convert
     92     static_assert(std::is_assignable<UACD, UAD&&>::value, "");
     93     static_assert(!std::is_assignable<UACD, UAC&&>::value, "");
     94     static_assert(!std::is_assignable<UAC, UACD&&>::value, "");
     95   }
     96   { // cannot move-convert with reference deleters of different types
     97     using UA1 = std::unique_ptr<A[], DA&>;
     98     using UA2 = std::unique_ptr<A[], DAC&>;
     99     static_assert(!std::is_assignable<UA1, UA2&&>::value, "");
    100   }
    101   { // cannot move-convert with reference deleters of different types
    102     using UA1 = std::unique_ptr<A[], const DA&>;
    103     using UA2 = std::unique_ptr<A[], const DAC&>;
    104     static_assert(!std::is_assignable<UA1, UA2&&>::value, "");
    105   }
    106   { // cannot move-convert from unique_ptr<Single>
    107     using UA1 = std::unique_ptr<A[]>;
    108     using UA2 = std::unique_ptr<A>;
    109     static_assert(!std::is_assignable<UA1, UA2&&>::value, "");
    110   }
    111   { // cannot move-convert from unique_ptr<Array[]>
    112     using UA1 = std::unique_ptr<A[], NCGenericDeleter>;
    113     using UA2 = std::unique_ptr<A, NCGenericDeleter>;
    114     static_assert(!std::is_assignable<UA1, UA2&&>::value, "");
    115   }
    116 }
    117 
    118 int main() {
    119   test_sfinae();
    120   // FIXME: add tests
    121 }
    122