1 //
2 // Tests for
3 //      safe_allocation& operator=(safe_allocation&& other);
4 //
5 
6 #include <libkern/c++/safe_allocation.h>
7 #include <darwintest.h>
8 #include "test_utils.h"
9 #include <utility>
10 
11 struct T {
12 	int i;
13 };
14 
15 template <typename T>
16 static void
tests()17 tests()
18 {
19 	// Move-assign non-null to non-null
20 	{
21 		{
22 			tracked_safe_allocation<T> from(10, libkern::allocate_memory);
23 			T* memory = from.data();
24 			{
25 				tracked_safe_allocation<T> to(20, libkern::allocate_memory);
26 				tracking_allocator::reset();
27 
28 				tracked_safe_allocation<T>& ref = (to = std::move(from));
29 				CHECK(&ref == &to);
30 				CHECK(to.data() == memory);
31 				CHECK(to.size() == 10);
32 				CHECK(from.data() == nullptr);
33 				CHECK(from.size() == 0);
34 
35 				CHECK(!tracking_allocator::did_allocate);
36 				CHECK(tracking_allocator::deallocated_size == 20 * sizeof(T));
37 				tracking_allocator::reset();
38 			}
39 			CHECK(tracking_allocator::deallocated_size == 10 * sizeof(T));
40 			tracking_allocator::reset();
41 		}
42 		CHECK(!tracking_allocator::did_deallocate);
43 	}
44 
45 	// Move-assign null to non-null
46 	{
47 		{
48 			tracked_safe_allocation<T> from = nullptr;
49 			{
50 				tracked_safe_allocation<T> to(20, libkern::allocate_memory);
51 				tracking_allocator::reset();
52 
53 				tracked_safe_allocation<T>& ref = (to = std::move(from));
54 				CHECK(&ref == &to);
55 				CHECK(to.data() == nullptr);
56 				CHECK(to.size() == 0);
57 				CHECK(from.data() == nullptr);
58 				CHECK(from.size() == 0);
59 
60 				CHECK(!tracking_allocator::did_allocate);
61 				CHECK(tracking_allocator::deallocated_size == 20 * sizeof(T));
62 				tracking_allocator::reset();
63 			}
64 			CHECK(!tracking_allocator::did_deallocate);
65 			tracking_allocator::reset();
66 		}
67 		CHECK(!tracking_allocator::did_deallocate);
68 	}
69 
70 	// Move-assign non-null to null
71 	{
72 		{
73 			tracked_safe_allocation<T> from(10, libkern::allocate_memory);
74 			T* memory = from.data();
75 			{
76 				tracked_safe_allocation<T> to = nullptr;
77 				tracking_allocator::reset();
78 
79 				tracked_safe_allocation<T>& ref = (to = std::move(from));
80 				CHECK(&ref == &to);
81 				CHECK(to.data() == memory);
82 				CHECK(to.size() == 10);
83 				CHECK(from.data() == nullptr);
84 				CHECK(from.size() == 0);
85 
86 				CHECK(!tracking_allocator::did_allocate);
87 				CHECK(!tracking_allocator::did_deallocate);
88 				tracking_allocator::reset();
89 			}
90 			CHECK(tracking_allocator::deallocated_size == 10 * sizeof(T));
91 			tracking_allocator::reset();
92 		}
93 		CHECK(!tracking_allocator::did_deallocate);
94 	}
95 
96 	// Move-assign null to null
97 	{
98 		{
99 			tracked_safe_allocation<T> from = nullptr;
100 			{
101 				tracked_safe_allocation<T> to = nullptr;
102 				tracking_allocator::reset();
103 
104 				tracked_safe_allocation<T>& ref = (to = std::move(from));
105 				CHECK(&ref == &to);
106 				CHECK(to.data() == nullptr);
107 				CHECK(to.size() == 0);
108 				CHECK(from.data() == nullptr);
109 				CHECK(from.size() == 0);
110 
111 				CHECK(!tracking_allocator::did_allocate);
112 				CHECK(!tracking_allocator::did_deallocate);
113 				tracking_allocator::reset();
114 			}
115 			CHECK(!tracking_allocator::did_deallocate);
116 			tracking_allocator::reset();
117 		}
118 		CHECK(!tracking_allocator::did_deallocate);
119 	}
120 
121 	// Move-assign to self
122 	{
123 		{
124 			tracked_safe_allocation<T> obj(10, libkern::allocate_memory);
125 			T* memory = obj.data();
126 
127 			tracking_allocator::reset();
128 			tracked_safe_allocation<T>& ref = (obj = std::move(obj));
129 			CHECK(&ref == &obj);
130 			CHECK(obj.data() == memory);
131 			CHECK(obj.size() == 10);
132 			CHECK(!tracking_allocator::did_allocate);
133 			CHECK(!tracking_allocator::did_deallocate);
134 			tracking_allocator::reset();
135 		}
136 		CHECK(tracking_allocator::deallocated_size == 10 * sizeof(T));
137 	}
138 }
139 
140 T_DECL(assign_move, "safe_allocation.assign.move", T_META_TAG_VM_PREFERRED) {
141 	tests<T>();
142 	tests<T const>();
143 }
144