12561885fSEric Fiselier //===----------------------------------------------------------------------===//
22561885fSEric Fiselier //
357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
62561885fSEric Fiselier //
72561885fSEric Fiselier //===----------------------------------------------------------------------===//
82561885fSEric Fiselier 
92561885fSEric Fiselier // <memory>
102561885fSEric Fiselier 
112561885fSEric Fiselier // unique_ptr
122561885fSEric Fiselier 
132561885fSEric Fiselier // Test swap
142561885fSEric Fiselier 
152561885fSEric Fiselier #include <memory>
162561885fSEric Fiselier #include <cassert>
172561885fSEric Fiselier 
182561885fSEric Fiselier #include "test_macros.h"
192561885fSEric Fiselier #include "deleter_types.h"
202561885fSEric Fiselier 
212561885fSEric Fiselier struct A
222561885fSEric Fiselier {
232561885fSEric Fiselier     int state_;
242561885fSEric Fiselier     static int count;
AA252561885fSEric Fiselier     A() : state_(0) {++count;}
AA262561885fSEric Fiselier     explicit A(int i) : state_(i) {++count;}
AA272561885fSEric Fiselier     A(const A& a) : state_(a.state_) {++count;}
operator =A282561885fSEric Fiselier     A& operator=(const A& a) {state_ = a.state_; return *this;}
~AA292561885fSEric Fiselier     ~A() {--count;}
302561885fSEric Fiselier 
operator ==(const A & x,const A & y)312561885fSEric Fiselier     friend bool operator==(const A& x, const A& y)
322561885fSEric Fiselier         {return x.state_ == y.state_;}
332561885fSEric Fiselier };
342561885fSEric Fiselier 
352561885fSEric Fiselier int A::count = 0;
362561885fSEric Fiselier 
372561885fSEric Fiselier template <class T>
382561885fSEric Fiselier struct NonSwappableDeleter {
NonSwappableDeleterNonSwappableDeleter392561885fSEric Fiselier   explicit NonSwappableDeleter(int) {}
operator =NonSwappableDeleter402561885fSEric Fiselier   NonSwappableDeleter& operator=(NonSwappableDeleter const&) { return *this; }
operator ()NonSwappableDeleter412561885fSEric Fiselier   void operator()(T*) const {}
422561885fSEric Fiselier private:
432561885fSEric Fiselier   NonSwappableDeleter(NonSwappableDeleter const&);
442561885fSEric Fiselier 
452561885fSEric Fiselier };
462561885fSEric Fiselier 
main(int,char **)47*2df59c50SJF Bastien int main(int, char**)
482561885fSEric Fiselier {
492561885fSEric Fiselier     {
502561885fSEric Fiselier     A* p1 = new A(1);
512561885fSEric Fiselier     std::unique_ptr<A, Deleter<A> > s1(p1, Deleter<A>(1));
522561885fSEric Fiselier     A* p2 = new A(2);
532561885fSEric Fiselier     std::unique_ptr<A, Deleter<A> > s2(p2, Deleter<A>(2));
542561885fSEric Fiselier     assert(s1.get() == p1);
552561885fSEric Fiselier     assert(*s1 == A(1));
562561885fSEric Fiselier     assert(s1.get_deleter().state() == 1);
572561885fSEric Fiselier     assert(s2.get() == p2);
582561885fSEric Fiselier     assert(*s2 == A(2));
592561885fSEric Fiselier     assert(s2.get_deleter().state() == 2);
602561885fSEric Fiselier     swap(s1, s2);
612561885fSEric Fiselier     assert(s1.get() == p2);
622561885fSEric Fiselier     assert(*s1 == A(2));
632561885fSEric Fiselier     assert(s1.get_deleter().state() == 2);
642561885fSEric Fiselier     assert(s2.get() == p1);
652561885fSEric Fiselier     assert(*s2 == A(1));
662561885fSEric Fiselier     assert(s2.get_deleter().state() == 1);
672561885fSEric Fiselier     assert(A::count == 2);
682561885fSEric Fiselier     }
692561885fSEric Fiselier     assert(A::count == 0);
702561885fSEric Fiselier     {
712561885fSEric Fiselier     A* p1 = new A[3];
722561885fSEric Fiselier     std::unique_ptr<A[], Deleter<A[]> > s1(p1, Deleter<A[]>(1));
732561885fSEric Fiselier     A* p2 = new A[3];
742561885fSEric Fiselier     std::unique_ptr<A[], Deleter<A[]> > s2(p2, Deleter<A[]>(2));
752561885fSEric Fiselier     assert(s1.get() == p1);
762561885fSEric Fiselier     assert(s1.get_deleter().state() == 1);
772561885fSEric Fiselier     assert(s2.get() == p2);
782561885fSEric Fiselier     assert(s2.get_deleter().state() == 2);
792561885fSEric Fiselier     swap(s1, s2);
802561885fSEric Fiselier     assert(s1.get() == p2);
812561885fSEric Fiselier     assert(s1.get_deleter().state() == 2);
822561885fSEric Fiselier     assert(s2.get() == p1);
832561885fSEric Fiselier     assert(s2.get_deleter().state() == 1);
842561885fSEric Fiselier     assert(A::count == 6);
852561885fSEric Fiselier     }
862561885fSEric Fiselier     assert(A::count == 0);
872561885fSEric Fiselier #if TEST_STD_VER >= 11
882561885fSEric Fiselier     {
892561885fSEric Fiselier         // test that unique_ptr's specialized swap is disabled when the deleter
902561885fSEric Fiselier         // is non-swappable. Instead we should pick up the generic swap(T, T)
912561885fSEric Fiselier         // and perform 3 move constructions.
922561885fSEric Fiselier         typedef NonSwappableDeleter<int> D;
932561885fSEric Fiselier         D  d(42);
942561885fSEric Fiselier         int x = 42;
952561885fSEric Fiselier         int y = 43;
962561885fSEric Fiselier         std::unique_ptr<int, D&> p(&x, d);
972561885fSEric Fiselier         std::unique_ptr<int, D&> p2(&y, d);
982561885fSEric Fiselier         std::swap(p, p2);
992561885fSEric Fiselier     }
1002561885fSEric Fiselier #endif
101*2df59c50SJF Bastien 
102*2df59c50SJF Bastien   return 0;
1032561885fSEric Fiselier }
104