diff --git a/include/Continuable.h b/include/Continuable.h index 9081189..3cb5dad 100644 --- a/include/Continuable.h +++ b/include/Continuable.h @@ -501,6 +501,9 @@ namespace detail template class multiple_result_storage_t, fu::identity<_RTy...>, fu::identity<_PTy...>> { + template + friend struct multiple_result_storage_invoker_t; + std::size_t partitions_left; std::tuple<_RTy...> result; @@ -509,52 +512,16 @@ namespace detail std::mutex lock; - template - struct result_store_sequencer - { - template - inline static void partial_set(Tuple& result, Current&& current) - { - // Store the callback result in the tuple - std::get(result) = std::forward(current); - } - - template - inline static void partial_set(Tuple& result, Current&& current, Rest&&... rest) - { - // Set the result... - partial_set(result, std::forward(current)); - - // ...and continue with the next parameter. - partial_set(result, std::forward(rest)...); - } - - // Do nothing when trying to store empty packs... - inline static void store(std::tuple<_RTy...>& result) - { - } - - // Store the args in the result tuple - template - inline static void store(std::tuple<_RTy...>& result, Args&&... args) - { - partial_set, Args...>(result, std::forward(args)...); - } - }; - public: multiple_result_storage_t(std::size_t partitions, Callback<_RTy...> callback_) : partitions_left(partitions), callback(callback_) { } - template - void store(Args&&... args) + void try_invoke() { - result_store_sequencer:: - store(result, std::forward(args)...); - // TODO Improve the lock here std::lock_guard guard(lock); - { // Never call callbacks twice! + { + // Never call callbacks twice! // assert(partitions_left); // If all partitions have completed invoke the final callback. @@ -569,6 +536,38 @@ namespace detail template struct multiple_result_storage_invoker_t, fu::identity<_RTy...>, fu::identity<_PTy...>> { + template + using move_position_to = multiple_result_storage_invoker_t, fu::identity<_RTy...>, fu::identity<_PTy...>>; + + template + inline static void partial_set(Tuple& result, Current&& current) + { + // Store the callback result in the tuple + std::get(result) = std::forward(current); + } + + template + inline static void partial_set(Tuple& result, Current&& current, Rest&&... rest) + { + // Set the result... + partial_set(result, std::forward(current)); + + // ...and continue with the next parameter. + move_position_to::partial_set(result, std::forward(rest)...); + } + + // Do nothing when trying to store empty packs... + inline static void store(std::tuple<_RTy...>& result) + { + } + + // Store the args in the result tuple + template + inline static void store(std::tuple<_RTy...>& result, Args&&... args) + { + partial_set(result, std::forward(args)...); + } + template static void invoke( std::shared_ptr, fu::identity<_RTy...>, fu::identity<_PTy...>>> storage, @@ -576,8 +575,8 @@ namespace detail { continuable.invoke([storage](Args&&... args) { - // FIXME - // storage->store(std::forward(args)...); + store(storage->result, std::forward(args)...); + storage->try_invoke(); }); } }; diff --git a/test.cpp b/test.cpp index ed89b7c..1438603 100644 --- a/test.cpp +++ b/test.cpp @@ -109,43 +109,6 @@ void test_unwrap(std::string const& msg) { std::cout << msg << " is unwrappable: " << (fu::is_unwrappable::value ? "true" : "false") << std::endl; } -/* -template -struct Apply { - template - static inline auto apply(F && f, T && t, A &&... a) - -> decltype(Apply::apply( - ::std::forward(f), ::std::forward(t), - ::std::get(::std::forward(t)), ::std::forward(a)... - )) - { - return Apply::apply(::std::forward(f), ::std::forward(t), - ::std::get(::std::forward(t)), ::std::forward(a)... - ); - } -}; - -template<> -struct Apply<0> { - template - static inline auto apply(F && f, T &&, A &&... a) - -> decltype(::std::forward(f)(::std::forward(a)...)) - { - return ::std::forward(f)(::std::forward(a)...); - } -}; - -template -inline auto apply(F && f, T && t) - -> decltype(Apply< ::std::tuple_size< - typename ::std::decay::type - >::value>::apply(::std::forward(f), ::std::forward(t))) -{ - return Apply< ::std::tuple_size< - typename ::std::decay::type - >::value>::apply(::std::forward(f), ::std::forward(t)); -} -*/ int main(int /*argc*/, char** /*argv*/) {