blob: eb92f1153c4e9ac7a1c30885fe3dba87f0b4c0e1 [file] [log] [blame]
Austin Schuh1676fec2019-12-28 20:17:34 -08001#ifndef AOS_UNIQUE_MALLOC_PTR_H_
2#define AOS_UNIQUE_MALLOC_PTR_H_
3
brians343bc112013-02-10 01:53:46 +00004#include <memory>
5
6namespace aos {
7
Austin Schuh1676fec2019-12-28 20:17:34 -08008namespace internal {
brians343bc112013-02-10 01:53:46 +00009
briansda7756f2013-02-27 04:19:33 +000010// Written as a functor so that it doesn't have to get passed to
11// std::unique_ptr's constructor as an argument.
brians343bc112013-02-10 01:53:46 +000012template<typename T, void(*function)(T *)>
briansda7756f2013-02-27 04:19:33 +000013class const_wrap {
14 public:
15 void operator()(const T *ptr) {
16 function(const_cast<T *>(ptr));
17 }
18};
brians343bc112013-02-10 01:53:46 +000019
20// Wrapper function to deal with the differences between C and C++ (C++ doesn't
21// automatically convert T* to void* like C).
22template<typename T>
23void free_type(T *ptr) { ::free(reinterpret_cast<void *>(ptr)); }
24
Austin Schuh1676fec2019-12-28 20:17:34 -080025} // namespace internal
brians343bc112013-02-10 01:53:46 +000026
27// A std::unique_ptr that should get freed with a C-style free function
28// (free(2) by default).
Austin Schuh1676fec2019-12-28 20:17:34 -080029template <typename T, void (*function)(T *) = internal::free_type<T>>
30class unique_c_ptr
31 : public std::unique_ptr<T, internal::const_wrap<T, function>> {
brians343bc112013-02-10 01:53:46 +000032 public:
Austin Schuh1676fec2019-12-28 20:17:34 -080033 unique_c_ptr(T *value)
34 : std::unique_ptr<T, internal::const_wrap<T, function>>(value) {}
briansda7756f2013-02-27 04:19:33 +000035
36 // perfect forwarding of these 2 to make unique_ptr work
Austin Schuh1676fec2019-12-28 20:17:34 -080037 template <typename... Args>
38 unique_c_ptr(Args &&... args)
39 : std::unique_ptr<T, internal::const_wrap<T, function>>(
40 std::forward<Args>(args)...) {}
briansda7756f2013-02-27 04:19:33 +000041 template<typename... Args>
42 unique_c_ptr<T, function> &operator=(Args&&... args) {
Austin Schuh1676fec2019-12-28 20:17:34 -080043 std::unique_ptr<T, internal::const_wrap<T, function>>::operator=(
briansda7756f2013-02-27 04:19:33 +000044 std::forward<Args>(args)...);
45 return *this;
46 }
brians343bc112013-02-10 01:53:46 +000047};
48
49} // namespace aos
Austin Schuh1676fec2019-12-28 20:17:34 -080050
51#endif // AOS_UNIQUE_MALLOC_PTR_H_