• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://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,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef API_BASE_CONTAINERS_REFCNT_PTR_H
17 #define API_BASE_CONTAINERS_REFCNT_PTR_H
18 
19 #include <cstddef>
20 
21 #include <base/containers/type_traits.h>
22 #include <base/namespace.h>
23 
BASE_BEGIN_NAMESPACE()24 BASE_BEGIN_NAMESPACE()
25 template<class T>
26 class refcnt_ptr {
27 public:
28     using pointer = BASE_NS::remove_reference_t<T>*;
29     using element_type = T;
30 
31     constexpr refcnt_ptr() noexcept {}
32 
33     constexpr refcnt_ptr(nullptr_t) noexcept {}
34 
35     explicit constexpr refcnt_ptr(pointer ptr) noexcept : ptr_(ptr)
36     {
37         if (ptr) {
38             ptr->Ref();
39         }
40     }
41 
42     refcnt_ptr(const refcnt_ptr& ptr) : refcnt_ptr(ptr.get()) {}
43 
44     template<class U>
45     refcnt_ptr(const refcnt_ptr<U>& ptr) : refcnt_ptr(static_cast<T*>(ptr.get()))
46     {}
47 
48     refcnt_ptr(refcnt_ptr&& ptr) noexcept : ptr_(exchange(ptr.ptr_, nullptr)) {}
49 
50     template<class U>
51     refcnt_ptr(refcnt_ptr<U>&& ptr) noexcept : ptr_(static_cast<T*>(ptr.release()))
52     {}
53 
54     ~refcnt_ptr()
55     {
56         if (ptr_) {
57             ptr_->Unref();
58         }
59     }
60 
61     pointer get() const noexcept
62     {
63         return ptr_;
64     }
65 
66     pointer release() noexcept
67     {
68         pointer res = ptr_;
69         ptr_ = nullptr;
70         return res;
71     }
72 
73     void reset(pointer ptr = pointer()) noexcept
74     {
75         if (ptr_ != ptr) {
76             pointer old_ptr = ptr_;
77             ptr_ = ptr;
78             if (ptr_) {
79                 ptr_->Ref();
80             }
81             if (old_ptr) {
82                 old_ptr->Unref();
83             }
84         }
85     }
86 
87     refcnt_ptr& operator=(nullptr_t) noexcept
88     {
89         reset();
90         return *this;
91     }
92 
93     refcnt_ptr& operator=(const refcnt_ptr& r) noexcept
94     {
95         reset(r.get());
96         return *this;
97     }
98 
99     template<class U>
100     refcnt_ptr& operator=(const refcnt_ptr<U>& r) noexcept
101     {
102         reset(r.get());
103         return *this;
104     }
105 
106     refcnt_ptr& operator=(refcnt_ptr&& r) noexcept
107     {
108         reset();
109         ptr_ = exchange(r.ptr_, nullptr);
110         return *this;
111     }
112 
113     template<class U>
114     refcnt_ptr& operator=(refcnt_ptr<U>&& r) noexcept
115     {
116         reset();
117         ptr_ = r.release();
118         return *this;
119     }
120 
121     void swap(refcnt_ptr& other) noexcept
122     {
123         ptr_ = exchange(other.ptr_, ptr_);
124     }
125 
126     explicit operator bool() const noexcept
127     {
128         return (ptr_ != nullptr);
129     }
130 
131     bool operator==(const refcnt_ptr& other) const noexcept
132     {
133         return (ptr_ == other.ptr_);
134     }
135 
136     bool operator!=(const refcnt_ptr& other) const noexcept
137     {
138         return (ptr_ != other.ptr_);
139     }
140 
141     pointer operator->() const noexcept
142     {
143         return ptr_;
144     }
145 
146     typename BASE_NS::add_lvalue_reference<T>::type operator*() const
147     {
148         return *ptr_;
149     }
150 
151     bool operator!=(nullptr_t) const noexcept
152     {
153         return ptr_ != nullptr;
154     }
155 
156     bool operator==(nullptr_t) const noexcept
157     {
158         return ptr_ == nullptr;
159     }
160 
161 protected:
162     pointer ptr_ { nullptr };
163 };
164 BASE_END_NAMESPACE()
165 
166 #endif // API_BASE_CONTAINERS_REFCNT_PTR_H
167