xref: /aosp_15_r20/system/chre/util/include/chre/util/unique_ptr_impl.h (revision 84e339476a462649f82315436d70fd732297a399)
1 /*
2  * Copyright (C) 2016 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_UNIQUE_PTR_IMPL_H_
18 #define CHRE_UTIL_UNIQUE_PTR_IMPL_H_
19 
20 // IWYU pragma: private
21 #include "chre/util/unique_ptr.h"
22 
23 #include <string.h>
24 #include <type_traits>
25 #include <utility>
26 
27 #include "chre/util/container_support.h"
28 #include "chre/util/memory.h"
29 
30 namespace chre {
31 
32 template <typename ObjectOrArrayType>
UniquePtr()33 UniquePtr<ObjectOrArrayType>::UniquePtr() : mObject(nullptr) {}
34 
35 template <typename ObjectOrArrayType>
UniquePtr(typename UniquePtr<ObjectOrArrayType>::ObjectType * object)36 UniquePtr<ObjectOrArrayType>::UniquePtr(
37     typename UniquePtr<ObjectOrArrayType>::ObjectType *object)
38     : mObject(object) {}
39 
40 template <typename ObjectOrArrayType>
UniquePtr(UniquePtr<ObjectOrArrayType> && other)41 UniquePtr<ObjectOrArrayType>::UniquePtr(UniquePtr<ObjectOrArrayType> &&other) {
42   mObject = other.mObject;
43   other.mObject = nullptr;
44 }
45 
46 template <typename ObjectOrArrayType>
47 template <typename OtherObjectOrArrayType>
UniquePtr(UniquePtr<OtherObjectOrArrayType> && other)48 UniquePtr<ObjectOrArrayType>::UniquePtr(
49     UniquePtr<OtherObjectOrArrayType> &&other) {
50   static_assert(std::is_array_v<ObjectOrArrayType> ==
51                     std::is_array_v<OtherObjectOrArrayType>,
52                 "UniquePtr conversion not supported across array and non-array "
53                 "types");
54   mObject = other.mObject;
55   other.mObject = nullptr;
56 }
57 
58 template <typename ObjectOrArrayType>
~UniquePtr()59 UniquePtr<ObjectOrArrayType>::~UniquePtr() {
60   reset();
61 }
62 
63 template <typename ObjectOrArrayType>
isNull()64 bool UniquePtr<ObjectOrArrayType>::isNull() const {
65   return (mObject == nullptr);
66 }
67 
68 template <typename ObjectOrArrayType>
69 typename UniquePtr<ObjectOrArrayType>::ObjectType *
get()70 UniquePtr<ObjectOrArrayType>::get() const {
71   return mObject;
72 }
73 
74 template <typename ObjectOrArrayType>
75 typename UniquePtr<ObjectOrArrayType>::ObjectType *
release()76 UniquePtr<ObjectOrArrayType>::release() {
77   ObjectType *obj = mObject;
78   mObject = nullptr;
79   return obj;
80 }
81 
82 template <typename ObjectOrArrayType>
reset(ObjectType * object)83 void UniquePtr<ObjectOrArrayType>::reset(ObjectType *object) {
84   CHRE_ASSERT(object == nullptr || mObject != object);
85 
86   reset();
87   mObject = object;
88 }
89 
90 template <typename ObjectOrArrayType>
reset()91 void UniquePtr<ObjectOrArrayType>::reset() {
92   if (mObject != nullptr) {
93     if constexpr (!std::is_trivially_destructible_v<ObjectType>) {
94       mObject->~ObjectType();
95     }
96     memoryFree(mObject);
97     mObject = nullptr;
98   }
99 }
100 
101 template <typename ObjectOrArrayType>
102 typename UniquePtr<ObjectOrArrayType>::ObjectType *
103 UniquePtr<ObjectOrArrayType>::operator->() const {
104   static_assert(!std::is_array_v<ObjectOrArrayType>,
105                 "UniquePtr<T>::operator-> is not supported for array types");
106   return get();
107 }
108 
109 template <typename ObjectOrArrayType>
110 typename UniquePtr<ObjectOrArrayType>::ObjectType &
111 UniquePtr<ObjectOrArrayType>::operator*() const {
112   static_assert(!std::is_array_v<ObjectOrArrayType>,
113                 "UniquePtr<T>::operator* is not supported for array types");
114   return *get();
115 }
116 
117 template <typename ObjectOrArrayType>
118 typename UniquePtr<ObjectOrArrayType>::ObjectType &
119 UniquePtr<ObjectOrArrayType>::operator[](size_t index) const {
120   static_assert(std::is_array_v<ObjectOrArrayType>,
121                 "UniquePtr<T>::operator[] is only allowed when T is an array");
122   return get()[index];
123 }
124 
125 template <typename ObjectOrArrayType>
126 bool UniquePtr<ObjectOrArrayType>::operator==(
127     const UniquePtr<ObjectOrArrayType> &other) const {
128   return mObject == other.get();
129 }
130 
131 template <typename ObjectOrArrayType>
132 bool UniquePtr<ObjectOrArrayType>::operator!=(
133     const UniquePtr<ObjectOrArrayType> &other) const {
134   return !(*this == other);
135 }
136 
137 template <typename ObjectOrArrayType>
138 UniquePtr<ObjectOrArrayType> &UniquePtr<ObjectOrArrayType>::operator=(
139     UniquePtr<ObjectOrArrayType> &&other) {
140   reset();
141   mObject = other.mObject;
142   other.mObject = nullptr;
143   return *this;
144 }
145 
146 template <typename ObjectType, typename... Args>
MakeUnique(Args &&...args)147 inline UniquePtr<ObjectType> MakeUnique(Args &&... args) {
148   return UniquePtr<ObjectType>(
149       memoryAlloc<ObjectType>(std::forward<Args>(args)...));
150 }
151 
152 template <typename ObjectArrayType>
MakeUniqueArray(size_t count)153 UniquePtr<ObjectArrayType> MakeUniqueArray(size_t count) {
154   return UniquePtr<ObjectArrayType>(memoryAllocArray<ObjectArrayType>(count));
155 }
156 
157 template <typename ObjectType>
MakeUniqueZeroFill()158 inline UniquePtr<ObjectType> MakeUniqueZeroFill() {
159   // For simplicity, we call memset *after* memoryAlloc<ObjectType>() - this is
160   // only valid for types that have a trivial constructor. This utility function
161   // is really meant to be used with trivial types only - if there's a desire to
162   // zero things out in a non-trivial type, the right place for that is in its
163   // constructor.
164   static_assert(std::is_trivial<ObjectType>::value,
165                 "MakeUniqueZeroFill is only supported for trivial types");
166   auto ptr = UniquePtr<ObjectType>(memoryAlloc<ObjectType>());
167   if (!ptr.isNull()) {
168     memset(ptr.get(), 0, sizeof(ObjectType));
169   }
170   return ptr;
171 }
172 
173 }  // namespace chre
174 
175 #endif  // CHRE_UTIL_UNIQUE_PTR_IMPL_H_
176