blob: 4ebb2a3130dd80976ddee385a142f80e07d54973 [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{
40 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)) {}
47
48 /** @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 }
63
64 /** @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 }
79
Brad Bishopb83a21e2016-11-30 13:43:37 -050080 /** @brief Provides a weak reference to the held interface. */
81 T& get()
82 {
83 return _held;
84 }
85
86 /** @brief Provides a weak reference to the held interface. */
87 const T& get() const
88 {
89 return _held;
90 }
91
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
115 virtual Ret operator()(Args&&...args) const = 0;
116 virtual Ret operator()(Args&&...args)
117 {
118 return const_cast<const CallableBase&>(*this)(
119 std::forward<Args>(args)...);
120 }
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;
140 CallableHolder & operator=(const CallableHolder&) = delete;
141 CallableHolder(CallableHolder&&) = default;
142 CallableHolder& operator=(CallableHolder&&) = default;
143 explicit CallableHolder(T&& func) : Holder<T>(std::forward<T>(func)) {}
144
145 virtual Ret operator()(Args&&...args) const override
146 {
147 return this->_held(std::forward<Args>(args)...);
148 }
149
150 virtual Ret operator()(Args&&...args) override
151 {
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