blob: 2abe33bbc61984c7d47845e1a111fa1af8a9e6e7 [file] [log] [blame]
// Copyright 2014 The Android Open Source Project
//
// This software is licensed under the terms of the GNU General Public
// License version 2, as published by the Free Software Foundation, and
// may be copied, distributed, and modified under those terms.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
#pragma once
#include "android/base/TypeTraits.h"
#include <memory>
#include <type_traits>
#include <utility>
#include <stdlib.h>
namespace android {
namespace base {
struct FreeDelete {
template <class T>
void operator()(T ptr) const {
free((void*)ptr);
}
};
template <class Func>
struct FuncDelete {
explicit FuncDelete(Func f = {}) : mF(f) {}
FuncDelete(const FuncDelete& other) = default;
FuncDelete(FuncDelete&& other) = default;
FuncDelete& operator=(const FuncDelete& other) = default;
FuncDelete& operator=(FuncDelete&& other) = default;
// To be able to copy/move from all compatible template instantiations.
template <class U> friend struct FuncDelete;
// Template constructors and move assignment from compatible instantiations.
template <class U>
FuncDelete(const FuncDelete<U>& other) : mF(other.mF) {}
template <class U>
FuncDelete(FuncDelete<U>&& other) : mF(std::move(other.mF)) {}
template <class U>
FuncDelete& operator=(const FuncDelete<U>& other) {
mF = other.mF;
return *this;
}
template <class U>
FuncDelete& operator=(FuncDelete<U>&& other) {
mF = std::move(other.mF);
return *this;
}
// This is the actual deleter call.
template <class T>
void operator()(T t) const {
mF(t);
}
private:
Func mF;
};
template <class T, class Deleter = std::default_delete<T>>
using ScopedPtr = std::unique_ptr<T, Deleter>;
template <class T>
using ScopedCPtr = std::unique_ptr<T, FreeDelete>;
template <class T, class Func>
using ScopedCustomPtr = std::unique_ptr<T, FuncDelete<Func>>;
// A factory function that creates a scoped pointer with |deleter|
// function used as a deleter - it is called at the scope exit.
// Note: enable_if<> limits the scope of allowed arguments to pointers and
// std::nullptr_t (to allow makeCustomScopedPtr(nullptr, ...) calls).
template <class T,
class Func,
class = enable_if_c<std::is_same<T, std::nullptr_t>::value ||
std::is_pointer<T>::value>>
ScopedCustomPtr<
typename std::decay<typename std::remove_pointer<T>::type>::type,
typename std::decay<Func>::type>
makeCustomScopedPtr(T data, Func deleter) {
return ScopedCustomPtr<
typename std::decay<typename std::remove_pointer<T>::type>::type,
typename std::decay<Func>::type>(
data, FuncDelete<typename std::decay<Func>::type>(deleter));
}
} // namespace base
} // namespace android