blob: 2dbd3b6b682ac3843dfdff3c0b489708c67a347f [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
80 protected:
81 T _held;
82};
83
84/** @struct CallableBase
85 * @brief Adapt any callable function object base class.
86 *
87 * Provides an un-templated base class for use with an adapt to any
88 * callable function object type.
89 *
90 * @tparam Ret - The return type of the callable.
91 * @tparam Args - The argument types of the callable.
92 */
93template <typename Ret, typename ...Args>
94struct CallableBase
95{
96 CallableBase() = default;
97 virtual ~CallableBase() = default;
98 CallableBase(const CallableBase&) = delete;
99 CallableBase& operator=(const CallableBase&) = delete;
100 CallableBase(CallableBase&&) = default;
101 CallableBase& operator=(CallableBase&&) = default;
102
103 virtual Ret operator()(Args&&...args) const = 0;
104 virtual Ret operator()(Args&&...args)
105 {
106 return const_cast<const CallableBase&>(*this)(
107 std::forward<Args>(args)...);
108 }
109};
110
111/** @struct CallableHolder
112 * @brief Adapt from any callable type.
113 *
114 * Adapts any callable type.
115 *
116 * @tparam T - The type of the callable.
117 * @tparam Ret - The return type of the callable.
118 * @tparam Args - The argument types of the callable.
119 */
120template <typename T, typename Ret, typename ...Args>
121struct CallableHolder final :
122 public CallableBase<Ret, Args...>,
123 public Holder<T>
124{
125 CallableHolder() = delete;
126 ~CallableHolder() = default;
127 CallableHolder(const CallableHolder&) = delete;
128 CallableHolder & operator=(const CallableHolder&) = delete;
129 CallableHolder(CallableHolder&&) = default;
130 CallableHolder& operator=(CallableHolder&&) = default;
131 explicit CallableHolder(T&& func) : Holder<T>(std::forward<T>(func)) {}
132
133 virtual Ret operator()(Args&&...args) const override
134 {
135 return this->_held(std::forward<Args>(args)...);
136 }
137
138 virtual Ret operator()(Args&&...args) override
139 {
140 return this->_held(std::forward<Args>(args)...);
141 }
142};
143
144} // namespace holder
145} // namespace details
146} // namespace manager
147} // namespace inventory
148} // namespace phosphor
149
150// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4