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;
AA25*30dadaa2SIgor Zhukov TEST_CONSTEXPR_CXX23 A() : state_(0) {
26*30dadaa2SIgor Zhukov if (!TEST_IS_CONSTANT_EVALUATED)
27*30dadaa2SIgor Zhukov ++count;
28*30dadaa2SIgor Zhukov }
AA29*30dadaa2SIgor Zhukov TEST_CONSTEXPR_CXX23 explicit A(int i) : state_(i) {
30*30dadaa2SIgor Zhukov if (!TEST_IS_CONSTANT_EVALUATED)
31*30dadaa2SIgor Zhukov ++count;
32*30dadaa2SIgor Zhukov }
AA33*30dadaa2SIgor Zhukov TEST_CONSTEXPR_CXX23 A(const A& a) : state_(a.state_) {
34*30dadaa2SIgor Zhukov if (!TEST_IS_CONSTANT_EVALUATED)
35*30dadaa2SIgor Zhukov ++count;
36*30dadaa2SIgor Zhukov }
operator =A37*30dadaa2SIgor Zhukov TEST_CONSTEXPR_CXX23 A& operator=(const A& a) {
38*30dadaa2SIgor Zhukov state_ = a.state_;
39*30dadaa2SIgor Zhukov return *this;
40*30dadaa2SIgor Zhukov }
~AA41*30dadaa2SIgor Zhukov TEST_CONSTEXPR_CXX23 ~A() {
42*30dadaa2SIgor Zhukov if (!TEST_IS_CONSTANT_EVALUATED)
43*30dadaa2SIgor Zhukov --count;
44*30dadaa2SIgor Zhukov }
452561885fSEric Fiselier
operator ==(const A & x,const A & y)46*30dadaa2SIgor Zhukov friend TEST_CONSTEXPR_CXX23 bool operator==(const A& x, const A& y) { return x.state_ == y.state_; }
472561885fSEric Fiselier };
482561885fSEric Fiselier
492561885fSEric Fiselier int A::count = 0;
502561885fSEric Fiselier
512561885fSEric Fiselier template <class T>
522561885fSEric Fiselier struct NonSwappableDeleter {
NonSwappableDeleterNonSwappableDeleter53*30dadaa2SIgor Zhukov TEST_CONSTEXPR_CXX23 explicit NonSwappableDeleter(int) {}
operator =NonSwappableDeleter54*30dadaa2SIgor Zhukov TEST_CONSTEXPR_CXX23 NonSwappableDeleter& operator=(NonSwappableDeleter const&) { return *this; }
operator ()NonSwappableDeleter55*30dadaa2SIgor Zhukov TEST_CONSTEXPR_CXX23 void operator()(T*) const {}
56*30dadaa2SIgor Zhukov
572561885fSEric Fiselier private:
582561885fSEric Fiselier NonSwappableDeleter(NonSwappableDeleter const&);
592561885fSEric Fiselier
602561885fSEric Fiselier };
612561885fSEric Fiselier
test()62*30dadaa2SIgor Zhukov TEST_CONSTEXPR_CXX23 bool test() {
632561885fSEric Fiselier {
642561885fSEric Fiselier A* p1 = new A(1);
652561885fSEric Fiselier std::unique_ptr<A, Deleter<A> > s1(p1, Deleter<A>(1));
662561885fSEric Fiselier A* p2 = new A(2);
672561885fSEric Fiselier std::unique_ptr<A, Deleter<A> > s2(p2, Deleter<A>(2));
682561885fSEric Fiselier assert(s1.get() == p1);
692561885fSEric Fiselier assert(*s1 == A(1));
702561885fSEric Fiselier assert(s1.get_deleter().state() == 1);
712561885fSEric Fiselier assert(s2.get() == p2);
722561885fSEric Fiselier assert(*s2 == A(2));
732561885fSEric Fiselier assert(s2.get_deleter().state() == 2);
742561885fSEric Fiselier swap(s1, s2);
752561885fSEric Fiselier assert(s1.get() == p2);
762561885fSEric Fiselier assert(*s1 == A(2));
772561885fSEric Fiselier assert(s1.get_deleter().state() == 2);
782561885fSEric Fiselier assert(s2.get() == p1);
792561885fSEric Fiselier assert(*s2 == A(1));
802561885fSEric Fiselier assert(s2.get_deleter().state() == 1);
81*30dadaa2SIgor Zhukov if (!TEST_IS_CONSTANT_EVALUATED)
822561885fSEric Fiselier assert(A::count == 2);
832561885fSEric Fiselier }
84*30dadaa2SIgor Zhukov if (!TEST_IS_CONSTANT_EVALUATED)
852561885fSEric Fiselier assert(A::count == 0);
862561885fSEric Fiselier {
872561885fSEric Fiselier A* p1 = new A[3];
882561885fSEric Fiselier std::unique_ptr<A[], Deleter<A[]> > s1(p1, Deleter<A[]>(1));
892561885fSEric Fiselier A* p2 = new A[3];
902561885fSEric Fiselier std::unique_ptr<A[], Deleter<A[]> > s2(p2, Deleter<A[]>(2));
912561885fSEric Fiselier assert(s1.get() == p1);
922561885fSEric Fiselier assert(s1.get_deleter().state() == 1);
932561885fSEric Fiselier assert(s2.get() == p2);
942561885fSEric Fiselier assert(s2.get_deleter().state() == 2);
952561885fSEric Fiselier swap(s1, s2);
962561885fSEric Fiselier assert(s1.get() == p2);
972561885fSEric Fiselier assert(s1.get_deleter().state() == 2);
982561885fSEric Fiselier assert(s2.get() == p1);
992561885fSEric Fiselier assert(s2.get_deleter().state() == 1);
100*30dadaa2SIgor Zhukov if (!TEST_IS_CONSTANT_EVALUATED)
1012561885fSEric Fiselier assert(A::count == 6);
1022561885fSEric Fiselier }
103*30dadaa2SIgor Zhukov if (!TEST_IS_CONSTANT_EVALUATED)
1042561885fSEric Fiselier assert(A::count == 0);
1052561885fSEric Fiselier #if TEST_STD_VER >= 11
1062561885fSEric Fiselier {
1072561885fSEric Fiselier // test that unique_ptr's specialized swap is disabled when the deleter
1082561885fSEric Fiselier // is non-swappable. Instead we should pick up the generic swap(T, T)
1092561885fSEric Fiselier // and perform 3 move constructions.
1102561885fSEric Fiselier typedef NonSwappableDeleter<int> D;
1112561885fSEric Fiselier D d(42);
1122561885fSEric Fiselier int x = 42;
1132561885fSEric Fiselier int y = 43;
1142561885fSEric Fiselier std::unique_ptr<int, D&> p(&x, d);
1152561885fSEric Fiselier std::unique_ptr<int, D&> p2(&y, d);
1162561885fSEric Fiselier std::swap(p, p2);
1172561885fSEric Fiselier }
1182561885fSEric Fiselier #endif
1192df59c50SJF Bastien
120*30dadaa2SIgor Zhukov return true;
121*30dadaa2SIgor Zhukov }
122*30dadaa2SIgor Zhukov
main(int,char **)123*30dadaa2SIgor Zhukov int main(int, char**) {
124*30dadaa2SIgor Zhukov test();
125*30dadaa2SIgor Zhukov #if TEST_STD_VER >= 23
126*30dadaa2SIgor Zhukov static_assert(test());
127*30dadaa2SIgor Zhukov #endif
128*30dadaa2SIgor Zhukov
1292df59c50SJF Bastien return 0;
1302561885fSEric Fiselier }
131