Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async ref #81

Merged
merged 2 commits into from
Aug 18, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 25 additions & 19 deletions stlab/concurrency/future.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
#include <stlab/concurrency/task.hpp>
#include <stlab/concurrency/traits.hpp>

#include <stlab/functional.hpp>
#include <stlab/utility.hpp>

/**************************************************************************************************/

namespace stlab {
Expand Down Expand Up @@ -1245,39 +1248,42 @@ auto when_all(E executor, F f, const std::pair<I, I>& range) {

/**************************************************************************************************/

template <typename E, // models task executor
typename F, // models functional object
typename I> // models ForwardIterator that reference to a range of futures of the same type
template <
typename E, // models task executor
typename F, // models functional object
typename I> // models ForwardIterator that reference to a range of futures of the same type
auto when_any(E executor, F f, const std::pair<I, I>& range) {
using param_t = typename std::iterator_traits<I>::value_type::result_type;
using result_t = typename detail::result_of_when_any_t<F, param_t>::result_type;
using context_result_t = std::conditional_t<std::is_same<void, param_t>::value, void, param_t>;
using context_t = detail::common_context<detail::context_result<F, true, context_result_t>,
F,
detail::single_trigger,
detail::all_trigger>;
using context_t = detail::common_context<detail::context_result<F, true, context_result_t>, F,
detail::single_trigger, detail::all_trigger>;

if (range.first == range.second) {
auto p = package_with_broken_promise<result_t()>(std::move(executor),
detail::context_result<F, true, context_result_t>(std::move(f), 0));
auto p = package_with_broken_promise<result_t()>(
std::move(executor),
detail::context_result<F, true, context_result_t>(std::move(f), 0));
return std::move(p.second);
}

return detail::create_range_of_futures<result_t, context_t>::do_it(std::move(executor),
std::move(f),
range.first, range.second);
return detail::create_range_of_futures<result_t, context_t>::do_it(
std::move(executor), std::move(f), range.first, range.second);
}

/**************************************************************************************************/

template <typename E, typename F, typename ...Args>
template <typename E, typename F, typename... Args>
auto async(E executor, F&& f, Args&&... args)
-> future<std::result_of_t<F (Args...)>>
{
auto p = package<std::result_of_t<F(Args...)>()>(executor,
std::bind([_f = std::forward<F>(f)](Args&... args) mutable {
return _f(std::move(args)...);
}, std::forward<Args>(args)...));
-> future<std::result_of_t<std::decay_t<F>(std::decay_t<Args>...)>> {
using result_type = std::result_of_t<std::decay_t<F>(std::decay_t<Args>...)>;

auto p = package<result_type()>(
executor, std::bind<result_type>(
[_f = std::forward<F>(f)](unwrap_reference_t<std::decay_t<Args>> &
... args) mutable->result_type {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The line wrapping here is strange. Probably a result of clangformat?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, clang-format is getting lost on that line.

return _f(move_if<!is_reference_wrapper_v<std::decay_t<Args>>>(args)...);
},
std::forward<Args>(args)...));

executor(std::move(p.first));

Expand Down
63 changes: 63 additions & 0 deletions stlab/functional.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
Copyright 2017 Adobe
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/

/**************************************************************************************************/

#ifndef STLAB_FUNCTIONAL_HPP
#define STLAB_FUNCTIONAL_HPP

/**************************************************************************************************/

#include <functional>
#include <type_traits>

/**************************************************************************************************/

namespace stlab {

/**************************************************************************************************/

inline namespace v1 {

/**************************************************************************************************/

template <class T>
struct unwrap_reference {
using type = T;
};

template <class T>
struct unwrap_reference<std::reference_wrapper<T>> {
using type = T;
};

template <class T>
using unwrap_reference_t = typename unwrap_reference<T>::type;

/**************************************************************************************************/

template <class T>
struct is_reference_wrapper : std::false_type {};
template <class T>
struct is_reference_wrapper<std::reference_wrapper<T>> : std::true_type {};

template <class T>
constexpr bool is_reference_wrapper_v = is_reference_wrapper<T>::value;

/**************************************************************************************************/

} // namespace v1

/**************************************************************************************************/

} // namespace stlab

/**************************************************************************************************/

#endif

/**************************************************************************************************/

66 changes: 66 additions & 0 deletions stlab/utility.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
Copyright 2017 Adobe
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/

/**************************************************************************************************/

#ifndef STLAB_UTILITY_HPP
#define STLAB_UTILITY_HPP

/**************************************************************************************************/

#include <type_traits>

/**************************************************************************************************/

namespace stlab {

/**************************************************************************************************/

inline namespace v1 {

/**************************************************************************************************/

namespace detail {

template <bool, class T>
struct move_if_helper;

template <class T>
struct move_if_helper<true, T> {
using type = std::remove_reference_t<T>&&;
};

template <class T>
struct move_if_helper<false, T> {
using type = std::remove_reference_t<T>&;
};

template <bool P, class T>
using move_if_helper_t = typename move_if_helper<P, T>::type;

} // namespace detail

/**************************************************************************************************/

template <bool P, class T>
constexpr detail::move_if_helper_t<P, T> move_if(T&& t) noexcept {
return static_cast<detail::move_if_helper_t<P, T>>(t);
}

/**************************************************************************************************/

} // namespace v1

/**************************************************************************************************/

} // namespace stlab

/**************************************************************************************************/

#endif

/**************************************************************************************************/