/* * 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 { struct InHandleTag{}; struct OutHandleTag{}; template struct InHandle : public InHandleTag { os::NativeHandle handle; constexpr InHandle() : handle(os::InvalidNativeHandle) { /* ... */ } constexpr InHandle(os::NativeHandle h) : handle(h) { /* ... */ } constexpr InHandle(const InHandle &o) : handle(o.handle) { /* ... */ } constexpr void operator=(const os::NativeHandle &h) { this->handle = h; } constexpr void operator=(const InHandle &o) { this->handle = o.handle; } constexpr /* TODO: explicit? */ operator os::NativeHandle() const { return this->handle; } constexpr os::NativeHandle GetValue() const { return this->handle; } }; template class OutHandleImpl : public OutHandleTag { static_assert(std::is_base_of::value, "OutHandleImpl requires InHandle base"); private: T *m_ptr; public: constexpr OutHandleImpl(T *p) : m_ptr(p) { /* ... */ } constexpr void SetValue(const os::NativeHandle &value) { *m_ptr = value; } constexpr void SetValue(const T &value) { *m_ptr = value; } constexpr const T &GetValue() const { return *m_ptr; } constexpr T *GetPointer() const { return m_ptr; } constexpr os::NativeHandle *GetHandlePointer() const { return &m_ptr->handle; } constexpr T &operator *() const { return *m_ptr; } constexpr T *operator ->() const { return m_ptr; } }; } using MoveHandle = typename impl::InHandle; using CopyHandle = typename impl::InHandle; static_assert(sizeof(MoveHandle) == sizeof(os::NativeHandle), "sizeof(MoveHandle)"); static_assert(sizeof(CopyHandle) == sizeof(os::NativeHandle), "sizeof(CopyHandle)"); template<> class IsOutForceEnabled : public std::true_type{}; template<> class IsOutForceEnabled : public std::true_type{}; template<> class Out : public impl::OutHandleImpl { private: using T = MoveHandle; using Base = impl::OutHandleImpl; public: constexpr Out(T *p) : Base(p) { /* ... */ } constexpr void SetValue(const os::NativeHandle &value) { Base::SetValue(value); } constexpr void SetValue(const T &value) { Base::SetValue(value); } constexpr const T &GetValue() const { return Base::GetValue(); } constexpr T *GetPointer() const { return Base::GetPointer(); } constexpr os::NativeHandle *GetHandlePointer() const { return Base::GetHandlePointer(); } constexpr T &operator *() const { return Base::operator*(); } constexpr T *operator ->() const { return Base::operator->(); } }; template<> class Out : public impl::OutHandleImpl { private: using T = CopyHandle; using Base = impl::OutHandleImpl; public: constexpr Out(T *p) : Base(p) { /* ... */ } constexpr void SetValue(const os::NativeHandle &value) { Base::SetValue(value); } constexpr void SetValue(const T &value) { Base::SetValue(value); } constexpr const T &GetValue() const { return Base::GetValue(); } constexpr T *GetPointer() const { return Base::GetPointer(); } constexpr os::NativeHandle *GetHandlePointer() const { return Base::GetHandlePointer(); } constexpr T &operator *() const { return Base::operator*(); } constexpr T *operator ->() const { return Base::operator->(); } }; using OutMoveHandle = tipc::Out; using OutCopyHandle = tipc::Out; }