Permalink
Browse files

Add documentation to hpx::util::unwrapped and hpx::util::unwrapped2.

* Also add some internal comments for improved guidance
  • Loading branch information...
Naios committed May 30, 2017
1 parent 6d8baf3 commit 9085f6b499d04bf5bb0758fd41ece9eac3a8a7f0
Showing with 70 additions and 4 deletions.
  1. +1 −0 docs/CMakeLists.txt
  2. +4 −0 docs/hpx.idx
  3. +65 −4 hpx/util/unwrapped.hpp
View
@@ -173,6 +173,7 @@ set(doxygen_dependencies
"${PROJECT_SOURCE_DIR}/hpx/lcos/when_each.hpp"
"${PROJECT_SOURCE_DIR}/hpx/util/invoke.hpp"
"${PROJECT_SOURCE_DIR}/hpx/util/invoke_fused.hpp"
"${PROJECT_SOURCE_DIR}/hpx/util/unwrapped.hpp"
"${PROJECT_SOURCE_DIR}/hpx/performance_counters/manage_counter_type.hpp")
View
@@ -519,6 +519,10 @@ invoke_r "" "header\.hpx\.util\.invoke_r.*"
invoke_fused "" "header\.hpx\.util\.invoke_fused.*"
invoke_fused_r "" "header\.hpx\.util\.invoke_fused_r.*"
# hpx/util/unwrapped.hpp
unwrapped "" "header\.hpx\.util\.unwrapped.*"
unwrapped2 "" "header\.hpx\.util\.unwrapped2.*"
# hpx/hpx_finalize.hpp
finalize "" "hpx\.finalize.*"
terminate "" "hpx\.terminate.*"
View
@@ -31,12 +31,15 @@
namespace hpx { namespace util
{
/// \cond NOINTERNAL
namespace detail
{
template <typename T, typename Enable = void>
struct unwrap_impl;
///////////////////////////////////////////////////////////////////////
// Implements first level future unwrapping for
// - `hpx::lcos::(shared_)?future<T>`
template <typename T>
struct unwrap_impl<
T,
@@ -82,6 +85,7 @@ namespace hpx { namespace util
};
#endif
// Ranges (begin() and end()) of futures
template <typename T>
struct unwrap_impl<
T,
@@ -111,6 +115,7 @@ namespace hpx { namespace util
return result;
}
// Edge case for void futures
template <typename Range>
static type call(Range& range, /*is_void=*/std::true_type)
{
@@ -120,6 +125,7 @@ namespace hpx { namespace util
}
}
// Tag dispatch trampoline
template <typename Range>
static type call(Range&& range)
{
@@ -425,6 +431,9 @@ namespace hpx { namespace util
template <typename Pack, typename Enable = void>
struct unwrap_dispatch;
// - hpx::lcos::(shared_)?future<T>
// - Range (begin(), end()) of futures
// - hpx::util::tuple<future<T>...>
template <typename T>
struct unwrap_dispatch<util::detail::pack<T>,
typename std::enable_if<
@@ -444,6 +453,7 @@ namespace hpx { namespace util
}
};
// Delayed function unwrapping: returns a callable object which unwraps
template <typename T>
struct unwrap_dispatch<util::detail::pack<T>,
typename std::enable_if<
@@ -458,11 +468,14 @@ namespace hpx { namespace util
static unwrapped_impl<typename decay<F>::type>
call(F && f)
{
// Return the callable object which performs the unwrap upon
// invocation
typedef unwrapped_impl<typename decay<F>::type> impl_type;
return impl_type(std::forward<F>(f));
}
};
// Unwraps a hpx::util::tuple which conatains futures
template <typename ... Ts>
struct unwrap_dispatch<util::detail::pack<Ts...>,
typename std::enable_if<
@@ -495,20 +508,67 @@ namespace hpx { namespace util
util::detail::pack<typename std::decay<Ts>::type...>
>::type type;
};
}
///////////////////////////////////////////////////////////////////////////
} // end namespace detail
/// \endcond
/// A multi-usable helper function for retrieving the actual result of
/// any hpx::lcos::future which is wrapped in an arbitrary way.
///
/// unwrapped supports multiple applications, the underlying
/// implementation is chosen based on the given arguments:
///
/// - For a single callable object as argument,
/// the **deferred form** is used, which makes the function to return a
/// callable object that unwraps the input and passes it to the
/// given callable object upon invocation:
/// ```cpp
/// auto add = [](int left, int right) {
/// return left + right;
/// };
/// auto unwrapper = hpx:util:::unwrapped(add);
/// hpx::util::tuple<hpx::future<int>, hpx::future<int>> tuple = ...;
/// int result = unwrapper(tuple);
/// ```
/// The `unwrapper` object could be used to connect the `add` function
/// to the continuation handler of a hpx::future.
///
/// - For any other input, the **immediate form** is used,
/// which unwraps the given pack of arguments,
/// so that any hpx::lcos::future object is replaced by
/// its future result type in the pack:
/// - `hpx::future<int>` -> `int`
/// - `hpx::future<std::vector<float>>` -> `std::vector<float>`
/// - `std::vector<future<float>>` -> `std::vector<float>`
///
/// \param ts the argument pack that determines the used implementation
///
/// \returns Depending on the chosen implementation the return type is
/// either a hpx::util::tuple containing unwrapped hpx::futures
/// when the *immediate form* is used.
/// If the *deferred form* is used, the function returns a
/// callable object, which unwrapps and forwards its arguments
/// when called, as desribed above.
///
/// \throws std::exception like object in case the immediate application is
/// used and if any of the given hpx::lcos::future objects were
/// resolved through an exception.
/// See hpx::lcos::future::get() for details.
///
template <typename ... Ts>
typename detail::unwrap_dispatch_result<Ts...>::type
unwrapped(Ts &&... ts)
{
// Select the underlying implementation
typedef detail::unwrap_dispatch<
util::detail::pack<typename std::decay<Ts>::type...>
> impl_type;
return impl_type::call(std::forward<Ts>(ts)...);
}
///////////////////////////////////////////////////////////////////////////
/// Provides an additional implementation of unwrapped which
/// unwraps nested hpx::futures within a two-level depth.
///
/// See hpx::util::unwrapped() for details.
template <typename Future>
typename util::lazy_enable_if<
traits::is_future<typename decay<Future>::type>::value
@@ -522,6 +582,7 @@ namespace hpx { namespace util
return unwrapped(unwrapped(std::forward<Future>(f)));
}
/// \copydoc unwrapped2
template <typename F>
typename std::enable_if<
!traits::is_future<typename decay<F>::type>::value

0 comments on commit 9085f6b

Please sign in to comment.