1 // Copyright 2014 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #pragma once
16
17 #include "aemu/base/TypeTraits.h"
18
19 #include <memory>
20 #include <type_traits>
21 #include <utility>
22
23 #include <stdlib.h>
24
25 namespace android {
26 namespace base {
27
28 struct FreeDelete {
29 template <class T>
operatorFreeDelete30 void operator()(T ptr) const {
31 free((void*)ptr);
32 }
33 };
34
35 template <class Func>
36 struct FuncDelete {
FuncDeleteFuncDelete37 FuncDelete() : mF() { }
FuncDeleteFuncDelete38 explicit FuncDelete(Func f) : mF(std::move(f)) {}
39
40 FuncDelete(const FuncDelete& other) = default;
41 FuncDelete(FuncDelete&& other) = default;
42 FuncDelete& operator=(const FuncDelete& other) = default;
43 FuncDelete& operator=(FuncDelete&& other) = default;
44
45 // To be able to copy/move from all compatible template instantiations.
46 template <class U> friend struct FuncDelete;
47
48 // Template constructors and move assignment from compatible instantiations.
49 template <class U>
FuncDeleteFuncDelete50 FuncDelete(const FuncDelete<U>& other) : mF(other.mF) {}
51 template <class U>
FuncDeleteFuncDelete52 FuncDelete(FuncDelete<U>&& other) : mF(std::move(other.mF)) {}
53 template <class U>
54 FuncDelete& operator=(const FuncDelete<U>& other) {
55 mF = other.mF;
56 return *this;
57 }
58 template <class U>
59 FuncDelete& operator=(FuncDelete<U>&& other) {
60 mF = std::move(other.mF);
61 return *this;
62 }
63
64 // This is the actual deleter call.
65 template <class T>
operatorFuncDelete66 void operator()(T t) const {
67 mF(t);
68 }
69
70 private:
71 Func mF;
72 };
73
74 template <class T, class Deleter = std::default_delete<T>>
75 using ScopedPtr = std::unique_ptr<T, Deleter>;
76
77 template <class T>
78 using ScopedCPtr = std::unique_ptr<T, FreeDelete>;
79
80 template <class T, class Func>
81 using ScopedCustomPtr = std::unique_ptr<T, FuncDelete<Func>>;
82
83 // A factory function that creates a scoped pointer with |deleter|
84 // function used as a deleter - it is called at the scope exit.
85 // Note: enable_if<> limits the scope of allowed arguments to pointers.
86 template <class T,
87 class Func,
88 class = enable_if_c<std::is_pointer<T>::value>>
89 ScopedCustomPtr<
90 typename std::decay<typename std::remove_pointer<T>::type>::type,
91 typename std::decay<Func>::type>
makeCustomScopedPtr(T data,Func deleter)92 makeCustomScopedPtr(T data, Func deleter) {
93 return ScopedCustomPtr<
94 typename std::decay<typename std::remove_pointer<T>::type>::type,
95 typename std::decay<Func>::type>(
96 data, FuncDelete<typename std::decay<Func>::type>(deleter));
97 }
98
99 } // namespace base
100 } // namespace android
101