improved unique_c_ptr

It didn't support using some really useful parts of unique_ptr before.

git-svn-id: https://robotics.mvla.net/svn/frc971/2013/trunk/src@4166 f308d9b7-e957-4cde-b6ac-9a88185e7312
diff --git a/aos/common/unique_malloc_ptr.h b/aos/common/unique_malloc_ptr.h
index 696b9f3..bd2c37c 100644
--- a/aos/common/unique_malloc_ptr.h
+++ b/aos/common/unique_malloc_ptr.h
@@ -4,10 +4,15 @@
 
 namespace {
 
+// 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 *)>
-void const_wrap(const T *ptr) {
-  function(const_cast<T *>(ptr));
-}
+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).
@@ -18,12 +23,22 @@
 
 // A std::unique_ptr that should get freed with a C-style free function
 // (free(2) by default).
-template<typename T, void(*function)(T *) = free_type>
-class unique_c_ptr : public std::unique_ptr<T, void(*)(const T *)> {
+template<typename T, void(*function)(T *) = free_type<T>>
+class unique_c_ptr : public std::unique_ptr<T, const_wrap<T, function>> {
  public:
-  unique_c_ptr(T *pointer)
-      : std::unique_ptr<T, void(*)(const T *)>(
-          pointer, const_wrap<T, function>) {}
+  unique_c_ptr(T *value) : std::unique_ptr<T, 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, const_wrap<T, function>>(std::forward<Args>(args)...) {
+  }
+  template<typename... Args>
+  unique_c_ptr<T, function> &operator=(Args&&... args) {
+    std::unique_ptr<T, const_wrap<T, function>>::operator=(
+        std::forward<Args>(args)...);
+    return *this;
+  }
 };
 
 }  // namespace aos