1 // Copyright 2023 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 #include "pw_intrusive_ptr/recyclable.h"
16
17 #include <stdint.h>
18
19 #include <utility>
20
21 #include "pw_intrusive_ptr/intrusive_ptr.h"
22 #include "pw_intrusive_ptr/ref_counted.h"
23 #include "pw_unit_test/framework.h"
24
25 namespace pw {
26 namespace {
27
28 class TestItem : public RefCounted<TestItem>, public Recyclable<TestItem> {
29 public:
30 TestItem() = default;
31
~TestItem()32 virtual ~TestItem() {}
33
34 inline static int32_t recycle_counter = 0;
35
36 private:
37 friend class Recyclable<TestItem>;
pw_recycle()38 void pw_recycle() {
39 recycle_counter++;
40 delete this;
41 }
42 };
43
44 // Class that thas the pw_recyclable method, but does not derive from
45 // Recyclable.
46 class TestItemNonRecyclable : public RefCounted<TestItemNonRecyclable> {
47 public:
48 TestItemNonRecyclable() = default;
49
~TestItemNonRecyclable()50 virtual ~TestItemNonRecyclable() {}
51
52 inline static int32_t recycle_counter = 0;
53
pw_recycle()54 void pw_recycle() { recycle_counter++; }
55 };
56
57 class RecyclableTest : public ::testing::Test {
58 protected:
SetUp()59 void SetUp() override {
60 TestItem::recycle_counter = 0;
61 TestItemNonRecyclable::recycle_counter = 0;
62 }
63 };
64
TEST_F(RecyclableTest,DeletingLastPtrRecyclesTheObject)65 TEST_F(RecyclableTest, DeletingLastPtrRecyclesTheObject) {
66 {
67 IntrusivePtr<TestItem> ptr(new TestItem());
68 EXPECT_EQ(TestItem::recycle_counter, 0);
69 }
70 EXPECT_EQ(TestItem::recycle_counter, 1);
71 }
72
TEST_F(RecyclableTest,ConstRecycle)73 TEST_F(RecyclableTest, ConstRecycle) {
74 {
75 IntrusivePtr<const TestItem> ptr(new TestItem());
76 EXPECT_EQ(TestItem::recycle_counter, 0);
77 }
78 EXPECT_EQ(TestItem::recycle_counter, 1);
79 }
80
TEST_F(RecyclableTest,NonRecyclableWithPwRecycleMethod)81 TEST_F(RecyclableTest, NonRecyclableWithPwRecycleMethod) {
82 {
83 IntrusivePtr<TestItemNonRecyclable> ptr(new TestItemNonRecyclable());
84 EXPECT_EQ(TestItemNonRecyclable::recycle_counter, 0);
85 }
86 EXPECT_EQ(TestItemNonRecyclable::recycle_counter, 0);
87 }
88
89 } // namespace
90 } // namespace pw
91