// 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: using Type = T; /* implicit */ Out(Type& t) : raw(&t) {} ~Out() = default; Type* Get() const { return raw; } Type& operator*() { return *raw; } private: Type* raw; }; template using SharedPointer = std::shared_ptr; struct ClientProcessId { explicit operator bool() const { return pid != 0; } const u64& operator*() const { return pid; } u64 pid; }; struct ProcessId { explicit operator bool() const { return pid != 0; } const u64& operator*() const { return pid; } u64 pid; }; using ClientAppletResourceUserId = ClientProcessId; using AppletResourceUserId = ProcessId; template class InCopyHandle { public: using Type = T; /* implicit */ InCopyHandle(Type* t) : raw(t) {} /* implicit */ InCopyHandle() : raw() {} ~InCopyHandle() = default; InCopyHandle& operator=(Type* rhs) { raw = rhs; return *this; } Type* Get() const { return raw; } Type& operator*() const { return *raw; } Type* operator->() const { return raw; } explicit operator bool() const { return raw != nullptr; } private: Type* raw; }; template class OutCopyHandle { public: using Type = T*; /* implicit */ OutCopyHandle(Type& t) : raw(&t) {} ~OutCopyHandle() = default; Type* Get() const { return raw; } Type& operator*() { return *raw; } private: Type* raw; }; template class OutMoveHandle { public: using Type = T*; /* implicit */ OutMoveHandle(Type& t) : raw(&t) {} ~OutMoveHandle() = default; Type* Get() const { return raw; } Type& operator*() { return *raw; } private: Type* raw; }; 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_trivially_copyable_v, "Buffer type must be trivially copyable"); 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; /* implicit */ Buffer(const std::span& rhs) : std::span(rhs) {} /* implicit */ Buffer() = default; 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_trivially_copyable_v, "LargeData type must be trivially copyable"); 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; /* implicit */ LargeData(const T& rhs) : T(rhs) {} /* implicit */ LargeData() = default; }; template using InLargeData = LargeData; template using OutLargeData = LargeData; template struct RemoveOut { using Type = std::remove_reference_t; }; template struct RemoveOut> { using Type = typename Out::Type; }; template struct RemoveOut> { using Type = typename OutCopyHandle::Type; }; template struct RemoveOut> { using Type = typename OutMoveHandle::Type; }; 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