More work on indexing continuables together with its result

This commit is contained in:
Denis Blank 2018-02-19 15:46:00 +01:00
parent f81f0e649c
commit 8dbd3d058a
3 changed files with 81 additions and 35 deletions

View File

@ -60,6 +60,8 @@ struct is_tuple_like<T, traits::void_t<decltype(std::tuple_size<T>::value)>>
/// A tag for dispatching based on the tuple like /// A tag for dispatching based on the tuple like
/// or container properties of a type. /// or container properties of a type.
///
/// This type deduces to a true_type if it has any category.
template <bool IsContainer, bool IsTupleLike> template <bool IsContainer, bool IsTupleLike>
struct container_category_tag struct container_category_tag
: std::integral_constant<bool, IsContainer || IsTupleLike> {}; : std::integral_constant<bool, IsContainer || IsTupleLike> {};

View File

@ -735,7 +735,7 @@ class mapping_helper : protected mapping_strategy_base<Strategy> {
-> decltype(std::declval<mapping_helper>().invoke_mapper( -> decltype(std::declval<mapping_helper>().invoke_mapper(
std::forward<T>(element))) { std::forward<T>(element))) {
// T could be any non container or non tuple like type here, // T could be any non container or non tuple like type here,
// take int or hpx::future<int> as an example. // take int or std::future<int> as an example.
return invoke_mapper(std::forward<T>(element)); return invoke_mapper(std::forward<T>(element));
} }

View File

@ -49,11 +49,20 @@ namespace remapping {
// Guard object for representing void results // Guard object for representing void results
struct void_result_guard {}; struct void_result_guard {};
/// Contains an continuable together with a location where the
/// result shall be stored.
template <typename Continuable, typename Target>
struct indexed_continuable {
Continuable continuable;
Target* target;
};
namespace detail {
struct result_extractor_mapper { struct result_extractor_mapper {
/// Create slots for a void result which is removed later. /// Create slots for a void result which is removed later.
/// This is required due to the fact that each continuable has exactly /// This is required due to the fact that each continuable has exactly
/// one matching valuen inside the result tuple. /// one matching valuen inside the result tuple.
static constexpr auto initialize(hints::signature_hint_tag<>) { static constexpr auto initialize(hints::signature_hint_tag<>) noexcept {
return void_result_guard{}; return void_result_guard{};
} }
/// Initialize a single value /// Initialize a single value
@ -80,47 +89,79 @@ struct result_extractor_mapper {
} }
}; };
/// Returns the result pack of the given deeply nested pack. /// Maps a deeply nested pack of continuables to
/// This invalidates all non-continuable values contained inside the pack. struct result_indexer_mapper {
template <typename... Args> /// Index a given continuable together with its target location
constexpr auto create_result_pack(Args&&... args) {
return cti::map_pack(result_extractor_mapper{}, std::forward<Args>(args)...);
}
/// Contains an continuable together with a location where the
/// result shall be stored.
template <typename Continuable, typename Target>
struct indexed_continuable {
Continuable continuable;
Target* target;
};
template <typename Target>
struct result_indexer {
Target* target;
template < template <
typename T, typename T,
std::enable_if_t<base::is_continuable<std::decay_t<T>>::value>* = nullptr> std::enable_if_t<base::is_continuable<std::decay_t<T>>::value>* = nullptr>
auto operator()(T&& continuable) { auto operator()(T&& continuable) {
using type = indexed_continuable<std::decay_t<T>, Target>; auto constexpr const hint = hints::hint_of(traits::identify<T>{});
return type{std::forward<T>(continuable), target};
using target = decltype(result_extractor_mapper::initialize(hint));
using type = indexed_continuable<std::decay_t<T>, target>;
return type{std::forward<T>(continuable), nullptr};
} }
template < /// Remove all other non container values from this pack
/*template <
typename T, typename T,
std::enable_if_t<base::is_continuable<std::decay_t<T>>::value>* = nullptr> typename Category = traversal::container_category_of_t<std::decay_t<T>>,
auto operator()(T&& continuable) { std::enable_if_t<!Category::value>* = nullptr>
using type = indexed_continuable<std::decay_t<T>, Target>; auto operator()(T&&) {
return type{std::forward<T>(continuable), target}; return spread_this();
} }*/
}; };
} // namespace detail
/// Returns the index pack of the given deeply nested pack /// Returns the result pack of the given deeply nested pack.
template <typename Target, typename... Args> /// This invalidates all non-continuable values contained inside the pack.
constexpr auto index_result_pack(Target* target, Args&&... args) { ///
return cti::map_pack(result_extractor_mapper{}, std::forward<Args>(args)...); /// This consumes all non continuables inside the pack.
template <typename... Args>
constexpr auto create_result_pack(Args&&... args) {
return cti::map_pack(detail::result_extractor_mapper{},
std::forward<Args>(args)...);
} }
/// Returns the result pack of the given deeply nested pack.
/// This invalidates all non-continuable values contained inside the pack.
///
/// This consumes all continuables inside the pack.
template <typename... Args>
constexpr auto create_index_pack(Args&&... args) {
return cti::map_pack(detail::result_indexer_mapper{},
std::forward<Args>(args)...);
}
/// Sets the target pointers of indexed_continuable's inside the index pack
/// to point to their given counterparts inside the given target.
template <typename Index, typename Target>
constexpr auto relocate_index_pack(Index* index, Target* target) {
/*return cti::map_pack(detail::result_indexer_mapper{},
std::forward<Args>(args)...);*/
}
/*
template <typename T>
auto remape_container(traversal::container_category_tag<false, true>,
T&& container) {
}
template <bool IsTupleLike, typename T>
auto remape_container(traversal::container_category_tag<true, IsTupleLike>,
T&& container) {
}
template <
typename T,
typename Category = traversal::container_category_of_t<std::decay_t<T>>,
std::enable_if_t<Category::value>* = nullptr>
auto operator()(T&& container) {
return remape_container(std::forward<T>(container));
}
*/
} // namespace remapping } // namespace remapping
struct c {}; struct c {};
@ -151,8 +192,11 @@ int main(int, char**) {
// std::tuple<loc<c, ct<0>>, c, c> loc; // std::tuple<loc<c, ct<0>>, c, c> loc;
auto p = auto p =
create_result_pack(0, 4, cti::make_ready_continuable(0), std::make_tuple(0, 4, cti::make_ready_continuable(0),
std::make_tuple(1, 2), cti::make_ready_continuable(0)); std::make_tuple(1, 2), cti::make_ready_continuable(0));
auto r = create_result_pack(std::move(p));
auto i = create_index_pack(std::move(p));
return 0; return 0;
} }