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