blob: eb92f1153c4e9ac7a1c30885fe3dba87f0b4c0e1 [file] [log] [blame]
#ifndef AOS_UNIQUE_MALLOC_PTR_H_
#define AOS_UNIQUE_MALLOC_PTR_H_
#include <memory>
namespace aos {
namespace internal {
// Written as a functor so that it doesn't have to get passed to
// std::unique_ptr's constructor as an argument.
template<typename T, void(*function)(T *)>
class const_wrap {
public:
void operator()(const T *ptr) {
function(const_cast<T *>(ptr));
}
};
// Wrapper function to deal with the differences between C and C++ (C++ doesn't
// automatically convert T* to void* like C).
template<typename T>
void free_type(T *ptr) { ::free(reinterpret_cast<void *>(ptr)); }
} // namespace internal
// A std::unique_ptr that should get freed with a C-style free function
// (free(2) by default).
template <typename T, void (*function)(T *) = internal::free_type<T>>
class unique_c_ptr
: public std::unique_ptr<T, internal::const_wrap<T, function>> {
public:
unique_c_ptr(T *value)
: std::unique_ptr<T, internal::const_wrap<T, function>>(value) {}
// perfect forwarding of these 2 to make unique_ptr work
template <typename... Args>
unique_c_ptr(Args &&... args)
: std::unique_ptr<T, internal::const_wrap<T, function>>(
std::forward<Args>(args)...) {}
template<typename... Args>
unique_c_ptr<T, function> &operator=(Args&&... args) {
std::unique_ptr<T, internal::const_wrap<T, function>>::operator=(
std::forward<Args>(args)...);
return *this;
}
};
} // namespace aos
#endif // AOS_UNIQUE_MALLOC_PTR_H_