source/*: Use unique_function so our callbacks can be move-only

This will allow move-only types like unique_ptr to be used in callbacks.

Change-Id: Ia99925cea3bf96e3c213ba0fe093cc6ab3f5a421
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/meson.build b/src/meson.build
index 59875da..ebe678c 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -1,6 +1,28 @@
+# Function2 might not have a pkg-config. It is header only so just make
+# sure we can access the needed symbols from the header.
+function2_dep = dependency('function2', required: false)
+has_function2 = meson.get_compiler('cpp').has_header_symbol(
+  'function2/function2.hpp',
+  'fu2::unique_function',
+  dependencies: function2_dep,
+  required: false)
+if not has_function2
+  function2_proj = import('cmake').subproject(
+    'function2',
+    cmake_options: [
+	  '-DBUILD_TESTING=OFF',
+    ],
+    required: false)
+  assert(function2_proj.found(), 'function2 is required')
+  if function2_proj.found()
+    function2_dep = function2_proj.dependency('function2')
+  endif
+endif
+
 sdeventplus_deps = [
   dependency('libsystemd', version: '>=239'),
   dependency('stdplus', fallback: ['stdplus', 'stdplus']),
+  function2_dep,
 ]
 
 sdeventplus_headers = include_directories('.')
diff --git a/src/sdeventplus/source/base.cpp b/src/sdeventplus/source/base.cpp
index 450d9a1..319b510 100644
--- a/src/sdeventplus/source/base.cpp
+++ b/src/sdeventplus/source/base.cpp
@@ -61,7 +61,7 @@
     }
 }
 
-const Base::Callback& Base::get_prepare() const
+Base::Callback& Base::get_prepare()
 {
     return prepare;
 }
diff --git a/src/sdeventplus/source/base.hpp b/src/sdeventplus/source/base.hpp
index e86b405..d177079 100644
--- a/src/sdeventplus/source/base.hpp
+++ b/src/sdeventplus/source/base.hpp
@@ -3,6 +3,7 @@
 #include <cerrno>
 #include <cstdint>
 #include <cstdio>
+#include <function2/function2.hpp>
 #include <functional>
 #include <sdeventplus/event.hpp>
 #include <sdeventplus/internal/utils.hpp>
@@ -34,7 +35,7 @@
 class Base
 {
   public:
-    using Callback = std::function<void(Base& source)>;
+    using Callback = fu2::unique_function<void(Base& source)>;
 
     virtual ~Base();
 
@@ -140,7 +141,7 @@
      *  @return A reference to the callback, this should be checked to make sure
      *          the callback is valid as there is no guarantee
      */
-    const Callback& get_prepare() const;
+    Callback& get_prepare();
 
     /** @brief A helper for subclasses to trivially wrap a c++ style callback
      *         to be called from the sd-event c library
@@ -151,8 +152,8 @@
      *  @param[in] args...  - Extra arguments to pass to the callaback
      *  @return An negative errno on error, or 0 on success
      */
-    template <typename Callback, class Source,
-              const Callback& (Source::*getter)() const, typename... Args>
+    template <typename Callback, class Source, Callback& (Source::*getter)(),
+              typename... Args>
     static int sourceCallback(const char* name, sd_event_source*,
                               void* userdata, Args&&... args)
     {
diff --git a/src/sdeventplus/source/child.cpp b/src/sdeventplus/source/child.cpp
index e1fe167..9701d82 100644
--- a/src/sdeventplus/source/child.cpp
+++ b/src/sdeventplus/source/child.cpp
@@ -29,7 +29,7 @@
     return pid;
 }
 
-const Child::Callback& Child::get_callback() const
+Child::Callback& Child::get_callback()
 {
     return callback;
 }
diff --git a/src/sdeventplus/source/child.hpp b/src/sdeventplus/source/child.hpp
index ed147d6..4f29994 100644
--- a/src/sdeventplus/source/child.hpp
+++ b/src/sdeventplus/source/child.hpp
@@ -1,6 +1,6 @@
 #pragma once
 
-#include <functional>
+#include <function2/function2.hpp>
 #include <sdeventplus/source/base.hpp>
 #include <signal.h>
 
