1 //
2 // Tests for
3 //  safe_allocation(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-construct from a non-null allocation (with different syntaxes)
20 	{
21 		{
22 			tracked_safe_allocation<T> from(10, libkern::allocate_memory);
23 			tracking_allocator::reset();
24 
25 			T* memory = from.data();
26 
27 			{
28 				tracked_safe_allocation<T> to(std::move(from));
29 				CHECK(!tracking_allocator::did_allocate);
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_deallocate);
36 			tracking_allocator::reset();
37 		}
38 		CHECK(!tracking_allocator::did_deallocate);
39 	}
40 	{
41 		{
42 			tracked_safe_allocation<T> from(10, libkern::allocate_memory);
43 			tracking_allocator::reset();
44 
45 			T* memory = from.data();
46 
47 			{
48 				tracked_safe_allocation<T> to{std::move(from)};
49 				CHECK(!tracking_allocator::did_allocate);
50 				CHECK(to.data() == memory);
51 				CHECK(to.size() == 10);
52 				CHECK(from.data() == nullptr);
53 				CHECK(from.size() == 0);
54 			}
55 			CHECK(tracking_allocator::did_deallocate);
56 			tracking_allocator::reset();
57 		}
58 		CHECK(!tracking_allocator::did_deallocate);
59 	}
60 	{
61 		{
62 			tracked_safe_allocation<T> from(10, libkern::allocate_memory);
63 			tracking_allocator::reset();
64 
65 			T* memory = from.data();
66 
67 			{
68 				tracked_safe_allocation<T> to = std::move(from);
69 				CHECK(!tracking_allocator::did_allocate);
70 				CHECK(to.data() == memory);
71 				CHECK(to.size() == 10);
72 				CHECK(from.data() == nullptr);
73 				CHECK(from.size() == 0);
74 			}
75 			CHECK(tracking_allocator::did_deallocate);
76 			tracking_allocator::reset();
77 		}
78 		CHECK(!tracking_allocator::did_deallocate);
79 	}
80 
81 	// Move-construct from a null allocation
82 	{
83 		{
84 			tracked_safe_allocation<T> from = nullptr;
85 			tracking_allocator::reset();
86 
87 			{
88 				tracked_safe_allocation<T> to(std::move(from));
89 				CHECK(!tracking_allocator::did_allocate);
90 				CHECK(to.data() == nullptr);
91 				CHECK(to.size() == 0);
92 				CHECK(from.data() == nullptr);
93 				CHECK(from.size() == 0);
94 			}
95 			CHECK(!tracking_allocator::did_deallocate);
96 			tracking_allocator::reset();
97 		}
98 		CHECK(!tracking_allocator::did_deallocate);
99 	}
100 }
101 
102 T_DECL(ctor_move, "safe_allocation.ctor.move", T_META_TAG_VM_PREFERRED) {
103 	tests<T>();
104 	tests<T const>();
105 }
106