mirror of
https://github.com/Naios/continuable.git
synced 2026-02-05 17:29:48 +08:00
Some more work on seperating the indexer and relocator
This commit is contained in:
parent
4632ff355c
commit
9be06f4bcc
@ -57,6 +57,12 @@ struct indexed_continuable {
|
|||||||
Target* target;
|
Target* target;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct is_indexed_continuable : std::false_type {};
|
||||||
|
template <typename Continuable, typename Target>
|
||||||
|
struct is_indexed_continuable<indexed_continuable<Continuable, Target>>
|
||||||
|
: std::true_type {};
|
||||||
|
|
||||||
namespace detail {
|
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.
|
||||||
@ -107,25 +113,38 @@ struct result_indexer_mapper {
|
|||||||
|
|
||||||
/// Relocates the target of a deeply nested pack of indexed_continuable objects
|
/// Relocates the target of a deeply nested pack of indexed_continuable objects
|
||||||
/// to the given target.
|
/// to the given target.
|
||||||
|
template <typename Evaluator>
|
||||||
struct result_relocator_mapper {
|
struct result_relocator_mapper {
|
||||||
template <typename Index, typename Result>
|
Evaluator evaluator;
|
||||||
static void traverse(traversal::container_category_tag<false, false>,
|
|
||||||
Index* /*index*/, Result* /*result*/) {
|
|
||||||
// Don't do anything when dealing witrh casual objects
|
|
||||||
}
|
|
||||||
template <typename Continuable, typename Target, typename Result>
|
|
||||||
static void traverse(traversal::container_category_tag<false, false>,
|
|
||||||
indexed_continuable<Continuable, Target>* index,
|
|
||||||
Result* result) {
|
|
||||||
|
|
||||||
// Assign the address of the target to the indexed continuable
|
template <typename Index, typename Result>
|
||||||
index->target = result;
|
void traverse_one(std::false_type, Index*, Result*) {
|
||||||
|
// Don't do anything when dealing with casual objects
|
||||||
|
}
|
||||||
|
template <typename Index, typename Result>
|
||||||
|
void traverse_one(std::true_type, Index* index, Result* result) {
|
||||||
|
|
||||||
|
// Call the evaluator with the address of the indexed object and its target
|
||||||
|
evaluator(index, result);
|
||||||
|
}
|
||||||
|
template <typename Index, typename Result>
|
||||||
|
void traverse(traversal::container_category_tag<false, false>, Index* index,
|
||||||
|
Result* result) {
|
||||||
|
|
||||||
|
auto id = traits::identity<std::decay_t<decltype(index)>>{};
|
||||||
|
auto i = is_indexed_continuable<std::decay_t<decltype(index)>>::value;
|
||||||
|
auto res = traits::is_invocable<Evaluator, Index, Result>{};
|
||||||
|
|
||||||
|
evaluator(index, result);
|
||||||
|
|
||||||
|
traverse_one(traits::is_invocable<Evaluator, Index, Result>{}, index,
|
||||||
|
result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Traverse a homogeneous container
|
/// Traverse a homogeneous container
|
||||||
template <bool IsTupleLike, typename Index, typename Result>
|
template <bool IsTupleLike, typename Index, typename Result>
|
||||||
static void traverse(traversal::container_category_tag<true, IsTupleLike>,
|
void traverse(traversal::container_category_tag<true, IsTupleLike>,
|
||||||
Index* index, Result* result) {
|
Index* index, Result* result) {
|
||||||
auto index_itr = index->begin();
|
auto index_itr = index->begin();
|
||||||
auto const index_end = index->end();
|
auto const index_end = index->end();
|
||||||
|
|
||||||
@ -142,8 +161,8 @@ struct result_relocator_mapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <std::size_t... I, typename Index, typename Result>
|
template <std::size_t... I, typename Index, typename Result>
|
||||||
static void traverse_tuple_like(std::integer_sequence<std::size_t, I...>,
|
void traverse_tuple_like(std::integer_sequence<std::size_t, I...>,
|
||||||
Index* index, Result* result) {
|
Index* index, Result* result) {
|
||||||
|
|
||||||
(void)std::initializer_list<int>{(
|
(void)std::initializer_list<int>{(
|
||||||
(void)traverse(
|
(void)traverse(
|
||||||
@ -154,10 +173,11 @@ struct result_relocator_mapper {
|
|||||||
|
|
||||||
/// Traverse tuple like container
|
/// Traverse tuple like container
|
||||||
template <typename Index, typename Result>
|
template <typename Index, typename Result>
|
||||||
static void traverse(traversal::container_category_tag<false, true>,
|
void traverse(traversal::container_category_tag<false, true>, Index* index,
|
||||||
Index* index, Result* result) {
|
Result* result) {
|
||||||
|
|
||||||
|
std::make_index_sequence<std::tuple_size<Index>::value> constexpr const i{};
|
||||||
|
|
||||||
constexpr std::make_index_sequence<std::tuple_size<Index>::value> const i{};
|
|
||||||
traverse_tuple_like(i, index, result);
|
traverse_tuple_like(i, index, result);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -185,10 +205,15 @@ constexpr auto create_index_pack(Args&&... args) {
|
|||||||
|
|
||||||
/// Sets the target pointers of indexed_continuable's inside the index pack
|
/// Sets the target pointers of indexed_continuable's inside the index pack
|
||||||
/// to point to their given counterparts inside the given target.
|
/// to point to their given counterparts inside the given target.
|
||||||
template <typename Index, typename Target>
|
template <typename Relocator, typename Index, typename Target>
|
||||||
constexpr void relocate_index_pack(Index* index, Target* target) {
|
constexpr void relocate_index_pack(Relocator&& relocator, Index* index,
|
||||||
|
Target* target) {
|
||||||
constexpr traversal::container_category_of_t<Index> const tag;
|
constexpr traversal::container_category_of_t<Index> const tag;
|
||||||
detail::result_relocator_mapper::traverse(tag, index, target);
|
|
||||||
|
detail::result_relocator_mapper<std::decay_t<Relocator>> mapper{
|
||||||
|
std::forward<Relocator>(relocator)};
|
||||||
|
|
||||||
|
mapper.traverse(tag, index, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -239,14 +264,23 @@ int main(int, char**) {
|
|||||||
// std::tuple<c, c, c> t;
|
// std::tuple<c, c, c> t;
|
||||||
// std::tuple<loc<c, ct<0>>, c, c> loc;
|
// std::tuple<loc<c, ct<0>>, c, c> loc;
|
||||||
|
|
||||||
auto p =
|
auto p = std::make_tuple(cti::make_ready_continuable(0) /*, 0, 4,
|
||||||
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 r = create_result_pack(std::move(p));
|
||||||
auto i = create_index_pack(std::move(p));
|
auto i = create_index_pack(std::move(p));
|
||||||
|
|
||||||
relocate_index_pack(&i, &r);
|
relocate_index_pack(
|
||||||
|
[](auto index, auto result)
|
||||||
|
-> std::enable_if_t<is_indexed_continuable<
|
||||||
|
std::remove_pointer_t<std::decay_t<decltype(index)>>>::value> {
|
||||||
|
|
||||||
|
// Assign the address of the target to the indexed continuable
|
||||||
|
index->target = result;
|
||||||
|
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
&i, &r);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user