/* * Copyright (c) Atmosphère-NX * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include #include #include namespace ams::tipc { namespace impl { template class EmplacedImplHolderBaseGetter { public: using Type = Impl; }; template class EmplacedImplHolder { template friend class impl::ImplTemplateBaseT; private: using Impl2 = typename EmplacedImplHolderBaseGetter::Type; static_assert(!std::is_abstract::value); private: Impl2 m_impl; private: template constexpr explicit EmplacedImplHolder(Args &&... args) : m_impl(std::forward(args)...) { /* ... */ } public: static constexpr Impl *GetImplPointer(EmplacedImplHolder *holder) { return std::addressof(holder->m_impl); } }; } template class ServiceObject final : public impl::ImplTemplateBase, impl::EmplacedImplHolder> { private: using ImplBase = impl::ImplTemplateBase, impl::EmplacedImplHolder>; public: using ImplBase::ImplBase; constexpr Impl &GetImpl() { return *impl::EmplacedImplHolder::GetImplPointer(this); } }; }