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