blob: 1ea7fc1ca84d736f5113657123f1e21a84bd0119 [file] [log] [blame]
Brad Bishop65ffffa2016-11-29 12:31:31 -05001#pragma once
2
3namespace phosphor
4{
5namespace inventory
6{
7namespace manager
8{
9namespace details
10{
11namespace holder
12{
13
14/** @struct Base
15 * @brief Adapt from any type base class.
16 *
17 * Provides an un-templated base class for use with an adapt to any type
18 * adapter to enable containers of mixed types.
19 */
20struct Base
21{
22 Base() = default;
23 virtual ~Base() = default;
24 Base(const Base&) = delete;
25 Base& operator=(const Base&) = delete;
26 Base(Base&&) = default;
27 Base& operator=(Base&&) = default;
28};
29
30/** @struct Holder
31 * @brief Adapt from any type.
32 *
33 * Adapts any type to enable containers of mixed types.
34 *
35 * @tparam T - The adapted type.
36 */
37template <typename T>
38struct Holder : public Base
39{
Brad Bishop7b337772017-01-12 16:11:24 -050040 Holder() = delete;
41 virtual ~Holder() = default;
42 Holder(const Holder&) = delete;
43 Holder& operator=(const Holder&) = delete;
44 Holder(Holder&&) = default;
45 Holder& operator=(Holder&&) = default;
46 explicit Holder(T&& held) : _held(std::forward<T>(held)) {}
Brad Bishop65ffffa2016-11-29 12:31:31 -050047
Brad Bishop7b337772017-01-12 16:11:24 -050048 /** @brief Construct an adapter.
49 *
50 * @param[in] held - The object to be adapted.
51 *
52 * @returns - std::unique pointer to the adapted object.
53 *
54 * @tparam Ret - The type of the pointer to be returned.
55 * @tparam Held - The type of the object to be adapted.
56 */
57 template <typename Ret, typename Held>
58 static auto make_unique(Held&& held)
59 {
60 return std::make_unique<Ret>(
61 std::forward<Held>(held));
62 }
Brad Bishop65ffffa2016-11-29 12:31:31 -050063
Brad Bishop7b337772017-01-12 16:11:24 -050064 /** @brief Construct an adapter.
65 *
66 * @param[in] held - The object to be adapted.
67 *
68 * @returns - std::shared pointer to the adapted object.
69 *
70 * @tparam Ret - The type of the pointer to be returned.
71 * @tparam Held - The type of the object to be adapted.
72 */
73 template <typename Ret, typename Held>
74 static auto make_shared(Held&& held)
75 {
76 return std::make_shared<Ret>(
77 std::forward<Held>(held));
78 }
Brad Bishop65ffffa2016-11-29 12:31:31 -050079
Brad Bishop7b337772017-01-12 16:11:24 -050080 /** @brief Provides a weak reference to the held interface. */
81 T& get()
82 {
83 return _held;
84 }
Brad Bishopb83a21e2016-11-30 13:43:37 -050085
Brad Bishop7b337772017-01-12 16:11:24 -050086 /** @brief Provides a weak reference to the held interface. */
87 const T& get() const
88 {
89 return _held;
90 }
Brad Bishopb83a21e2016-11-30 13:43:37 -050091
Brad Bishop65ffffa2016-11-29 12:31:31 -050092 protected:
93 T _held;
94};
95
96/** @struct CallableBase
97 * @brief Adapt any callable function object base class.
98 *
99 * Provides an un-templated base class for use with an adapt to any
100 * callable function object type.
101 *
102 * @tparam Ret - The return type of the callable.
103 * @tparam Args - The argument types of the callable.
104 */
105template <typename Ret, typename ...Args>
106struct CallableBase
107{
108 CallableBase() = default;
109 virtual ~CallableBase() = default;
110 CallableBase(const CallableBase&) = delete;
111 CallableBase& operator=(const CallableBase&) = delete;
112 CallableBase(CallableBase&&) = default;
113 CallableBase& operator=(CallableBase&&) = default;
114
Brad Bishop7b337772017-01-12 16:11:24 -0500115 virtual Ret operator()(Args&& ...args) const = 0;
116 virtual Ret operator()(Args&& ...args)
Brad Bishop65ffffa2016-11-29 12:31:31 -0500117 {
118 return const_cast<const CallableBase&>(*this)(
Brad Bishop7b337772017-01-12 16:11:24 -0500119 std::forward<Args>(args)...);
Brad Bishop65ffffa2016-11-29 12:31:31 -0500120 }
121};
122
123/** @struct CallableHolder
124 * @brief Adapt from any callable type.
125 *
126 * Adapts any callable type.
127 *
128 * @tparam T - The type of the callable.
129 * @tparam Ret - The return type of the callable.
130 * @tparam Args - The argument types of the callable.
131 */
132template <typename T, typename Ret, typename ...Args>
133struct CallableHolder final :
134 public CallableBase<Ret, Args...>,
135 public Holder<T>
136{
137 CallableHolder() = delete;
138 ~CallableHolder() = default;
139 CallableHolder(const CallableHolder&) = delete;
Brad Bishop7b337772017-01-12 16:11:24 -0500140 CallableHolder& operator=(const CallableHolder&) = delete;
Brad Bishop65ffffa2016-11-29 12:31:31 -0500141 CallableHolder(CallableHolder&&) = default;
142 CallableHolder& operator=(CallableHolder&&) = default;
143 explicit CallableHolder(T&& func) : Holder<T>(std::forward<T>(func)) {}
144
Brad Bishop7b337772017-01-12 16:11:24 -0500145 virtual Ret operator()(Args&& ...args) const override
Brad Bishop65ffffa2016-11-29 12:31:31 -0500146 {
147 return this->_held(std::forward<Args>(args)...);
148 }
149
Brad Bishop7b337772017-01-12 16:11:24 -0500150 virtual Ret operator()(Args&& ...args) override
Brad Bishop65ffffa2016-11-29 12:31:31 -0500151 {
152 return this->_held(std::forward<Args>(args)...);
153 }
154};
155
156} // namespace holder
157} // namespace details
158} // namespace manager
159} // namespace inventory
160} // namespace phosphor
161
162// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4