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()17tests() 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