Removed duplicated Holder adapters

Refactor copy/pasted action/filter/interface object
adapter types into a single templated framework.

Change-Id: Iafbd814572a7db13fddc5314617e310fe5f0a062
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
diff --git a/actions.hpp b/actions.hpp
index ff08019..0966ee4 100644
--- a/actions.hpp
+++ b/actions.hpp
@@ -2,6 +2,7 @@
 
 #include <utility>
 #include <memory>
+#include "utils.hpp"
 
 namespace phosphor
 {
@@ -9,106 +10,34 @@
 {
 namespace manager
 {
+
 class Manager;
+namespace details
+{
+using ActionBase = holder::CallableBase<void, Manager&>;
+using ActionBasePtr = std::shared_ptr<ActionBase>;
+template <typename T>
+using Action = holder::CallableHolder<T, void, Manager&>;
+
+/** @brief make_action
+ *
+ *  Adapt an action function object.
+ *
+ *  @param[in] action - The action being adapted.
+ *  @returns - The adapted action.
+ *
+ *  @tparam T - The type of the action being adapted.
+ */
+template <typename T>
+auto make_action(T&& action)
+{
+    return Action<T>::template make_shared<Action<T>>(
+        std::forward<T>(action));
+}
+} // namespace details
 
 namespace actions
 {
-namespace details
-{
-namespace holder
-{
-
-/** @struct Base
- *  @brief Event action functor holder base.
- *
- *  Provides an un-templated holder for actionsof any type with the correct
- *  function call signature.
- */
-struct Base
-{
-    Base() = default;
-    virtual ~Base() = default;
-    Base(const Base&) = delete;
-    Base& operator=(const Base&) = delete;
-    Base(Base&&) = default;
-    Base& operator=(Base&&) = default;
-
-    virtual void operator()(Manager &mgr) const = 0;
-    virtual void operator()(Manager &mgr)
-    {
-        const_cast<const Base &>(*this)(mgr);
-    }
-};
-
-/** @struct Holder
- *  @brief Event action functor holder.
- *
- *  Adapts a functor of any type (with the correct function call
- *  signature) to a non-templated type usable by the manager for
- *  actions.
- *
- *  @tparam T - The functor type.
- */
-template <typename T>
-struct Holder final : public Base
-{
-    Holder() = delete;
-    ~Holder() = default;
-    Holder(const Holder&) = delete;
-    Holder & operator=(const Holder&) = delete;
-    Holder(Holder&&) = default;
-    Holder& operator=(Holder&&) = default;
-    explicit Holder(T &&func) : _func(std::forward<T>(func)) {}
-
-    virtual void operator()(Manager &mgr) const override
-    {
-        _func(mgr);
-    }
-
-    virtual void operator()(Manager &mgr) override
-    {
-        _func(mgr);
-    }
-
-    private:
-    T _func;
-};
-
-} // namespace holder
-
-/** @struct Wrapper
- *  @brief Provides implicit type conversion from action functors.
- *
- *  Converts action functors to ptr-to-holder.
- */
-struct Wrapper
-{
-    template <typename T>
-    Wrapper(T &&func) :
-        _ptr(static_cast<std::shared_ptr<holder::Base>>(
-                    std::make_shared<holder::Holder<T>>(
-                        std::forward<T>(func)))) { }
-
-    ~Wrapper() = default;
-    Wrapper(const Wrapper&) = default;
-    Wrapper& operator=(const Wrapper&) = delete;
-    Wrapper(Wrapper&&) = default;
-    Wrapper& operator=(Wrapper&&) = default;
-
-    void operator()(Manager &mgr)
-    {
-        (*_ptr)(mgr);
-    }
-    void operator()(Manager &mgr) const
-    {
-        (*_ptr)(mgr);
-    }
-
-    private:
-    std::shared_ptr<holder::Base> _ptr;
-};
-
-} // namespace details
 
 /** @brief The default action.  */
 inline void noop(Manager &mgr) noexcept { }
diff --git a/filters.hpp b/filters.hpp
index 2a3da48..e2a87e3 100644
--- a/filters.hpp
+++ b/filters.hpp
@@ -3,6 +3,7 @@
 #include <utility>
 #include <memory>
 #include <sdbusplus/message.hpp>
+#include "utils.hpp"
 
 namespace phosphor
 {
@@ -12,104 +13,36 @@
 {
 
 class Manager;
+namespace details
+{
+using FilterBase = holder::CallableBase<
+    bool, sdbusplus::message::message&, Manager&>;
+using FilterBasePtr = std::shared_ptr<FilterBase>;
+template <typename T>
+using Filter = holder::CallableHolder<
+    T, bool, sdbusplus::message::message&, Manager&>;
+
+/** @brief make_filter
+ *
+ *  Adapt a filter function object.
+ *
+ *  @param[in] filter - The filter being adapted.
+ *  @returns - The adapted filter.
+ *
+ *  @tparam T - The type of the filter being adapted.
+ */
+template <typename T>
+auto make_filter(T&& filter)
+{
+    return Filter<T>::template make_shared<Filter<T>>(
+        std::forward<T>(filter));
+}
+} // namespace details
+
 namespace filters
 {
 namespace details
 {
-namespace holder
-{
-
-/** @struct Base
- *  @brief Match event filter functor holder base.
- *
- *  Provides an un-templated holder for filters of any type with the correct
- *  function call signature.
- */
-struct Base
-{
-    Base() = default;
-    virtual ~Base() = default;
-    Base(const Base&) = delete;
-    Base& operator=(const Base&) = delete;
-    Base(Base&&) = default;
-    Base& operator=(Base&&) = default;
-
-    virtual bool operator()(sdbusplus::message::message &, Manager &) const = 0;
-    virtual bool operator()(sdbusplus::message::message &msg, Manager &mgr)
-    {
-        return const_cast<const Base &>(*this)(msg, mgr);
-    }
-};
-
-/** @struct Holder
- *  @brief Match event filter functor holder.
- *
- *  Adapts a functor of any type (with the correct function call
- *  signature) to a non-templated type usable by the manager for
- *  filtering.
- *
- *  @tparam T - The functor type.
- */
-template <typename T>
-struct Holder final : public Base
-{
-    Holder() = delete;
-    ~Holder() = default;
-    Holder(const Holder&) = delete;
-    Holder & operator=(const Holder&) = delete;
-    Holder(Holder&&) = default;
-    Holder& operator=(Holder&&) = default;
-    explicit Holder(T &&func) : _func(std::forward<T>(func)) { }
-
-    virtual bool operator()(
-            sdbusplus::message::message &msg, Manager &mgr) const override
-    {
-        return _func(msg, mgr);
-    }
-
-    virtual bool operator()(
-            sdbusplus::message::message &msg, Manager &mgr) override
-    {
-        return _func(msg, mgr);
-    }
-
-    private:
-    T _func;
-};
-
-} // namespace holder
-
-/** @struct Wrapper
- *  @brief Provides implicit type conversion from filter functors.
- *
- *  Converts filter functors to ptr-to-holder.
- */
-struct Wrapper
-{
-    template <typename T>
-    Wrapper(T &&func) :
-        _ptr(std::shared_ptr<holder::Base>(
-                    new holder::Holder<T>(std::forward<T>(func)))) { }
-
-    ~Wrapper() = default;
-    Wrapper(const Wrapper&) = default;
-    Wrapper& operator=(const Wrapper&) = delete;
-    Wrapper(Wrapper&&) = default;
-    Wrapper& operator=(Wrapper&&) = default;
-
-    bool operator()(sdbusplus::message::message &msg, Manager &mgr)
-    {
-        return (*_ptr)(msg, mgr);
-    }
-    bool operator()(sdbusplus::message::message &msg, Manager &mgr) const
-    {
-        return (*_ptr)(msg, mgr);
-    }
-
-    private:
-    std::shared_ptr<holder::Base> _ptr;
-};
-
 namespace property_condition
 {
 
diff --git a/generated.mako.cpp b/generated.mako.cpp
index e1925a2..984f00b 100644
--- a/generated.mako.cpp
+++ b/generated.mako.cpp
@@ -8,6 +8,7 @@
         return '::'.join(lst)
 %>
 #include "manager.hpp"
+#include "utils.hpp"
 % for i in interfaces:
 #include <${'/'.join(i.split('.') + ['server.hpp'])}>
 % endfor
@@ -23,7 +24,7 @@
 % for i in interfaces:
     {
         "${i}",
-        details::interface::holder::Holder<
+        details::MakeInterface<
             details::ServerObject<
                 sdbusplus::${interface_type(i)}>>::make,
     },
@@ -46,28 +47,28 @@
             % endif
         % endfor
             % if e['filter'].get('args'):
-            filters::${e['filter']['type']}(
+            details::make_filter(filters::${e['filter']['type']}(
                 % for i, a in enumerate(e['filter']['args']):
                     % if i + 1 == len(e['filter']['args']):
-                "${a['value']}"),
+                "${a['value']}")),
                     % else:
                 "${a['value']}",
                     % endif
                 % endfor
             % else:
-            filters::${e['filter']['type']},
+            details::make_filter(filters::${e['filter']['type']}),
             % endif
             % if e['action'].get('args'):
-            actions::${e['action']['type']}(
+            details::make_action(actions::${e['action']['type']}(
                 % for i, a in enumerate(e['action']['args']):
                     % if i + 1 == len(e['action']['args']):
-                "${a['value']}")
+                "${a['value']}"))
                     % else:
                 "${a['value']}",
                     % endif
                 % endfor
             % else:
-            actions::${e['action']['type']}
+            details::make_action(actions::${e['action']['type']})
             % endif
         ),
     },
diff --git a/manager.cpp b/manager.cpp
index c62c288..b7a1634 100644
--- a/manager.cpp
+++ b/manager.cpp
@@ -144,8 +144,8 @@
 
 void Manager::signal(sdbusplus::message::message &msg, auto &args)
 {
-    auto &filter = std::get<1>(args);
-    auto &action = std::get<2>(args);
+    auto &filter = *std::get<1>(args);
+    auto &action = *std::get<2>(args);
 
     if(filter(msg, *this)) {
         action(*this);
diff --git a/manager.hpp b/manager.hpp
index 31ced21..47bd8b1 100644
--- a/manager.hpp
+++ b/manager.hpp
@@ -17,67 +17,6 @@
 {
 namespace details
 {
-namespace interface
-{
-namespace holder
-{
-
-/** @struct Base
- *  @brief sdbusplus server interface holder base.
- *
- *  Provides a common type for assembling containers of sdbusplus server
- *  interfaces.  Typically a multiple inheritance scheme (sdbusplus::object)
- *  would be used for this; however, for objects created by PIM the interfaces
- *  are not known at build time.
- */
-struct Base
-{
-    Base() = default;
-    virtual ~Base() = default;
-    Base(const Base&) = delete;
-    Base& operator=(const Base&) = delete;
-    Base(Base&&) = default;
-    Base& operator=(Base&&) = default;
-};
-
-/** @struct Holder
- *  @brief sdbusplus server interface holder.
- *
- *  Holds a pointer to an sdbusplus server interface instance.
- *
- *  @tparam T - The sdbusplus server interface type to hold.
- */
-template <typename T>
-struct Holder final : public Base
-{
-    Holder() = delete;
-    ~Holder() = default;
-    Holder(const Holder&) = delete;
-    Holder& operator=(const Holder&) = delete;
-    Holder(Holder&&) = default;
-    Holder& operator=(Holder&&) = default;
-    explicit Holder(auto &&ptr) noexcept : _ptr(std::move(ptr)) {}
-
-    /** @brief sdbusplus server interface holder factory method.
-     *
-     *  @param bus[in] - An sdbusplus bus connection
-     *  @param bus[in] - The path of the object for which
-     *          an interface is to be held.
-     *  @returns A held interface.
-     */
-    static auto make(sdbusplus::bus::bus &bus, const char *path)
-    {
-        return static_cast<std::unique_ptr<Base>>(
-                std::make_unique<Holder<T>>(
-                    std::make_unique<T>(bus, path)));
-    }
-
-    private:
-    std::unique_ptr<T> _ptr;
-};
-
-} // namespace holder
-} // namespace interface
 
 template <typename T>
 using ServerObject = typename sdbusplus::server::object::object<T>;
@@ -85,6 +24,28 @@
 using ManagerIface =
     sdbusplus::server::xyz::openbmc_project::Inventory::Manager;
 
+/** @struct MakeInterface
+ *  @brief Adapt an sdbusplus interface proxy.
+ *
+ *  Template instances are builder functions that create
+ *  adapted sdbusplus interface proxy interface objects.
+ *
+ *  @tparam T - The type of the interface being adapted.
+ */
+template <typename T>
+struct MakeInterface
+{
+    static decltype(auto) make(sdbusplus::bus::bus &bus, const char *path)
+    {
+        using HolderType = holder::Holder<std::unique_ptr<T>>;
+        return static_cast<std::unique_ptr<holder::Base>>(
+            HolderType::template make_unique<HolderType>(
+                std::forward<std::unique_ptr<T>>(
+                    std::make_unique<T>(
+                        std::forward<decltype(bus)>(bus),
+                        std::forward<decltype(path)>(path)))));
+    }
+};
 } // namespace details
 
 /** @class Manager
@@ -135,8 +96,8 @@
 
     using Event = std::tuple<
         const char *,
-        filters::details::Wrapper,
-        actions::details::Wrapper>;
+        details::FilterBasePtr,
+        details::ActionBasePtr>;
     using SigArgs = std::vector<
         std::unique_ptr<
             std::tuple<
@@ -145,8 +106,7 @@
     using SigArg = SigArgs::value_type::element_type;
 
     private:
-    using Holder = details::interface::holder::Base;
-    using HolderPtr = std::unique_ptr<Holder>;
+    using HolderPtr = std::unique_ptr<details::holder::Base>;
     using InterfaceComposite = std::map<std::string, HolderPtr>;
     using ObjectReferences = std::map<std::string, InterfaceComposite>;
     using Events = std::map<const char *, Event>;
diff --git a/utils.hpp b/utils.hpp
new file mode 100644
index 0000000..2dbd3b6
--- /dev/null
+++ b/utils.hpp
@@ -0,0 +1,150 @@
+#pragma once
+
+namespace phosphor
+{
+namespace inventory
+{
+namespace manager
+{
+namespace details
+{
+namespace holder
+{
+
+/** @struct Base
+ *  @brief Adapt from any type base class.
+ *
+ *  Provides an un-templated base class for use with an adapt to any type
+ *  adapter to enable containers of mixed types.
+ */
+struct Base
+{
+    Base() = default;
+    virtual ~Base() = default;
+    Base(const Base&) = delete;
+    Base& operator=(const Base&) = delete;
+    Base(Base&&) = default;
+    Base& operator=(Base&&) = default;
+};
+
+/** @struct Holder
+ *  @brief Adapt from any type.
+ *
+ *  Adapts any type to enable containers of mixed types.
+ *
+ *  @tparam T - The adapted type.
+ */
+template <typename T>
+struct Holder : public Base
+{
+    Holder() = delete;
+    virtual ~Holder() = default;
+    Holder(const Holder&) = delete;
+    Holder & operator=(const Holder&) = delete;
+    Holder(Holder&&) = default;
+    Holder& operator=(Holder&&) = default;
+    explicit Holder(T&& held) : _held(std::forward<T>(held)) {}
+
+    /** @brief Construct an adapter.
+     *
+     *  @param[in] held - The object to be adapted.
+     *
+     *  @returns - std::unique pointer to the adapted object.
+     *
+     *  @tparam Ret - The type of the pointer to be returned.
+     *  @tparam Held - The type of the object to be adapted.
+     */
+    template <typename Ret, typename Held>
+    static auto make_unique(Held&& held)
+    {
+        return std::make_unique<Ret>(
+                std::forward<Held>(held));
+    }
+
+    /** @brief Construct an adapter.
+     *
+     *  @param[in] held - The object to be adapted.
+     *
+     *  @returns - std::shared pointer to the adapted object.
+     *
+     *  @tparam Ret - The type of the pointer to be returned.
+     *  @tparam Held - The type of the object to be adapted.
+     */
+    template <typename Ret, typename Held>
+    static auto make_shared(Held&& held)
+    {
+        return std::make_shared<Ret>(
+                std::forward<Held>(held));
+    }
+
+    protected:
+        T _held;
+};
+
+/** @struct CallableBase
+ *  @brief Adapt any callable function object base class.
+ *
+ *  Provides an un-templated base class for use with an adapt to any
+ *  callable function object type.
+ *
+ *  @tparam Ret - The return type of the callable.
+ *  @tparam Args - The argument types of the callable.
+ */
+template <typename Ret, typename ...Args>
+struct CallableBase
+{
+    CallableBase() = default;
+    virtual ~CallableBase() = default;
+    CallableBase(const CallableBase&) = delete;
+    CallableBase& operator=(const CallableBase&) = delete;
+    CallableBase(CallableBase&&) = default;
+    CallableBase& operator=(CallableBase&&) = default;
+
+    virtual Ret operator()(Args&&...args) const = 0;
+    virtual Ret operator()(Args&&...args)
+    {
+        return const_cast<const CallableBase&>(*this)(
+                std::forward<Args>(args)...);
+    }
+};
+
+/** @struct CallableHolder
+ *  @brief Adapt from any callable type.
+ *
+ *  Adapts any callable type.
+ *
+ *  @tparam T - The type of the callable.
+ *  @tparam Ret - The return type of the callable.
+ *  @tparam Args - The argument types of the callable.
+ */
+template <typename T, typename Ret, typename ...Args>
+struct CallableHolder final :
+    public CallableBase<Ret, Args...>,
+    public Holder<T>
+{
+    CallableHolder() = delete;
+    ~CallableHolder() = default;
+    CallableHolder(const CallableHolder&) = delete;
+    CallableHolder & operator=(const CallableHolder&) = delete;
+    CallableHolder(CallableHolder&&) = default;
+    CallableHolder& operator=(CallableHolder&&) = default;
+    explicit CallableHolder(T&& func) : Holder<T>(std::forward<T>(func)) {}
+
+    virtual Ret operator()(Args&&...args) const override
+    {
+        return this->_held(std::forward<Args>(args)...);
+    }
+
+    virtual Ret operator()(Args&&...args) override
+    {
+        return this->_held(std::forward<Args>(args)...);
+    }
+};
+
+} // namespace holder
+} // namespace details
+} // namespace manager
+} // namespace inventory
+} // namespace phosphor
+
+// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4