blob: bd2c37c5af4d3a67d4e9ec944080d39284cc3ce0 [file] [log] [blame]
brians343bc112013-02-10 01:53:46 +00001#include <memory>
2
3namespace aos {
4
5namespace {
6
briansda7756f2013-02-27 04:19:33 +00007// Written as a functor so that it doesn't have to get passed to
8// std::unique_ptr's constructor as an argument.
brians343bc112013-02-10 01:53:46 +00009template<typename T, void(*function)(T *)>
briansda7756f2013-02-27 04:19:33 +000010class const_wrap {
11 public:
12 void operator()(const T *ptr) {
13 function(const_cast<T *>(ptr));
14 }
15};
brians343bc112013-02-10 01:53:46 +000016
17// Wrapper function to deal with the differences between C and C++ (C++ doesn't
18// automatically convert T* to void* like C).
19template<typename T>
20void free_type(T *ptr) { ::free(reinterpret_cast<void *>(ptr)); }
21
22} // namespace
23
24// A std::unique_ptr that should get freed with a C-style free function
25// (free(2) by default).
briansda7756f2013-02-27 04:19:33 +000026template<typename T, void(*function)(T *) = free_type<T>>
27class unique_c_ptr : public std::unique_ptr<T, const_wrap<T, function>> {
brians343bc112013-02-10 01:53:46 +000028 public:
briansda7756f2013-02-27 04:19:33 +000029 unique_c_ptr(T *value) : std::unique_ptr<T, const_wrap<T, function>>(value) {}
30
31 // perfect forwarding of these 2 to make unique_ptr work
32 template<typename... Args>
33 unique_c_ptr(Args&&... args)
34 : std::unique_ptr<T, const_wrap<T, function>>(std::forward<Args>(args)...) {
35 }
36 template<typename... Args>
37 unique_c_ptr<T, function> &operator=(Args&&... args) {
38 std::unique_ptr<T, const_wrap<T, function>>::operator=(
39 std::forward<Args>(args)...);
40 return *this;
41 }
brians343bc112013-02-10 01:53:46 +000042};
43
44} // namespace aos