1 /*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #ifndef CHRE_UTIL_SYSTEM_SHARED_PTR_IMPL_H_
18 #define CHRE_UTIL_SYSTEM_SHARED_PTR_IMPL_H_
19
20 #include "chre/util/system/shared_ptr.h"
21
22 #include "chre/util/container_support.h"
23 #include "chre/util/memory.h"
24 #include "chre/util/system/ref_base.h"
25
26 namespace chre {
27
28 template <typename ObjectType>
SharedPtr()29 SharedPtr<ObjectType>::SharedPtr() {
30 static_assert(std::is_base_of<RefBase<ObjectType>, ObjectType>::value,
31 "Class must inherit from RefBase to use SharedPtr");
32 }
33
34 template <typename ObjectType>
SharedPtr(ObjectType * object)35 SharedPtr<ObjectType>::SharedPtr(ObjectType *object) : mObject(object) {}
36
37 template <typename ObjectType>
SharedPtr(SharedPtr<ObjectType> && other)38 SharedPtr<ObjectType>::SharedPtr(SharedPtr<ObjectType> &&other)
39 : mObject(other.mObject) {
40 other.mObject = nullptr;
41 }
42
43 template <typename ObjectType>
44 template <typename OtherObjectType>
SharedPtr(SharedPtr<OtherObjectType> && other)45 SharedPtr<ObjectType>::SharedPtr(SharedPtr<OtherObjectType> &&other)
46 : mObject(other.mObject) {
47 other.mObject = nullptr;
48 }
49
50 template <typename ObjectType>
SharedPtr(const SharedPtr & other)51 SharedPtr<ObjectType>::SharedPtr(const SharedPtr &other) {
52 reset(other.mObject);
53 }
54
55 template <typename ObjectType>
56 template <typename OtherObjectType>
SharedPtr(const SharedPtr<OtherObjectType> & other)57 SharedPtr<ObjectType>::SharedPtr(const SharedPtr<OtherObjectType> &other) {
58 reset(other.mObject);
59 }
60
61 template <typename ObjectType>
~SharedPtr()62 SharedPtr<ObjectType>::~SharedPtr() {
63 reset();
64 }
65
66 template <typename ObjectType>
isNull()67 bool SharedPtr<ObjectType>::isNull() const {
68 return (mObject == nullptr);
69 }
70
71 template <typename ObjectType>
get()72 ObjectType *SharedPtr<ObjectType>::get() const {
73 return mObject;
74 }
75
76 template <typename ObjectType>
reset(ObjectType * object)77 void SharedPtr<ObjectType>::reset(ObjectType *object) {
78 CHRE_ASSERT(object == nullptr || mObject != object);
79
80 reset();
81 mObject = object;
82 if (mObject != nullptr) {
83 mObject->incRef();
84 }
85 }
86
87 template <typename ObjectType>
reset()88 void SharedPtr<ObjectType>::reset() {
89 if (mObject != nullptr) {
90 mObject->decRef();
91 mObject = nullptr;
92 }
93 }
94
95 template <typename ObjectType>
96 ObjectType *SharedPtr<ObjectType>::operator->() const {
97 return get();
98 }
99
100 template <typename ObjectType>
101 ObjectType &SharedPtr<ObjectType>::operator*() const {
102 return *get();
103 }
104
105 template <typename ObjectType>
106 ObjectType &SharedPtr<ObjectType>::operator[](size_t index) const {
107 return get()[index];
108 }
109
110 template <typename ObjectType>
111 bool SharedPtr<ObjectType>::operator==(
112 const SharedPtr<ObjectType> &other) const {
113 return mObject == other.get();
114 }
115
116 template <typename ObjectType>
117 bool SharedPtr<ObjectType>::operator!=(
118 const SharedPtr<ObjectType> &other) const {
119 return !(*this == other);
120 }
121
122 template <typename ObjectType>
123 SharedPtr<ObjectType> &SharedPtr<ObjectType>::operator=(
124 const SharedPtr<ObjectType> &other) {
125 reset(other.mObject);
126 return *this;
127 }
128
129 template <typename ObjectType>
130 SharedPtr<ObjectType> &SharedPtr<ObjectType>::operator=(
131 SharedPtr<ObjectType> &&other) {
132 reset();
133 mObject = other.mObject;
134 other.mObject = nullptr;
135 return *this;
136 }
137
138 template <typename ObjectType, typename... Args>
MakeShared(Args &&...args)139 inline SharedPtr<ObjectType> MakeShared(Args &&...args) {
140 return SharedPtr<ObjectType>(
141 memoryAlloc<ObjectType>(std::forward<Args>(args)...));
142 }
143
144 template <typename ObjectType>
MakeSharedZeroFill()145 inline SharedPtr<ObjectType> MakeSharedZeroFill() {
146 // Due to the need for ObjectType to inherit from RefBase, typical
147 // trivial-types won't have a trivial constructor. To match what is provided
148 // for UniquePtr, this logic is slightly reworked to allow zero'ing out the
149 // memory before constructing the object.
150 auto *ptr = memoryAlloc(sizeof(ObjectType));
151 if (ptr != nullptr) {
152 memset(ptr, 0, sizeof(ObjectType));
153 }
154
155 auto *castedPtr = static_cast<ObjectType *>(ptr);
156 if (castedPtr != nullptr) {
157 new (castedPtr) ObjectType();
158 }
159
160 return SharedPtr<ObjectType>(castedPtr);
161 }
162
163 } // namespace chre
164
165 #endif // CHRE_UTIL_SYSTEM_SHARED_PTR_IMPL_H_
166