internal/sdref: Remove in favor of stdplus/handle

We no longer need to roll our own managed handle type now that stdplus
implements a generic one.

Tested:
    Built and run through unit tests.

Change-Id: Id34cd8d3ffacf7901d49cac335fa93f744f0e310
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/Makefile.am b/src/Makefile.am
index 9cd7706..40e3c89 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -16,9 +16,6 @@
 nobase_include_HEADERS += sdeventplus/internal/sdevent.hpp
 libsdeventplus_la_SOURCES += sdeventplus/internal/sdevent.cpp
 
-nobase_include_HEADERS += sdeventplus/internal/sdref.hpp
-libsdeventplus_la_SOURCES += sdeventplus/internal/sdref.cpp
-
 nobase_include_HEADERS += sdeventplus/internal/utils.hpp
 
 nobase_include_HEADERS += sdeventplus/source/base.hpp
diff --git a/src/meson.build b/src/meson.build
index eec3218..a7d99cb 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -1,4 +1,5 @@
 libsystemd = dependency('libsystemd')
+stdplus = dependency('stdplus')
 
 sdeventplus = library(
   'sdeventplus',
@@ -7,7 +8,6 @@
     'sdeventplus/event.cpp',
     'sdeventplus/exception.cpp',
     'sdeventplus/internal/sdevent.cpp',
-    'sdeventplus/internal/sdref.cpp',
     'sdeventplus/source/base.cpp',
     'sdeventplus/source/child.cpp',
     'sdeventplus/source/event.cpp',
@@ -19,7 +19,10 @@
   include_directories: includes,
   implicit_include_directories: false,
   version: meson.project_version(),
-  dependencies: libsystemd,
+  dependencies: [
+    libsystemd,
+    stdplus
+  ],
   install: true)
 
 import('pkgconfig').generate(
@@ -37,7 +40,6 @@
 
 install_headers(
   'sdeventplus/internal/sdevent.hpp',
-  'sdeventplus/internal/sdref.hpp',
   'sdeventplus/internal/utils.hpp',
   subdir: 'sdeventplus/internal')
 
diff --git a/src/sdeventplus/event.cpp b/src/sdeventplus/event.cpp
index 946d34c..132dc7f 100644
--- a/src/sdeventplus/event.cpp
+++ b/src/sdeventplus/event.cpp
@@ -9,16 +9,14 @@
 {
 
 Event::Event(sd_event* event, const internal::SdEvent* sdevent) :
-    sdevent(sdevent), event(event, &internal::SdEvent::sd_event_ref,
-                            &internal::SdEvent::sd_event_unref, sdevent)
+    sdevent(sdevent), event(event, sdevent)
 {
 }
 
 Event::Event(sd_event* event, std::false_type,
              const internal::SdEvent* sdevent) :
     sdevent(sdevent),
-    event(event, &internal::SdEvent::sd_event_ref,
-          &internal::SdEvent::sd_event_unref, std::false_type(), sdevent)
+    event(std::move(event), sdevent)
 {
 }
 
@@ -46,7 +44,7 @@
 
 sd_event* Event::get() const
 {
-    return event.get();
+    return event.value();
 }
 
 const internal::SdEvent* Event::getSdEvent() const
@@ -148,4 +146,14 @@
     return r;
 }
 
+sd_event* Event::ref(sd_event* const& event, const internal::SdEvent*& sdevent)
+{
+    return sdevent->sd_event_ref(event);
+}
+
+void Event::drop(sd_event*&& event, const internal::SdEvent*& sdevent)
+{
+    sdevent->sd_event_unref(event);
+}
+
 } // namespace sdeventplus
diff --git a/src/sdeventplus/event.hpp b/src/sdeventplus/event.hpp
index ba7c77d..f234e5c 100644
--- a/src/sdeventplus/event.hpp
+++ b/src/sdeventplus/event.hpp
@@ -2,8 +2,8 @@
 
 #include <optional>
 #include <sdeventplus/internal/sdevent.hpp>
-#include <sdeventplus/internal/sdref.hpp>
 #include <sdeventplus/internal/utils.hpp>
+#include <stdplus/handle/copyable.hpp>
 #include <systemd/sd-event.h>
 
 namespace sdeventplus
@@ -146,8 +146,13 @@
     bool set_watchdog(bool b) const;
 
   private:
+    static sd_event* ref(sd_event* const& event,
+                         const internal::SdEvent*& sdevent);
+    static void drop(sd_event*&& event, const internal::SdEvent*& sdevent);
+
     const internal::SdEvent* sdevent;