@@ -16,7 +16,8 @@
 class Child : public Base
 {
   public:
-    using Callback = std::function<void(Child& source, const siginfo_t* si)>;
+    using Callback =
+        fu2::unique_function<void(Child& source, const siginfo_t* si)>;
 
     /** @brief Adds a new child source handler to the Event
      *         This type of source defaults to Enabled::Oneshot, and needs to be
@@ -51,7 +52,7 @@
      *
      *  @return A reference to the callback
      */
-    const Callback& get_callback() const;
+    Callback& get_callback();
 
     /** @brief Creates a new child source attached to the Event
      *
diff --git a/src/sdeventplus/source/event.cpp b/src/sdeventplus/source/event.cpp
index b64ef64..b65322d 100644
--- a/src/sdeventplus/source/event.cpp
+++ b/src/sdeventplus/source/event.cpp
@@ -20,7 +20,7 @@
 {
 }
 
-const EventBase::Callback& EventBase::get_callback() const
+EventBase::Callback& EventBase::get_callback()
 {
     return callback;
 }
diff --git a/src/sdeventplus/source/event.hpp b/src/sdeventplus/source/event.hpp
index c384364..a2ee939 100644
--- a/src/sdeventplus/source/event.hpp
+++ b/src/sdeventplus/source/event.hpp
@@ -1,6 +1,6 @@
 #pragma once
 
-#include <functional>
+#include <function2/function2.hpp>
 #include <sdeventplus/internal/sdevent.hpp>
 #include <sdeventplus/source/base.hpp>
 #include <systemd/sd-event.h>
@@ -19,7 +19,7 @@
 class EventBase : public Base
 {
   public:
-    using Callback = std::function<void(EventBase& source)>;
+    using Callback = fu2::unique_function<void(EventBase& source)>;
 
     /** @brief Sets the callback
      *
@@ -50,7 +50,7 @@
      *
      *  @return A reference to the callback
      */
-    const Callback& get_callback() const;
+    Callback& get_callback();
 
     /** @brief Creates a new source attached to the Event
      *
diff --git a/src/sdeventplus/source/io.cpp b/src/sdeventplus/source/io.cpp
index 50e0bbf..9bd4005 100644
--- a/src/sdeventplus/source/io.cpp
+++ b/src/sdeventplus/source/io.cpp
@@ -59,7 +59,7 @@
     return revents;
 }
 
-const IO::Callback& IO::get_callback() const
+IO::Callback& IO::get_callback()
 {
     return callback;
 }
diff --git a/src/sdeventplus/source/io.hpp b/src/sdeventplus/source/io.hpp
index b35500e..409a1fe 100644
--- a/src/sdeventplus/source/io.hpp
+++ b/src/sdeventplus/source/io.hpp
@@ -1,7 +1,7 @@
 #pragma once
 
 #include <cstdint>
-#include <functional>
+#include <function2/function2.hpp>
 #include <sdeventplus/source/base.hpp>
 #include <systemd/sd-event.h>
 
@@ -17,7 +17,7 @@
 class IO : public Base
 {
   public:
-    using Callback = std::function<void(IO&, int fd, uint32_t revents)>;
+    using Callback = fu2::unique_function<void(IO&, int fd, uint32_t revents)>;
 
     /** @brief Adds a new IO source handler to the Event
      *         This type of source defaults to Enabled::On, executing the
@@ -83,7 +83,7 @@
      *
      *  @return A reference to the callback
      */
-    const Callback& get_callback() const;
+    Callback& get_callback();
 
     /** @brief Creates a new IO source attached to the Event
      *
diff --git a/src/sdeventplus/source/signal.cpp b/src/sdeventplus/source/signal.cpp
index dc39023..a433cb4 100644
--- a/src/sdeventplus/source/signal.cpp
+++ b/src/sdeventplus/source/signal.cpp
@@ -27,7 +27,7 @@
                                event.getSdEvent(), get());
 }
 
-const Signal::Callback& Signal::get_callback() const
+Signal::Callback& Signal::get_callback()
 {
     return callback;
 }
diff --git a/src/sdeventplus/source/signal.hpp b/src/sdeventplus/source/signal.hpp
index f62db44..08c0eff 100644
--- a/src/sdeventplus/source/signal.hpp
+++ b/src/sdeventplus/source/signal.hpp
@@ -1,6 +1,6 @@
 #pragma once
 
-#include <functional>
+#include <function2/function2.hpp>
 #include <sdeventplus/event.hpp>
 #include <sdeventplus/source/base.hpp>
 #include <sys/signalfd.h>
@@ -18,8 +18,8 @@
 {
   public:
     /** @brief Type of the user provided callback function */
-    using Callback =
-        std::function<void(Signal& source, const struct signalfd_siginfo* si)>;
+    using Callback = fu2::unique_function<void(
+        Signal& source, const struct signalfd_siginfo* si)>;
 
     /** @brief Creates a new signal event source on the provided event loop
      *         This type of source defaults to Enabled::On, executing the
@@ -53,7 +53,7 @@
      *
      *  @return A reference to the callback
      */
-    const Callback& get_callback() const;
+    Callback& get_callback();
 
     /** @brief Creates a new signal source attached to the Event
      *
diff --git a/src/sdeventplus/source/time.cpp b/src/sdeventplus/source/time.cpp
index 856e65f..0b62f29 100644
--- a/src/sdeventplus/source/time.cpp
+++ b/src/sdeventplus/source/time.cpp
@@ -64,7 +64,7 @@
 }
 
 template <ClockId Id>
-const typename Time<Id>::Callback& Time<Id>::get_callback() const
+typename Time<Id>::Callback& Time<Id>::get_callback()
 {
     return callback;
 }
diff --git a/src/sdeventplus/source/time.hpp b/src/sdeventplus/source/time.hpp
index ef79803..a262588 100644
--- a/src/sdeventplus/source/time.hpp
+++ b/src/sdeventplus/source/time.hpp
@@ -1,7 +1,7 @@
 #pragma once
 
 #include <cstdint>
-#include <functional>
+#include <function2/function2.hpp>
 #include <sdeventplus/clock.hpp>
 #include <sdeventplus/internal/utils.hpp>
 #include <sdeventplus/source/base.hpp>
@@ -25,7 +25,7 @@
     /** @brief Type used to define the accuracy of the time source */
     using Accuracy = SdEventDuration;
     /** @brief Type of the user provided callback function */
-    using Callback = std::function<void(Time& source, TimePoint time)>;
+    using Callback = fu2::unique_function<void(Time& source, TimePoint time)>;
 
     /** @brief Creates a new time event source on the provided event loop
      *         This type of source defaults to Enabled::Oneshot, and needs to be
@@ -81,7 +81,7 @@
      *
      *  @return A reference to the callback
      */
-    const Callback& get_callback() const;
+    Callback& get_callback();
 
     /** @brief Creates a new time source attached to the Event
      *
diff --git a/subprojects/function2.wrap b/subprojects/function2.wrap
new file mode 100644
index 0000000..096a1d2
--- /dev/null
+++ b/subprojects/function2.wrap
@@ -0,0 +1,3 @@
+[wrap-git]
+url = https://github.com/Naios/function2
+revision = master