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_H_ 18 #define CHRE_UTIL_UNIQUE_PTR_H_ 19 20 #include <cstddef> 21 #include <type_traits> 22 23 #include "chre/util/non_copyable.h" 24 25 namespace chre { 26 27 /** 28 * Wraps a pointer to a dynamically allocated object and manages the underlying 29 * memory. The goal is to be similar to std::unique_ptr, but we do not support 30 * custom deleters - deletion is always done via memoryFree(). 31 */ 32 template <typename ObjectOrArrayType> 33 class UniquePtr : public NonCopyable { 34 // For array types (e.g. char[]) we need to drop the [] to get to the actual 35 // type used with pointers. If ObjectOrArrayType is not an array, then the 36 // type is the same. 37 using ObjectType = typename std::remove_extent<ObjectOrArrayType>::type; 38 39 // This limitation is due to CHRE not supporting operator delete[], which 40 // requires querying the allocation size from the heap allocator to know how 41 // many times to invoke the destructor. 42 static_assert(!std::is_array_v<ObjectOrArrayType> || 43 std::is_trivially_destructible_v<ObjectType>, 44 "UniquePtr is only supported for arrays with trivially " 45 "destructible elements"); 46 47 public: 48 typedef ObjectType *pointer; 49 50 /** 51 * Construct a UniquePtr instance that does not own any object. 52 */ 53 UniquePtr(); UniquePtr(std::nullptr_t)54 UniquePtr(std::nullptr_t) : UniquePtr() {} 55 56 /** 57 * Constructs a UniquePtr instance that owns the given object, and will free 58 * its memory when the UniquePtr is destructed. 59 * 60 * @param object Pointer to an object allocated via memoryAlloc. It is not 61 * valid for this object's memory to come from any other source, 62 * including the stack, or static allocation on the heap. 63 */ 64 explicit UniquePtr(ObjectType *object); 65 66 /** 67 * Constructs a new UniquePtr via moving the Object from another UniquePtr. 68 * 69 * @param other UniquePtr instance to move into this object 70 */ 71 UniquePtr(UniquePtr<ObjectOrArrayType> &&other); 72 73 /** 74 * Constructs a new UniquePtr via moving the Object from another UniquePtr. 75 * This constructor allows conversion (ie: upcast) to another type if 76 * possible. 77 * 78 * @param other UniquePtr instance to move and convert into this object. 79 */ 80 template <typename OtherObjectOrArrayType> 81 UniquePtr(UniquePtr<OtherObjectOrArrayType> &&other); 82 83 /** 84 * Deconstructs the object (if necessary) and releases associated memory. 85 */ 86 ~UniquePtr(); 87 88 /** 89 * Determines if this UniquePtr owns an object, or references null. 90 * 91 * @return true if get() returns nullptr 92 */ 93 bool isNull() const; 94 95 /** 96 * @return A pointer to the underlying object, or nullptr if this object is 97 * not currently valid. 98 */ 99 ObjectType *get() const; 100 101 /** 102 * Releases ownership of the underlying object, so it will not be freed when 103 * this object is destructed. After this function returns, get() will return 104 * nullptr. 105 * 106 * @return A pointer to the underlying object (i.e. what get() would return 107 * prior to this function call) 108 */ 109 ObjectType *release(); 110 111 /** 112 * Replaces the object owned by the UniquePtr by an object pointed by a given 113 * pointer. Also calls the destructor and releases the associated memory of 114 * the previously owned object. Invoking this method on the object managed by 115 * the UniquePtr, obtained via get(), is illegal. 116 * 117 * @param object the object to replace the ownership of the UniquePtr 118 */ 119 void reset(ObjectType *object); 120 121 /** 122 * Destroys the object owned by the UniquePtr. Also calls the destructor and 123 * releases the associated memory of the previously owned object. 124 */ 125 void reset(); 126 127 /** 128 * @return A pointer to the underlying object. 129 */ 130 ObjectType *operator->() const; 131 132 /** 133 * @return A reference to the underlying object. 134 */ 135 ObjectType &operator*() const; 136 137 /** 138 * Indexing operator. Only supported if the type we are wrapping is an array. 139 */ 140 ObjectType &operator[](size_t index) const; 141 142 /** 143 * Move assignment operator. Ownership of this object is transferred and the 144 * other object is left in an invalid state. 145 * 146 * @param other The other object being moved. 147 * @return A reference to the newly moved object. 148 */ 149 UniquePtr<ObjectOrArrayType> &operator=(UniquePtr<ObjectOrArrayType> &&other); 150 151 /** 152 * Two unique_ptr compare equal (==) if their stored pointers compare equal, 153 * and not equal (!=) otherwise. 154 * 155 * @param other The other object being compared. 156 * @return true if the other's pointer is same as the underlying pointer, 157 * otherwise false. 158 */ 159 bool operator==(const UniquePtr<ObjectOrArrayType> &other) const; 160 161 /** 162 * Two unique_ptr compare equal (==) if their stored pointers compare equal, 163 * and not equal (!=) otherwise. 164 * 165 * @param other The other object being compared. 166 * @return true if the other's pointer is different than the underlying 167 * pointer, otherwise false. 168 */ 169 bool operator!=(const UniquePtr<ObjectOrArrayType> &other) const; 170 171 //! @defgroup Alternative approaches for null testing 172 //! @{ 173 bool operator!=(std::nullptr_t) const { 174 return !isNull(); 175 } 176 bool operator==(std::nullptr_t) const { 177 return isNull(); 178 } 179 operator bool() const { 180 return !isNull(); 181 } 182 //! @} 183 184 private: 185 // Befriend this class to itself to allow the templated conversion constructor 186 // permission to access mObject below. 187 template <typename OtherObjectOrArrayType> 188 friend class UniquePtr; 189 190 ObjectType *mObject; 191 }; 192 193 // Help the compiler out with a deduction guide – now that the template 194 // parameter may differ from the constructor parameter (e.g. char[] vs. char*), 195 // it isn't always able to make the connection that they are usually the same. 196 template <typename ObjectType> 197 UniquePtr(ObjectType *) -> UniquePtr<ObjectType>; 198 199 /** 200 * Allocates and constructs a new object of type ObjectType on the heap, and 201 * returns a UniquePtr that owns the object. This function is similar to 202 * std::make_unique. 203 * 204 * @param args The arguments to pass to the object's constructor. 205 */ 206 template <typename ObjectType, typename... Args> 207 UniquePtr<ObjectType> MakeUnique(Args &&...args); 208 209 /** 210 * Allocates an array of objects of type ObjectType on the heap, and returns a 211 * UniquePtr that owns the object. ObjectType must be an array type with unknown 212 * bound, for example char[]. Objects are default-initialized (i.e. may hold an 213 * indeterminate/uninitialized value). This function is similar to 214 * std::make_unique_for_overwrite(std::size_t). 215 * 216 * Example usage: 217 * auto buf = MakeUniqueArray<uint8_t[]>(size); 218 * 219 * @param count The size of the array 220 */ 221 template <typename ObjectArrayType> 222 UniquePtr<ObjectArrayType> MakeUniqueArray(size_t count); 223 224 /** 225 * Just like MakeUnique(), except it zeros out any allocated memory. Intended to 226 * be used for creating objects that have trivial constructors (e.g. C structs) 227 * but should start with a known state. 228 */ 229 template <typename ObjectType> 230 UniquePtr<ObjectType> MakeUniqueZeroFill(); 231 232 } // namespace chre 233 234 #include "chre/util/unique_ptr_impl.h" 235 236 #endif // CHRE_UTIL_UNIQUE_PTR_H_ 237