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