Skip to content

Commit

Permalink
DPL Analysis: speedup prune_voids_pack
Browse files Browse the repository at this point in the history
  • Loading branch information
ktf committed Jun 29, 2024
1 parent 8fd0c2d commit 045c239
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 5 deletions.
41 changes: 36 additions & 5 deletions Framework/Foundation/include/Framework/Pack.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,45 @@ consteval auto prune_voids_pack(Result result, pack<>)
return result;
}

// The first one is non void, but one of the others is void
template <typename... Rs, typename T, typename... Ts>
requires(!std::is_void_v<T>)
consteval auto prune_voids_pack(pack<Rs...> result, pack<T, Ts...>)
{
if constexpr (std::is_void_v<T> == false) {
return prune_voids_pack(pack<Rs..., T>{}, pack<Ts...>{});
} else {
return prune_voids_pack(pack<Rs...>{}, pack<Ts...>{});
}
return prune_voids_pack(pack<Rs..., T>{}, pack<Ts...>{});
}

// The first one is void
template <typename... Rs, typename V, typename... Ts>
requires(std::is_void_v<V>)
consteval auto prune_voids_pack(pack<Rs...> result, pack<V, Ts...>)
{
return prune_voids_pack(pack<Rs...>{}, pack<Ts...>{});
}

// The first one is non void, but one of the others is void
template <typename... Rs, typename T1, typename T2, typename... Ts>
requires(!std::is_void_v<T1> && !std::is_void_v<T2>)
consteval auto prune_voids_pack(pack<Rs...> result, pack<T1, T2, Ts...>)
{
return prune_voids_pack(pack<Rs..., T1, T2>{}, pack<Ts...>{});
}

// Eats 4 types at the time
template <typename... Rs, typename T1, typename T2, typename T3, typename T4, typename... Ts>
requires(!std::is_void_v<T1> && !std::is_void_v<T2> && !std::is_void_v<T3> && !std::is_void_v<T4>)
consteval auto prune_voids_pack(pack<Rs...> result, pack<T1, T2, T3, T4, Ts...>)
{
return prune_voids_pack(pack<Rs..., T1, T2, T3, T4>{}, pack<Ts...>{});
}

// Eats 8 types at the time
template <typename... Rs, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename... Ts>
requires(!std::is_void_v<T1> && !std::is_void_v<T2> && !std::is_void_v<T3> && !std::is_void_v<T4> && !std::is_void_v<T5> && !std::is_void_v<T6> && !std::is_void_v<T7> && !std::is_void_v<T8>)
consteval auto prune_voids_pack(pack<Rs...> result, pack<T1, T2, T3, T4, T5, T6, T7, T8, Ts...>)
{
return prune_voids_pack(pack<Rs..., T1, T2, T3, T4, T5, T6, T7, T8>{}, pack<Ts...>{});
}

/// Selects from the pack types that satisfy the Condition
Expand Down
3 changes: 3 additions & 0 deletions Framework/Foundation/test/test_FunctionalHelpers.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ TEST_CASE("TestOverride")
static_assert(has_type<double>(pack<int, float>{}) == false, "double should not be in the pack");
static_assert(has_type_v<int, pack<int, float>> == true, "int should be in the pack");
static_assert(has_type_v<double, pack<int, float>> == false, "double should not be in the pack");
static_assert(std::is_same_v<decltype(prune_voids_pack({}, pack<int, int, int, int, int, int, int, int, void>{})), pack<int, int, int, int, int, int, int, int>>, "prune last void");
static_assert(has_type_conditional_v<std::is_same, int, pack<int, float>> == true, "int should be in the pack");
static_assert(has_type_conditional_v<std::is_same, double, pack<int, float>> == false, "double should not be in the pack");

Expand All @@ -42,6 +43,8 @@ TEST_CASE("TestOverride")
static_assert(has_type_at_conditional<std::is_same, bool>(pack<int, float, double>()) == 3 + 1, "bool is not in the pack so the function returns size + 1");

static_assert(std::is_same_v<selected_pack<is_int_t, int, float, char>, pack<int>>, "selector should select int");
static_assert(std::is_same_v<selected_pack<is_int_t, int, int, float, char>, pack<int, int>>, "selector should select int");
static_assert(std::is_same_v<selected_pack<is_int_t, float, int, int, float, char>, pack<int, int>>, "selector should select int");
static_assert(std::is_same_v<selected_pack_multicondition<is_same_as_second_t, pack<int>, pack<int, float, char>>, pack<int>>, "multiselector should select int");
static_assert(std::is_same_v<filtered_pack<is_int_t, int, float, char>, pack<float, char>>, "filter should remove int");
static_assert(std::is_same_v<intersected_pack_t<pack<int, float, char>, pack<float, double>>, pack<float>>, "filter intersect two packs");
Expand Down

0 comments on commit 045c239

Please sign in to comment.