// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once #include #include #include "common/common_types.h" namespace Service { // clang-format off template struct AutoOut { T raw; }; template class Out { public: using Type = T; /* implicit */ Out(const Out& t) : raw(t.raw) {} /* implicit */ Out(AutoOut& t) : raw(&t.raw) {} /* implicit */ Out(Type* t) : raw(t) {} Out& operator=(const Out&) = delete; Type* Get() const { return raw; } Type& operator*() const { return *raw; } Type* operator->() const { return raw; } operator Type*() const { return raw; } private: Type* raw; }; template using SharedPointer = std::shared_ptr; template using OutInterface = Out>; struct ClientProcessId { explicit operator bool() const { return pid != 0; } const u64& operator*() const { return pid; } u64 pid; }; struct ProcessId { explicit ProcessId() : pid() {} explicit ProcessId(u64 p) : pid(p) {} /* implicit */ ProcessId(const ClientProcessId& c) : pid(c.pid) {} bool operator==(const ProcessId& rhs) const { return pid == rhs.pid; } 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(const OutCopyHandle& t) : raw(t.raw) {} /* implicit */ OutCopyHandle(AutoOut& t) : raw(&t.raw) {} /* implicit */ OutCopyHandle(Type* t) : raw(t) {} OutCopyHandle& operator=(const OutCopyHandle&) = delete; Type* Get() const { return raw; } Type& operator*() const { return *raw; } Type* operator->() const { return raw; } operator Type*() const { return raw; } private: Type* raw; }; template class OutMoveHandle { public: using Type = T*; /* implicit */ OutMoveHandle(const OutMoveHandle& t) : raw(t.raw) {} /* implicit */ OutMoveHandle(AutoOut& t) : raw(&t.raw) {} /* implicit */ OutMoveHandle(Type* t) : raw(t) {} OutMoveHandle& operator=(const OutMoveHandle&) = delete; Type* Get() const { return raw; } Type& operator*() const { return *raw; } Type* operator->() const { return raw; } operator Type*() const { return raw; } private: Type* raw; }; enum BufferAttr : int { /* 0x01 */ BufferAttr_In = (1U << 0), /* 0x02 */ BufferAttr_Out = (1U << 1), /* 0x04 */ BufferAttr_HipcMapAlias = (1U << 2), /* 0x08 */ BufferAttr_HipcPointer = (1U << 3), /* 0x10 */ BufferAttr_FixedSize = (1U << 4), /* 0x20 */ BufferAttr_HipcAutoSelect = (1U << 5), /* 0x40 */ BufferAttr_HipcMapTransferAllowsNonSecure = (1U << 6), /* 0x80 */ 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 class InLargeData { public: static_assert(std::is_trivially_copyable_v, "LargeData type must be trivially copyable"); static_assert((A & BufferAttr_Out) == 0, "InLargeData attr must not be Out"); static constexpr BufferAttr Attr = static_cast(A | BufferAttr_In | BufferAttr_FixedSize); using Type = const T; /* implicit */ InLargeData(Type& t) : raw(&t) {} ~InLargeData() = default; InLargeData& 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 OutLargeData { public: static_assert(std::is_trivially_copyable_v, "LargeData type must be trivially copyable"); static_assert((A & BufferAttr_In) == 0, "OutLargeData attr must not be In"); static constexpr BufferAttr Attr = static_cast(A | BufferAttr_Out | BufferAttr_FixedSize); using Type = T; /* implicit */ OutLargeData(const OutLargeData& t) : raw(t.raw) {} /* implicit */ OutLargeData(Type* t) : raw(t) {} /* implicit */ OutLargeData(AutoOut& t) : raw(&t.raw) {} OutLargeData& operator=(const OutLargeData&) = delete; Type* Get() const { return raw; } Type& operator*() const { return *raw; } Type* operator->() const { return raw; } operator Type*() const { return raw; } private: Type* raw; }; // clang-format on } // namespace Service