1 //
2 // Tests for
3 //  void swap(intrusive_shared_ptr& a, intrusive_shared_ptr& b);
4 //
5 
6 #include <libkern/c++/intrusive_shared_ptr.h>
7 #include <darwintest.h>
8 #include "test_policy.h"
9 
10 struct T { int i; };
11 
12 template <typename T>
13 static void
14 tests()
15 {
16 	T obj1{1};
17 	T obj2{2};
18 
19 	// Swap non-null with non-null
20 	{
21 		tracked_shared_ptr<T> a(&obj1, libkern::retain);
22 		tracked_shared_ptr<T> b(&obj2, libkern::retain);
23 		T* a_raw = a.get();
24 		T* b_raw = b.get();
25 		tracking_policy::reset();
26 
27 		swap(a, b); // ADL call
28 
29 		CHECK(tracking_policy::retains == 0);
30 		CHECK(tracking_policy::releases == 0);
31 		CHECK(a.get() == b_raw);
32 		CHECK(b.get() == a_raw);
33 	}
34 
35 	// Swap non-null with null
36 	{
37 		tracked_shared_ptr<T> a(&obj1, libkern::retain);
38 		tracked_shared_ptr<T> b = nullptr;
39 		T* a_raw = a.get();
40 		tracking_policy::reset();
41 
42 		swap(a, b); // ADL call
43 
44 		CHECK(tracking_policy::retains == 0);
45 		CHECK(tracking_policy::releases == 0);
46 		CHECK(a.get() == nullptr);
47 		CHECK(b.get() == a_raw);
48 	}
49 
50 	// Swap null with non-null
51 	{
52 		tracked_shared_ptr<T> a = nullptr;
53 		tracked_shared_ptr<T> b(&obj2, libkern::retain);
54 		T* b_raw = b.get();
55 		tracking_policy::reset();
56 
57 		swap(a, b); // ADL call
58 
59 		CHECK(tracking_policy::retains == 0);
60 		CHECK(tracking_policy::releases == 0);
61 		CHECK(a.get() == b_raw);
62 		CHECK(b.get() == nullptr);
63 	}
64 
65 	// Swap null with null
66 	{
67 		tracked_shared_ptr<T> a = nullptr;
68 		tracked_shared_ptr<T> b = nullptr;
69 		tracking_policy::reset();
70 
71 		swap(a, b); // ADL call
72 
73 		CHECK(tracking_policy::retains == 0);
74 		CHECK(tracking_policy::releases == 0);
75 		CHECK(a.get() == nullptr);
76 		CHECK(b.get() == nullptr);
77 	}
78 
79 	// Swap with self
80 	{
81 		tracked_shared_ptr<T> a(&obj1, libkern::retain);
82 		T* a_raw = a.get();
83 		tracking_policy::reset();
84 
85 		swap(a, a); // ADL call
86 
87 		CHECK(tracking_policy::retains == 0);
88 		CHECK(tracking_policy::releases == 0);
89 		CHECK(a.get() == a_raw);
90 	}
91 }
92 
93 T_DECL(swap, "intrusive_shared_ptr.swap") {
94 	tests<T>();
95 	tests<T const>();
96 }
97