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