// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once #include #include "common/common_funcs.h" #include "common/common_types.h" #include "core/hle/service/hle_ipc.h" namespace Service { // clang-format off template class Out { public: /* implicit */ Out(T& t) : raw(&t) {} ~Out() = default; T* Get() const { return raw; } T& operator*() { return *raw; } private: T* raw; }; template using SharedPointer = std::shared_ptr; struct ClientProcessId { explicit operator bool() const { return pid != 0; } const u64& operator*() const { return pid; } u64 pid; }; using ClientAppletResourceUserId = ClientProcessId; template class InCopyHandle : public Kernel::KScopedAutoObject { public: using Type = T; template /* implicit */ InCopyHandle(Args&&... args) : Kernel::KScopedAutoObject(std::forward(args)...) {} ~InCopyHandle() = default; InCopyHandle& operator=(InCopyHandle&& rhs) { Kernel::KScopedAutoObject::operator=(std::move(rhs)); return *this; } }; template class OutCopyHandle : public Kernel::KScopedAutoObject { public: using Type = T; template /* implicit */ OutCopyHandle(Args&&... args) : Kernel::KScopedAutoObject(std::forward(args)...) {} ~OutCopyHandle() = default; OutCopyHandle& operator=(OutCopyHandle&& rhs) { Kernel::KScopedAutoObject::operator=(std::move(rhs)); return *this; } }; template class OutMoveHandle : public Kernel::KScopedAutoObject { public: using Type = T; template /* implicit */ OutMoveHandle(Args&&... args) : Kernel::KScopedAutoObject(std::forward(args)...) {} ~OutMoveHandle() = default; OutMoveHandle& operator=(OutMoveHandle&& rhs) { Kernel::KScopedAutoObject::operator=(std::move(rhs)); return *this; } }; enum BufferAttr : int { BufferAttr_In = (1U << 0), BufferAttr_Out = (1U << 1), BufferAttr_HipcMapAlias = (1U << 2), BufferAttr_HipcPointer = (1U << 3), BufferAttr_FixedSize = (1U << 4), BufferAttr_HipcAutoSelect = (1U << 5), BufferAttr_HipcMapTransferAllowsNonSecure = (1U << 6), BufferAttr_HipcMapTransferAllowsNonDevice = (1U << 7), }; template struct Buffer : public std::span { static_assert(std::is_trivial_v, "Buffer type must be trivial"); static_assert((A & BufferAttr_FixedSize) == 0, "Buffer attr must not contain FixedSize"); static_assert(((A & BufferAttr_In) == 0) ^ ((A & BufferAttr_Out) == 0), "Buffer attr must be In or Out"); static constexpr BufferAttr Attr = static_cast(A); using Type = T; Buffer& operator=(const std::span& rhs) { std::span::operator=(rhs); return *this; } T& operator*() const { return *this->data(); } explicit operator bool() const { return this->size() > 0; } }; template using InBuffer = Buffer; template using InArray = Buffer; template using OutBuffer = Buffer; template using OutArray = Buffer; template struct LargeData : public T { static_assert(std::is_trivial_v, "LargeData type must be trivial"); static_assert((A & BufferAttr_FixedSize) != 0, "LargeData attr must contain FixedSize"); static_assert(((A & BufferAttr_In) == 0) ^ ((A & BufferAttr_Out) == 0), "LargeData attr must be In or Out"); static constexpr BufferAttr Attr = static_cast(A); using Type = T; }; template using InLargeData = LargeData; template using OutLargeData = LargeData; template struct RemoveOut { using Type = std::remove_reference_t; }; template struct RemoveOut> { using Type = T; }; enum class ArgumentType { InProcessId, InData, InInterface, InCopyHandle, OutData, OutInterface, OutCopyHandle, OutMoveHandle, InBuffer, InLargeData, OutBuffer, OutLargeData, }; template struct ArgumentTraits; template <> struct ArgumentTraits { static constexpr ArgumentType Type = ArgumentType::InProcessId; }; template struct ArgumentTraits> { static constexpr ArgumentType Type = ArgumentType::InInterface; }; template struct ArgumentTraits> { static constexpr ArgumentType Type = ArgumentType::InCopyHandle; }; template struct ArgumentTraits>> { static constexpr ArgumentType Type = ArgumentType::OutInterface; }; template struct ArgumentTraits> { static constexpr ArgumentType Type = ArgumentType::OutData; }; template struct ArgumentTraits> { static constexpr ArgumentType Type = ArgumentType::OutCopyHandle; }; template struct ArgumentTraits> { static constexpr ArgumentType Type = ArgumentType::OutMoveHandle; }; template struct ArgumentTraits> { static constexpr ArgumentType Type = (A & BufferAttr_In) == 0 ? ArgumentType::OutBuffer : ArgumentType::InBuffer; }; template struct ArgumentTraits> { static constexpr ArgumentType Type = (A & BufferAttr_In) == 0 ? ArgumentType::OutLargeData : ArgumentType::InLargeData; }; template struct ArgumentTraits { static constexpr ArgumentType Type = ArgumentType::InData; }; // clang-format on } // namespace Service