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 #include "chre/util/unique_ptr.h"
21
22 #include <string.h>
23 #include <type_traits>
24 #include <utility>
25
26 #include "chre/util/container_support.h"
27 #include "chre/util/memory.h"
28
29 namespace chre {
30
31 template <typename ObjectType>
UniquePtr()32 UniquePtr<ObjectType>::UniquePtr() : mObject(nullptr) {}
33
34 template <typename ObjectType>
UniquePtr(ObjectType * object)35 UniquePtr<ObjectType>::UniquePtr(ObjectType *object) : mObject(object) {}
36
37 template <typename ObjectType>
UniquePtr(UniquePtr<ObjectType> && other)38 UniquePtr<ObjectType>::UniquePtr(UniquePtr<ObjectType> &&other) {
39 mObject = other.mObject;
40 other.mObject = nullptr;
41 }
42
43 template <typename ObjectType>
44 template <typename OtherObjectType>
UniquePtr(UniquePtr<OtherObjectType> && other)45 UniquePtr<ObjectType>::UniquePtr(UniquePtr<OtherObjectType> &&other) {
46 mObject = other.mObject;
47 other.mObject = nullptr;
48 }
49
50 template <typename ObjectType>
~UniquePtr()51 UniquePtr<ObjectType>::~UniquePtr() {
52 reset();
53 }
54
55 template <typename ObjectType>
isNull()56 bool UniquePtr<ObjectType>::isNull() const {
57 return (mObject == nullptr);
58 }
59
60 template <typename ObjectType>
get()61 ObjectType *UniquePtr<ObjectType>::get() const {
62 return mObject;
63 }
64
65 template <typename ObjectType>
release()66 ObjectType *UniquePtr<ObjectType>::release() {
67 ObjectType *obj = mObject;
68 mObject = nullptr;
69 return obj;
70 }
71
72 template <typename ObjectType>
reset(ObjectType * object)73 void UniquePtr<ObjectType>::reset(ObjectType *object) {
74 CHRE_ASSERT(object == nullptr || mObject != object);
75
76 reset();
77 mObject = object;
78 }
79
80 template <typename ObjectType>
reset()81 void UniquePtr<ObjectType>::reset() {
82 if (mObject != nullptr) {
83 mObject->~ObjectType();
84 memoryFree(mObject);
85 mObject = nullptr;
86 }
87 }
88
89 template <typename ObjectType>
90 ObjectType *UniquePtr<ObjectType>::operator->() const {
91 return get();
92 }
93
94 template <typename ObjectType>
95 ObjectType &UniquePtr<ObjectType>::operator*() const {
96 return *get();
97 }
98
99 template <typename ObjectType>
100 ObjectType &UniquePtr<ObjectType>::operator[](size_t index) const {
101 return get()[index];
102 }
103
104 template <typename ObjectType>
105 bool UniquePtr<ObjectType>::operator==(
106 const UniquePtr<ObjectType> &other) const {
107 return mObject == other.get();
108 }
109
110 template <typename ObjectType>
111 bool UniquePtr<ObjectType>::operator!=(
112 const UniquePtr<ObjectType> &other) const {
113 return !(*this == other);
114 }
115
116 template <typename ObjectType>
117 UniquePtr<ObjectType> &UniquePtr<ObjectType>::operator=(
118 UniquePtr<ObjectType> &&other) {
119 reset();
120 mObject = other.mObject;
121 other.mObject = nullptr;
122 return *this;
123 }
124
125 template <typename ObjectType, typename... Args>
MakeUnique(Args &&...args)126 inline UniquePtr<ObjectType> MakeUnique(Args &&... args) {
127 return UniquePtr<ObjectType>(
128 memoryAlloc<ObjectType>(std::forward<Args>(args)...));
129 }
130
131 template <typename ObjectType>
MakeUniqueZeroFill()132 inline UniquePtr<ObjectType> MakeUniqueZeroFill() {
133 // For simplicity, we call memset *after* memoryAlloc<ObjectType>() - this is
134 // only valid for types that have a trivial constructor. This utility function
135 // is really meant to be used with trivial types only - if there's a desire to
136 // zero things out in a non-trivial type, the right place for that is in its
137 // constructor.
138 static_assert(std::is_trivial<ObjectType>::value,
139 "MakeUniqueZeroFill is only supported for trivial types");
140 auto ptr = UniquePtr<ObjectType>(memoryAlloc<ObjectType>());
141 if (!ptr.isNull()) {
142 memset(ptr.get(), 0, sizeof(ObjectType));
143 }
144 return ptr;
145 }
146
147 } // namespace chre
148
149 #endif // CHRE_UTIL_UNIQUE_PTR_IMPL_H_
150