From 16ad4936eedc77f5d45f10bbff8e5aa7e9bb8c33 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 29 Jul 2015 23:55:28 +0300 Subject: [PATCH] atomic.h fixed --- rpcs3/Emu/Memory/atomic.h | 60 ++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 19 deletions(-) diff --git a/rpcs3/Emu/Memory/atomic.h b/rpcs3/Emu/Memory/atomic.h index 26e8e29c16..48fd65d3d7 100644 --- a/rpcs3/Emu/Memory/atomic.h +++ b/rpcs3/Emu/Memory/atomic.h @@ -33,12 +33,12 @@ template struct _to_atomic_subtype template using atomic_subtype_t = typename _to_atomic_subtype::type; // result wrapper to deal with void result type -template struct atomic_op_result_t +template struct atomic_op_result_t { RT result; - template inline atomic_op_result_t(T func, Args&&... args) - : result(std::move(func(std::forward(args)...))) + template inline atomic_op_result_t(T func, VT& var, Args&&... args) + : result(std::move(func(var, std::forward(args)...))) { } @@ -49,22 +49,55 @@ template struct atomic_op_result_t }; // void specialization: result is the initial value of the first arg -template struct atomic_op_result_t +template struct atomic_op_result_t { - RT result; + VT result; - template inline atomic_op_result_t(T func, RT& var, Args&&... args) + template inline atomic_op_result_t(T func, VT& var, Args&&... args) : result(var) { func(var, std::forward(args)...); } + inline VT move() + { + return std::move(result); + } +}; + +// member function specialization +template struct atomic_op_result_t +{ + RT result; + + template inline atomic_op_result_t(RT(CT::*func)(FArgs...), VT& var, Args&&... args) + : result(std::move((var.*func)(std::forward(args)...))) + { + } + inline RT move() { return std::move(result); } }; +// member function void specialization +template struct atomic_op_result_t +{ + VT result; + + template inline atomic_op_result_t(void(CT::*func)(FArgs...), VT& var, Args&&... args) + : result(var) + { + (var.*func)(std::forward(args)...); + } + + inline VT move() + { + return std::move(result); + } +}; + template union _atomic_base { using type = std::remove_cv_t; @@ -148,7 +181,7 @@ public: } // perform an atomic operation on data (callable object version, first arg is a reference to atomic type) - template> auto atomic_op(F func, Args&&... args) volatile -> decltype(std::declval>().result) + template> auto atomic_op(F func, Args&&... args) volatile -> decltype(atomic_op_result_t::result) { while (true) { @@ -159,24 +192,13 @@ public: subtype _new = old; // call atomic op for the local copy of the old value and save the return value of the function - atomic_op_result_t result(func, to_type(_new), args...); + atomic_op_result_t result(func, to_type(_new), args...); // atomically compare value with `old`, replace with `_new` and return on success if (sync_bool_compare_and_swap(&sub_data, old, _new)) return result.move(); } } - // perform an atomic operation on data (member function version) - template RT atomic_op(RT(CT::* func)(FArgs...), Args&&... args) volatile - { - return atomic_op(std::mem_fn(func), std::forward(args)...); - } - - template T atomic_op(void(CT::* func)(FArgs...), Args&&... args) volatile - { - return atomic_op(std::mem_fn(func), std::forward(args)...); - } - // atomic bitwise OR, returns previous data force_inline const type _or(const type& right) volatile {