Use std::invoke_result_t

Also simplify idm code
This commit is contained in:
Nekotekina 2018-09-05 15:10:37 +03:00
parent d750e955c3
commit 99ffc3fca9
3 changed files with 49 additions and 87 deletions

View File

@ -209,7 +209,7 @@ public:
}
// Wait until pred(). Abortable, may throw.
template<typename F, typename RT = std::result_of_t<F()>>
template<typename F, typename RT = std::invoke_result_t<F>>
static inline RT wait(F&& pred)
{
while (true)

View File

@ -271,7 +271,7 @@ template<typename T, T Func>
ppu_static_function* ppu_module_manager::registered<T, Func>::info = nullptr;
// Call specified function directly if LLE is not available, call LLE equivalent in callback style otherwise
template<typename T, T Func, typename... Args, typename RT = std::result_of_t<T(Args...)>>
template<typename T, T Func, typename... Args, typename RT = std::invoke_result_t<T, Args...>>
inline RT ppu_execute_function_or_callback(ppu_thread& ppu, Args&&... args)
{
vm::ptr<RT(Args...)> func = vm::cast(*ppu_module_manager::find_static_function<T, Func>().export_addr);

View File

@ -376,7 +376,7 @@ public:
}
// Add a new ID for an object returned by provider()
template <typename T, typename Made = T, typename F, typename = std::result_of_t<F()>>
template <typename T, typename Made = T, typename F, typename = std::invoke_result_t<F>>
static inline u32 import(F&& provider)
{
if (auto pair = create_id<T, Made>(std::forward<F>(provider)))
@ -417,32 +417,32 @@ public:
}
// Check the ID, access object under shared lock
template <typename T, typename Get = T, typename F, typename FRT = std::result_of_t<F(Get&)>, typename = std::enable_if_t<std::is_void<FRT>::value>>
static inline Get* check(u32 id, F&& func, int = 0)
template <typename T, typename Get = T, typename F, typename FRT = std::invoke_result_t<F, Get&>>
static inline auto check(u32 id, F&& func)
{
reader_lock lock(id_manager::g_mutex);
if (const auto ptr = check_unlocked<T, Get>(id))
{
func(*ptr);
return ptr;
if constexpr (!std::is_void_v<FRT>)
{
return return_pair<Get*, FRT>{ptr, func(*ptr)};
}
else
{
func(*ptr);
return ptr;
}
}
return nullptr;
}
// Check the ID, access object under reader lock, propagate return value
template <typename T, typename Get = T, typename F, typename FRT = std::result_of_t<F(Get&)>, typename = std::enable_if_t<!std::is_void<FRT>::value>>
static inline return_pair<Get*, FRT> check(u32 id, F&& func)
{
reader_lock lock(id_manager::g_mutex);
if (const auto ptr = check_unlocked<T, Get>(id))
if constexpr (!std::is_void_v<FRT>)
{
return {ptr, func(*ptr)};
return return_pair<Get*, FRT>{nullptr};
}
else
{
return static_cast<Get*>(nullptr);
}
return {nullptr};
}
// Get the object without locking (can be called from other method)
@ -476,45 +476,29 @@ public:
}
// Get the object, access object under reader lock
template <typename T, typename Get = T, typename F, typename FRT = std::result_of_t<F(Get&)>, typename = std::enable_if_t<std::is_void<FRT>::value>>
static inline auto get(u32 id, F&& func, int = 0)
template <typename T, typename Get = T, typename F, typename FRT = std::invoke_result_t<F, Get&>>
static inline std::conditional_t<std::is_void_v<FRT>, std::shared_ptr<Get>, return_pair<Get, FRT>> get(u32 id, F&& func)
{
using result_type = std::shared_ptr<Get>;
reader_lock lock(id_manager::g_mutex);
const auto found = find_id<T, Get>(id);
if (UNLIKELY(found == nullptr))
{
return result_type{nullptr};
return {nullptr};
}
const auto ptr = static_cast<Get*>(found->second.get());
func(*ptr);
return result_type{found->second, ptr};
}
// Get the object, access object under reader lock, propagate return value
template <typename T, typename Get = T, typename F, typename FRT = std::result_of_t<F(Get&)>, typename = std::enable_if_t<!std::is_void<FRT>::value>>
static inline auto get(u32 id, F&& func)
{
using result_type = return_pair<Get, FRT>;
reader_lock lock(id_manager::g_mutex);
const auto found = find_id<T, Get>(id);
if (UNLIKELY(found == nullptr))
if constexpr (std::is_void_v<FRT>)
{
return result_type{nullptr};
func(*ptr);
return {found->second, ptr};
}
else
{
return {{found->second, ptr}, func(*ptr)};
}
const auto ptr = static_cast<Get*>(found->second.get());
return result_type{{found->second, ptr}, func(*ptr)};
}
// Access all objects of specified type. Returns the number of objects processed.
@ -615,63 +599,41 @@ public:
}
// Remove the ID after accessing the object under writer lock, return the object and propagate return value
template <typename T, typename Get = T, typename F, typename FRT = std::result_of_t<F(Get&)>, typename = std::enable_if_t<std::is_void<FRT>::value>>
static inline auto withdraw(u32 id, F&& func, int = 0)
template <typename T, typename Get = T, typename F, typename FRT = std::invoke_result_t<F, Get&>>
static inline std::conditional_t<std::is_void_v<FRT>, std::shared_ptr<Get>, return_pair<Get, FRT>> withdraw(u32 id, F&& func)
{
using result_type = std::shared_ptr<Get>;
std::unique_lock lock(id_manager::g_mutex);
std::shared_ptr<void> ptr;
if (const auto found = find_id<T, Get>(id))
{
std::lock_guard lock(id_manager::g_mutex);
const auto _ptr = static_cast<Get*>(found->second.get());
if (const auto found = find_id<T, Get>(id))
if constexpr (std::is_void_v<FRT>)
{
func(*static_cast<Get*>(found->second.get()));
ptr = std::move(found->second);
func(*_ptr);
std::shared_ptr<void> ptr = std::move(found->second);
lock.unlock();
id_manager::on_stop<Get>::func(static_cast<Get*>(ptr.get()));
return {ptr, static_cast<Get*>(ptr.get())};
}
else
{
return result_type{nullptr};
}
}
id_manager::on_stop<Get>::func(static_cast<Get*>(ptr.get()));
return result_type{ptr, static_cast<Get*>(ptr.get())};
}
// Conditionally remove the ID (if return value evaluates to false) after accessing the object under writer lock, return the object and propagate return value
template <typename T, typename Get = T, typename F, typename FRT = std::result_of_t<F(Get&)>, typename = std::enable_if_t<!std::is_void<FRT>::value>>
static inline auto withdraw(u32 id, F&& func)
{
using result_type = return_pair<Get, FRT>;
std::shared_ptr<void> ptr;
FRT ret;
{
std::lock_guard lock(id_manager::g_mutex);
if (const auto found = find_id<T, Get>(id))
{
const auto _ptr = static_cast<Get*>(found->second.get());
ret = func(*_ptr);
FRT ret = func(*_ptr);
if (ret)
{
return result_type{{found->second, _ptr}, std::move(ret)};
// If return value evaluates to true, don't delete the object (error code)
return {{found->second, _ptr}, std::move(ret)};
}
ptr = std::move(found->second);
}
else
{
return result_type{nullptr};
std::shared_ptr<void> ptr = std::move(found->second);
lock.unlock();
id_manager::on_stop<Get>::func(static_cast<Get*>(ptr.get()));
return {{ptr, static_cast<Get*>(ptr.get())}, std::move(ret)};
}
}
id_manager::on_stop<Get>::func(static_cast<Get*>(ptr.get()));
return result_type{{ptr, static_cast<Get*>(ptr.get())}, std::move(ret)};
return {nullptr};
}
};