diff --git a/Source/Core/Common/CMakeLists.txt b/Source/Core/Common/CMakeLists.txt index 608e2f270a..aca142b9cd 100644 --- a/Source/Core/Common/CMakeLists.txt +++ b/Source/Core/Common/CMakeLists.txt @@ -70,6 +70,7 @@ add_library(common Flag.h FloatUtils.cpp FloatUtils.h + Functional.h FormatUtil.h FPURoundMode.h GekkoDisassembler.cpp diff --git a/Source/Core/Common/Functional.h b/Source/Core/Common/Functional.h new file mode 100644 index 0000000000..49d81d5a24 --- /dev/null +++ b/Source/Core/Common/Functional.h @@ -0,0 +1,51 @@ +// Copyright 2025 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +// TODO C++23: Replace with std::move_only_function. + +namespace Common +{ + +template +class MoveOnlyFunction; + +template +class MoveOnlyFunction +{ +public: + using result_type = R; + + MoveOnlyFunction() = default; + + template + MoveOnlyFunction(F&& f) : m_ptr{std::make_unique>(std::forward(f))} + { + } + + result_type operator()(Args... args) const { return m_ptr->Invoke(std::forward(args)...); } + explicit operator bool() const { return m_ptr != nullptr; }; + void swap(MoveOnlyFunction& other) { m_ptr.swap(other.m_ptr); } + +private: + struct FuncBase + { + virtual ~FuncBase() = default; + virtual result_type Invoke(Args...) = 0; + }; + + template + struct Func : FuncBase + { + Func(F&& f) : func{std::forward(f)} {} + result_type Invoke(Args... args) override { return func(std::forward(args)...); } + F func; + }; + + std::unique_ptr m_ptr; +}; + +} // namespace Common diff --git a/Source/Core/DolphinLib.props b/Source/Core/DolphinLib.props index 8b5e3b9f00..57d0465959 100644 --- a/Source/Core/DolphinLib.props +++ b/Source/Core/DolphinLib.props @@ -62,6 +62,7 @@ +