blob: 2dbd3b6b682ac3843dfdff3c0b489708c67a347f [file] [log] [blame]
#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