#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
