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_unit_test/framework.h"
23
24 namespace pw {
25 namespace {
26
27 class TestItem : public RefCounted<TestItem>, public Recyclable<TestItem> {
28 public:
29 TestItem() = default;
30
~TestItem()31 virtual ~TestItem() {}
32
33 inline static int32_t recycle_counter = 0;
34
35 private:
36 friend class Recyclable<TestItem>;
pw_recycle()37 void pw_recycle() {
38 recycle_counter++;
39 delete this;
40 }
41 };
42
43 // Class that thas the pw_recyclable method, but does not derive from
44 // Recyclable.
45 class TestItemNonRecyclable : public RefCounted<TestItemNonRecyclable> {
46 public:
47 TestItemNonRecyclable() = default;
48
~TestItemNonRecyclable()49 virtual ~TestItemNonRecyclable() {}
50
51 inline static int32_t recycle_counter = 0;
52
pw_recycle()53 void pw_recycle() { recycle_counter++; }
54 };
55
56 class RecyclableTest : public ::testing::Test {
57 protected:
SetUp()58 void SetUp() override {
59 TestItem::recycle_counter = 0;
60 TestItemNonRecyclable::recycle_counter = 0;
61 }
62 };
63
TEST_F(RecyclableTest,DeletingLastPtrRecyclesTheObject)64 TEST_F(RecyclableTest, DeletingLastPtrRecyclesTheObject) {
65 {
66 IntrusivePtr<TestItem> ptr(new TestItem());
67 EXPECT_EQ(TestItem::recycle_counter, 0);
68 }
69 EXPECT_EQ(TestItem::recycle_counter, 1);
70 }
71
TEST_F(RecyclableTest,ConstRecycle)72 TEST_F(RecyclableTest, ConstRecycle) {
73 {
74 IntrusivePtr<const TestItem> ptr(new TestItem());
75 EXPECT_EQ(TestItem::recycle_counter, 0);
76 }
77 EXPECT_EQ(TestItem::recycle_counter, 1);
78 }
79
TEST_F(RecyclableTest,NonRecyclableWithPwRecycleMethod)80 TEST_F(RecyclableTest, NonRecyclableWithPwRecycleMethod) {
81 {
82 IntrusivePtr<TestItemNonRecyclable> ptr(new TestItemNonRecyclable());
83 EXPECT_EQ(TestItemNonRecyclable::recycle_counter, 0);
84 }
85 EXPECT_EQ(TestItemNonRecyclable::recycle_counter, 0);
86 }
87
88 } // namespace
89 } // namespace pw
90