1 // Copyright 2016 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <stdio.h>
6 #include <type_traits>
7 #include <utility>
8 
9 #include <fbl/alloc_checker.h>
10 #include <fbl/unique_free_ptr.h>
11 #include <unittest/unittest.h>
12 
13 static_assert(std::is_standard_layout<fbl::unique_free_ptr<int>>::value,
14               "fbl::unique_free_ptr<int>'s should have a standard layout");
15 
16 // These tests mostly serve to exercise the unique_free_ptr type and work well with heap checkers as
17 // the side effects of calling libc free() cannot be directly observed.
ufptr_test_move()18 static bool ufptr_test_move() {
19     BEGIN_TEST;
20 
21     // Construct and move into another unique_ptr.
22     {
23         fbl::unique_free_ptr<int> ptr(static_cast<int*>(malloc(sizeof(int))));
24 
25         fbl::unique_free_ptr<int> ptr2 = std::move(ptr);
26         EXPECT_NULL(ptr, "expected ptr to be null");
27     }
28 
29     END_TEST;
30 }
31 
ufptr_test_null_scoped_destruction()32 static bool ufptr_test_null_scoped_destruction() {
33     BEGIN_TEST;
34 
35     // Construct a null unique_ptr and let it fall out of scope - should not call
36     // deleter.
37     {
38         fbl::unique_free_ptr<int> ptr(nullptr);
39     }
40 
41     END_TEST;
42 }
43 
ufptr_test_diff_scope_swap()44 static bool ufptr_test_diff_scope_swap() {
45     BEGIN_TEST;
46 
47     // Construct a pair of unique_ptrs in different scopes, swap them, and verify
48     // that the values change places and that the values are destroyed at the
49     // correct times.
50 
51     {
52         fbl::unique_free_ptr<int> ptr1(static_cast<int*>(malloc(sizeof(int))));
53         *ptr1 = 4;
54         {
55             fbl::unique_free_ptr<int> ptr2(static_cast<int*>(malloc(sizeof(int))));
56             *ptr2 = 7;
57 
58             ptr1.swap(ptr2);
59             EXPECT_EQ(7, *ptr1);
60             EXPECT_EQ(4, *ptr2);
61         }
62     }
63 
64     END_TEST;
65 }
66 
ufptr_test_bool_op()67 static bool ufptr_test_bool_op() {
68     BEGIN_TEST;
69 
70 
71     fbl::unique_free_ptr<int> foo(static_cast<int*>(malloc(sizeof(int))));
72     EXPECT_TRUE(static_cast<bool>(foo));
73 
74     foo.reset();
75     EXPECT_FALSE(static_cast<bool>(foo));
76 
77     END_TEST;
78 }
79 
ufptr_test_comparison()80 static bool ufptr_test_comparison() {
81     BEGIN_TEST;
82 
83     // Test comparison operators.
84     fbl::unique_free_ptr<int> null_unique;
85     fbl::unique_free_ptr<int> lesser_unique(static_cast<int*>(malloc(sizeof(int))));
86     *lesser_unique = 1;
87 
88     fbl::unique_free_ptr<int> greater_unique(static_cast<int*>(malloc(sizeof(int))));
89     *greater_unique = 2;
90 
91     EXPECT_NE(lesser_unique.get(), greater_unique.get());
92     if (lesser_unique.get() > greater_unique.get())
93         lesser_unique.swap(greater_unique);
94 
95     // Comparison against nullptr
96     EXPECT_TRUE(   null_unique == nullptr);
97     EXPECT_TRUE( lesser_unique != nullptr);
98     EXPECT_TRUE(greater_unique != nullptr);
99 
100     EXPECT_TRUE(nullptr ==    null_unique);
101     EXPECT_TRUE(nullptr !=  lesser_unique);
102     EXPECT_TRUE(nullptr != greater_unique);
103 
104     // Comparison against other unique_free_ptr<>s
105     EXPECT_TRUE( lesser_unique  ==  lesser_unique);
106     EXPECT_FALSE( lesser_unique == greater_unique);
107     EXPECT_FALSE(greater_unique ==  lesser_unique);
108     EXPECT_TRUE(greater_unique  == greater_unique);
109 
110     EXPECT_FALSE( lesser_unique !=  lesser_unique);
111     EXPECT_TRUE ( lesser_unique != greater_unique, "");
112     EXPECT_TRUE (greater_unique !=  lesser_unique, "");
113     EXPECT_FALSE(greater_unique != greater_unique);
114 
115     EXPECT_FALSE( lesser_unique <   lesser_unique);
116     EXPECT_TRUE ( lesser_unique <  greater_unique, "");
117     EXPECT_FALSE(greater_unique <   lesser_unique);
118     EXPECT_FALSE(greater_unique <  greater_unique);
119 
120     EXPECT_FALSE( lesser_unique >   lesser_unique);
121     EXPECT_FALSE( lesser_unique >  greater_unique);
122     EXPECT_TRUE (greater_unique >   lesser_unique, "");
123     EXPECT_FALSE(greater_unique >  greater_unique);
124 
125     EXPECT_TRUE ( lesser_unique <=  lesser_unique, "");
126     EXPECT_TRUE ( lesser_unique <= greater_unique, "");
127     EXPECT_FALSE(greater_unique <=  lesser_unique);
128     EXPECT_TRUE (greater_unique <= greater_unique, "");
129 
130     EXPECT_TRUE ( lesser_unique >=  lesser_unique, "");
131     EXPECT_FALSE( lesser_unique >= greater_unique);
132     EXPECT_TRUE (greater_unique >=  lesser_unique, "");
133     EXPECT_TRUE (greater_unique >= greater_unique, "");
134 
135     END_TEST;
136 }
137 
138 BEGIN_TEST_CASE(unique_free_ptr)
139 RUN_NAMED_TEST("Move",                             ufptr_test_move)
140 RUN_NAMED_TEST("nullptr Scoped Destruction",       ufptr_test_null_scoped_destruction)
141 RUN_NAMED_TEST("Different Scope Swapping",         ufptr_test_diff_scope_swap)
142 RUN_NAMED_TEST("operator bool",                    ufptr_test_bool_op)
143 RUN_NAMED_TEST("comparison operators",             ufptr_test_comparison)
144 END_TEST_CASE(unique_free_ptr);
145