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>(memoryAlloc<ObjectType>(
128       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