-    internal::SdRef<sd_event> event;
+    stdplus::Copyable<sd_event*, const internal::SdEvent*>::Handle<drop, ref>
+        event;
 };
 
 } // namespace sdeventplus
diff --git a/src/sdeventplus/internal/sdref.cpp b/src/sdeventplus/internal/sdref.cpp
deleted file mode 100644
index add6b90..0000000
--- a/src/sdeventplus/internal/sdref.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-#include <sdeventplus/internal/sdref.hpp>
-#include <type_traits>
-#include <utility>
-
-namespace sdeventplus
-{
-namespace internal
-{
-
-template <typename T>
-SdRef<T>::SdRef(T* ref, Func take_ref, Func release_ref,
-                const SdEvent* sdevent) :
-    SdRef(take_ref(sdevent, ref), take_ref, release_ref, std::false_type(),
-          sdevent)
-{
-}
-
-template <typename T>
-SdRef<T>::SdRef(T* ref, Func take_ref, Func release_ref, std::false_type,
-                const SdEvent* sdevent) :
-    sdevent(sdevent),
-    take_ref(take_ref), release_ref(release_ref), ref(ref)
-{
-}
-
-template <typename T>
-SdRef<T>::SdRef(const SdRef& other) :
-    SdRef(other.ref, other.take_ref, other.release_ref, other.sdevent)
-{
-}
-
-template <typename T>
-SdRef<T>& SdRef<T>::operator=(const SdRef& other)
-{
-    if (this != &other)
-    {
-        // release_ref will be invalid if moved
-        if (release_ref)
-        {
-            release_ref(sdevent, ref);
-        }
-
-        sdevent = other.sdevent;
-        take_ref = other.take_ref;
-        release_ref = other.release_ref;
-        ref = take_ref(sdevent, other.ref);
-    }
-    return *this;
-}
-
-template <typename T>
-SdRef<T>::SdRef(SdRef&& other) :
-    sdevent(std::move(other.sdevent)), take_ref(std::move(other.take_ref)),
-    release_ref(std::move(other.release_ref)), ref(std::move(other.ref))
-{
-    other.ref = nullptr;
-}
-
-template <typename T>
-SdRef<T>& SdRef<T>::operator=(SdRef&& other)
-{
-    if (this != &other)
-    {
-        // release_ref will be invalid if move
-        if (release_ref)
-        {
-            release_ref(sdevent, ref);
-        }
-
-        sdevent = std::move(other.sdevent);
-        take_ref = std::move(other.take_ref);
-        release_ref = std::move(other.release_ref);
-        ref = std::move(other.ref);
-        other.ref = nullptr;
-    }
-    return *this;
-}
-
-template <typename T>
-SdRef<T>::~SdRef()
-{
-    // release_ref will be invalid after a move
-    if (release_ref)
-        release_ref(sdevent, ref);
-}
-
-template <typename T>
-SdRef<T>::operator bool() const
-{
-    return ref != nullptr;
-}
-
-template <typename T>
-T* SdRef<T>::get() const
-{
-    return ref;
-}
-
-template class SdRef<sd_event>;
-template class SdRef<sd_event_source>;
-
-} // namespace internal
-} // namespace sdeventplus
diff --git a/src/sdeventplus/internal/sdref.hpp b/src/sdeventplus/internal/sdref.hpp
deleted file mode 100644
index a05eca2..0000000
--- a/src/sdeventplus/internal/sdref.hpp
+++ /dev/null
@@ -1,77 +0,0 @@
-#pragma once
-
-#include <functional>
-#include <sdeventplus/internal/sdevent.hpp>
-#include <type_traits>
-
-namespace sdeventplus
-{
-namespace internal
-{
-
-/** @class SdRef
- *  @brief Takes and releases references to T objects
- *  @details Used primarily as an RAII wrapper around sd_event
- *           and sd_event_source object references.
- */
-template <typename T>
-class SdRef
-{
-  public:
-    /** @brief The type signature of ref / deref functions
-     */
-    using Func = std::function<T*(const SdEvent*, T*)>;
-
-    /** @brief Constructs a new reference holder
-     *         This constructor calls take_ref on ref
-     *
-     *  @param[in] ref         - Object which is referenced
-     *  @param[in] take_ref    - Function used to take references
-     *  @param[im] release_ref - Function used to release references
-     *  @param[in] sdevent     - Optional underlying sd_event implementation
-     */
-    SdRef(T* ref, Func take_ref, Func release_ref,
-          const SdEvent* sdevent = &sdevent_impl);
-
-    /** @brief Constructs a new reference holder
-     *         Does not take a new reference on the passed ref
-     *         NOTE: This will still take a reference during future copies
-     *         Useful for first creation of an object reference
-     *
-     *  @param[in] ref         - Object which is referenced
-     *  @param[in] take_ref    - Function used to take references
-     *  @param[im] release_ref - Function used to release references
-     *  @param[in]             - Denotes no reference taken during construction
-     *  @param[in] sdevent     - Optional underlying sd_event implementation
-     */
-    SdRef(T* ref, Func take_ref, Func release_ref, std::false_type,
-          const SdEvent* sdevent = &sdevent_impl);
-
-    virtual ~SdRef();
-    SdRef(const SdRef& other);
-    SdRef& operator=(const SdRef& other);
-    SdRef(SdRef&& other);
-    SdRef& operator=(SdRef&& other);
-
-    /** @brief Determines if a reference is currently being held
-     *
-     *  @return 'true' if a reference is held
-     *          'false' if empty
-     */
-    explicit operator bool() const;
-
-    /** @brief Get a pointer to the object being referenced
-     *
-     * @return The object pointer
-     */
-    T* get() const;
-
-  private:
-    const SdEvent* sdevent;
-    Func take_ref;
-    Func release_ref;
-    T* ref;
-};
-
-} // namespace internal
-} // namespace sdeventplus
diff --git a/src/sdeventplus/source/base.cpp b/src/sdeventplus/source/base.cpp
index 81ea591..55c2d10 100644
--- a/src/sdeventplus/source/base.cpp
+++ b/src/sdeventplus/source/base.cpp
@@ -20,7 +20,7 @@
 
 sd_event_source* Base::get() const
 {
-    return source.get();
+    return source.value();
 }
 
 const Event& Base::get_event() const
