From 2d9f5b6942b5cb48e3dfc2802adeaf29e8ddbc55 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 8 Jul 2020 15:07:40 -0700 Subject: [PATCH] sf: support service objects which must themselves be shared pointers --- .../sf/impl/sf_impl_service_object_macros.hpp | 34 +++++++++++++++++++ .../stratosphere/sf/sf_service_object.hpp | 9 ++++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/libraries/libstratosphere/include/stratosphere/sf/impl/sf_impl_service_object_macros.hpp b/libraries/libstratosphere/include/stratosphere/sf/impl/sf_impl_service_object_macros.hpp index 2d251f58a..fa1b2feb3 100644 --- a/libraries/libstratosphere/include/stratosphere/sf/impl/sf_impl_service_object_macros.hpp +++ b/libraries/libstratosphere/include/stratosphere/sf/impl/sf_impl_service_object_macros.hpp @@ -125,6 +125,13 @@ namespace ams::sf::impl { return static_cast(_this)->NAME(std::forward(args)...); \ } + #define AMS_SF_IMPL_DECLARE_INTERFACE_FUNCTION_INVOKER_SHARED_POINTER(CLASSNAME, CMD_ID, RETURN, NAME, ARGS, VERSION_MIN, VERSION_MAX) \ + template \ + requires std::same_as, AMS_SF_IMPL_HELPER_FUNCTION_ARGS(CLASSNAME, NAME)> \ + static RETURN NAME##Invoker (CLASSNAME *_this, Arguments &&... args) { \ + return static_cast(_this)->NAME(std::forward(args)...); \ + } + #define AMS_SF_IMPL_DECLARE_INTERFACE_FUNCTION_IMPL(CLASSNAME, CMD_ID, RETURN, NAME, ARGS, VERSION_MIN, VERSION_MAX) \ template \ requires (std::same_as, AMS_SF_IMPL_HELPER_FUNCTION_ARGS(CLASSNAME, NAME)> && \ @@ -241,6 +248,29 @@ namespace ams::sf::impl { static constexpr CommandPointerTable CommandPointerTableImpl = { \ CMD_MACRO(CLASSNAME, AMS_SF_IMPL_DEFINE_INTERFACE_COMMAND_POINTER_TABLE_MEMBER) \ }; \ + }; \ + \ + class ImplSharedPointer : public S { \ + private: \ + std::shared_ptr impl; \ + public: \ + constexpr ImplSharedPointer(std::shared_ptr &&t) \ + : S(std::addressof(CommandPointerTableImpl)), impl(std::move(t)) \ + { \ + /* ... */ \ + } \ + ALWAYS_INLINE T &GetImpl() { return *this->impl; } \ + ALWAYS_INLINE const T &GetImpl() const { return *this->impl; } \ + private: \ + CMD_MACRO(CLASSNAME, AMS_SF_IMPL_DECLARE_INTERFACE_FUNCTION_INVOKER_SHARED_POINTER) \ + public: \ + CMD_MACRO(CLASSNAME, AMS_SF_IMPL_DECLARE_INTERFACE_FUNCTION_IMPL_PTR) \ + private: \ + CMD_MACRO(CLASSNAME, AMS_SF_IMPL_DEFINE_INTERFACE_IMPL_FUNCTION_POINTER_HOLDER) \ + public: \ + static constexpr CommandPointerTable CommandPointerTableImpl = { \ + CMD_MACRO(CLASSNAME, AMS_SF_IMPL_DEFINE_INTERFACE_COMMAND_POINTER_TABLE_MEMBER) \ + }; \ }; \ static_assert(Is##CLASSNAME); \ }; \ @@ -253,6 +283,10 @@ namespace ams::sf::impl { template requires (!std::same_as&& Is##CLASSNAME) \ using ImplPointer = typename ImplGenerator::ImplPointer; \ \ + template requires (!std::same_as&& Is##CLASSNAME && \ + std::derived_from>) \ + using ImplSharedPointer = typename ImplGenerator::ImplSharedPointer; \ + \ AMS_SF_CMIF_IMPL_DEFINE_SERVICE_DISPATCH_TABLE { \ CMD_MACRO(CLASSNAME, AMS_SF_IMPL_DEFINE_CMIF_SERVICE_COMMAND_META_TABLE_ENTRY) \ }; \ diff --git a/libraries/libstratosphere/include/stratosphere/sf/sf_service_object.hpp b/libraries/libstratosphere/include/stratosphere/sf/sf_service_object.hpp index 7406be541..bee400c81 100644 --- a/libraries/libstratosphere/include/stratosphere/sf/sf_service_object.hpp +++ b/libraries/libstratosphere/include/stratosphere/sf/sf_service_object.hpp @@ -50,11 +50,18 @@ namespace ams::sf { { T::ShouldMitm(c) } -> std::same_as; }; - template requires std::constructible_from + template + requires std::constructible_from constexpr ALWAYS_INLINE std::shared_ptr> MakeShared(Arguments &&... args) { return std::make_shared>(std::forward(args)...); } + template + requires (std::constructible_from && std::derived_from>) + constexpr ALWAYS_INLINE std::shared_ptr> MakeShared(Arguments &&... args) { + return std::make_shared>(std::make_shared(std::forward(args)...)); + } + template constexpr ALWAYS_INLINE std::shared_ptr> GetSharedPointerTo(Impl *impl) { return std::make_shared>(impl);