xref: /aosp_15_r20/system/chre/apps/nearby/third_party/contexthub/chre/util/include/chre/util/unique_ptr.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_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