From 4632ff355cdfea0a27181ee4613bb2381e5c9633 Mon Sep 17 00:00:00 2001 From: Denis Blank Date: Wed, 21 Feb 2018 08:19:47 +0100 Subject: [PATCH] Add relocate_index_pack to assign the target address to indexed continuables --- test/playground/comp.cpp | 72 ++++++++++++++++++++++++++++++++++------ 1 file changed, 61 insertions(+), 11 deletions(-) diff --git a/test/playground/comp.cpp b/test/playground/comp.cpp index c381eb1..348fd8f 100644 --- a/test/playground/comp.cpp +++ b/test/playground/comp.cpp @@ -103,15 +103,63 @@ struct result_indexer_mapper { using type = indexed_continuable, target>; return type{std::forward(continuable), nullptr}; } +}; - /// Remove all other non container values from this pack - /*template < - typename T, - typename Category = traversal::container_category_of_t>, - std::enable_if_t* = nullptr> - auto operator()(T&&) { - return spread_this(); - }*/ +/// Relocates the target of a deeply nested pack of indexed_continuable objects +/// to the given target. +struct result_relocator_mapper { + template + static void traverse(traversal::container_category_tag, + Index* /*index*/, Result* /*result*/) { + // Don't do anything when dealing witrh casual objects + } + template + static void traverse(traversal::container_category_tag, + indexed_continuable* index, + Result* result) { + + // Assign the address of the target to the indexed continuable + index->target = result; + } + + /// Traverse a homogeneous container + template + static void traverse(traversal::container_category_tag, + Index* index, Result* result) { + auto index_itr = index->begin(); + auto const index_end = index->end(); + + auto result_itr = result->begin(); + auto const result_end = result->end(); + + using element_t = std::decay_tbegin())>; + traversal::container_category_of_t constexpr const tag; + + for (; index_itr != index_end; ++index_itr, ++result_itr) { + assert(result_itr != result_end); + traverse(tag, &*index_itr, &*result_itr); + } + } + + template + static void traverse_tuple_like(std::integer_sequence, + Index* index, Result* result) { + + (void)std::initializer_list{( + (void)traverse( + traversal::container_category_of_t(*index))>{}, + &std::get(*index), &std::get(*result)), + 0)...}; + } + + /// Traverse tuple like container + template + static void traverse(traversal::container_category_tag, + Index* index, Result* result) { + + constexpr std::make_index_sequence::value> const i{}; + traverse_tuple_like(i, index, result); + } }; } // namespace detail @@ -138,9 +186,9 @@ constexpr auto create_index_pack(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 -constexpr auto relocate_index_pack(Index* index, Target* target) { - /*return cti::map_pack(detail::result_indexer_mapper{}, - std::forward(args)...);*/ +constexpr void relocate_index_pack(Index* index, Target* target) { + constexpr traversal::container_category_of_t const tag; + detail::result_relocator_mapper::traverse(tag, index, target); } /* @@ -198,5 +246,7 @@ int main(int, char**) { auto r = create_result_pack(std::move(p)); auto i = create_index_pack(std::move(p)); + relocate_index_pack(&i, &r); + return 0; }