Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2025 Project CHIP Authors
4 : *
5 : * Licensed under the Apache License, Version 2.0 (the "License");
6 : * you may not use this file except in compliance with the License.
7 : * You may obtain a copy of the License at
8 : *
9 : * http://www.apache.org/licenses/LICENSE-2.0
10 : *
11 : * Unless required by applicable law or agreed to in writing, software
12 : * distributed under the License is distributed on an "AS IS" BASIS,
13 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 : * See the License for the specific language governing permissions and
15 : * limitations under the License.
16 : */
17 :
18 : #pragma once
19 :
20 : #include "ReferenceCountedHandle.h"
21 : #include <lib/support/CodeUtils.h>
22 :
23 : namespace chip {
24 :
25 : /** ReferenceCountedPtr acts like a shared_ptr to an object derived from ReferenceCounted. */
26 : template <typename T>
27 : class ReferenceCountedPtr
28 : {
29 : public:
30 138465 : ReferenceCountedPtr() : mRefCounted(nullptr) {}
31 2154 : ReferenceCountedPtr(T * releasable) : mRefCounted(releasable ? releasable->Ref() : nullptr) {}
32 277 : ReferenceCountedPtr(const ReferenceCountedPtr & src) : ReferenceCountedPtr(src.mRefCounted) {}
33 : ReferenceCountedPtr(const ReferenceCountedHandle<T> & src) : ReferenceCountedPtr(&src.Get()) {}
34 109 : ReferenceCountedPtr(ReferenceCountedPtr && src) noexcept : mRefCounted(src.mRefCounted) { src.mRefCounted = nullptr; }
35 :
36 1358 : ReferenceCountedPtr & operator=(const ReferenceCountedPtr & src)
37 : {
38 1358 : Set(src.mRefCounted);
39 1358 : return *this;
40 : }
41 335 : ReferenceCountedPtr & operator=(ReferenceCountedPtr && src) noexcept
42 : {
43 335 : if (this != &src)
44 : {
45 335 : Release();
46 335 : mRefCounted = src.mRefCounted;
47 335 : src.mRefCounted = nullptr;
48 : }
49 335 : return *this;
50 : }
51 :
52 140728 : ~ReferenceCountedPtr() { Release(); }
53 :
54 1308 : inline T * operator->() const { return mRefCounted; }
55 128 : inline T & operator*() const { return *mRefCounted; }
56 :
57 187 : inline operator bool() { return mRefCounted != nullptr; }
58 2660 : inline bool IsNull() const { return mRefCounted == nullptr; }
59 :
60 68 : inline bool operator==(const ReferenceCountedPtr & other) const { return this->mRefCounted == other.mRefCounted; }
61 2 : inline bool operator!=(const ReferenceCountedPtr & other) const { return this->mRefCounted != other.mRefCounted; }
62 : inline bool operator==(const ReferenceCountedHandle<T> & other) const { return this->mRefCounted == &other.Get(); }
63 : inline bool operator!=(const ReferenceCountedHandle<T> & other) const { return this->mRefCounted != &other.Get(); }
64 : inline bool operator==(const T & other) const { return this->mRefCounted == &other; }
65 : inline bool operator!=(const T & other) const { return this->mRefCounted != &other; }
66 :
67 141656 : void Release()
68 : {
69 141656 : VerifyOrReturn(mRefCounted != nullptr);
70 883 : mRefCounted->Unref();
71 883 : mRefCounted = nullptr;
72 : }
73 :
74 1358 : void Set(T * releasable)
75 : {
76 1358 : if (mRefCounted != releasable)
77 : {
78 115 : Release();
79 115 : mRefCounted = releasable ? releasable->Ref() : nullptr;
80 : }
81 1358 : }
82 :
83 37 : bool IsReferencing(const T * p) const { return mRefCounted == p; }
84 :
85 : protected:
86 : T * mRefCounted = nullptr;
87 : };
88 :
89 : } // namespace chip
|