@@ -119,17 +119,13 @@
 }
 
 Base::Base(const Event& event, sd_event_source* source) :
-    event(event),
-    source(source, &internal::SdEvent::sd_event_source_ref,
-           &internal::SdEvent::sd_event_source_unref, event.getSdEvent())
+    event(event), source(source, event.getSdEvent())
 {
     set_userdata();
 }
 
 Base::Base(const Event& event, sd_event_source* source, std::false_type) :
-    event(event), source(source, &internal::SdEvent::sd_event_source_ref,
-                         &internal::SdEvent::sd_event_source_unref,
-                         std::false_type(), event.getSdEvent())
+    event(event), source(std::move(source), event.getSdEvent())
 {
     set_userdata();
 }
@@ -161,6 +157,17 @@
     return *this;
 }
 
+sd_event_source* Base::ref(sd_event_source* const& source,
+                           const internal::SdEvent*& sdevent)
+{
+    return sdevent->sd_event_source_ref(source);
+}
+
+void Base::drop(sd_event_source*&& source, const internal::SdEvent*& sdevent)
+{
+    sdevent->sd_event_source_unref(source);
+}
+
 int Base::prepareCallback(sd_event_source* source, void* userdata)
 {
     return sourceCallback<Callback, Base, &Base::get_prepare>("prepareCallback",
diff --git a/src/sdeventplus/source/base.hpp b/src/sdeventplus/source/base.hpp
index 33b37d7..c14ad7f 100644
--- a/src/sdeventplus/source/base.hpp
+++ b/src/sdeventplus/source/base.hpp
@@ -5,8 +5,8 @@
 #include <cstdio>
 #include <functional>
 #include <sdeventplus/event.hpp>
-#include <sdeventplus/internal/sdref.hpp>
 #include <sdeventplus/internal/utils.hpp>
+#include <stdplus/handle/copyable.hpp>
 #include <systemd/sd-bus.h>
 #include <type_traits>
 
@@ -112,7 +112,6 @@
 
   protected:
     Event event;
-    internal::SdRef<sd_event_source> source;
 
     /** @brief Constructs a basic event source wrapper
      *         Adds a reference to the source
@@ -175,6 +174,14 @@
     }
 
   private:
+    static sd_event_source* ref(sd_event_source* const& source,
+                                const internal::SdEvent*& sdevent);
+    static void drop(sd_event_source*&& source,
+                     const internal::SdEvent*& sdevent);
+
+    stdplus::Copyable<sd_event_source*, const internal::SdEvent*>::Handle<drop,
+                                                                          ref>
+        source;
     Callback prepare;
 
     /** @brief A helper used to make sure the userdata for the sd-event