Skip to content

Commit 922462a

Browse files
authored
🐎 🎨 [cib/detail] Replace type_pack_element recursive version (#61)
Problem: - When `__type_pack_element` builtin is not implemented `type_pack_element` is using recursion which is slow to compile. Solution: - Speed up compilation time by replacing non-recursive version of type_pack_element when `__type_pack_element` is not available by creating inherited list of type and id pairs and leverage inheritance to get the Nth type pack element. Co-authored-by: Kris Jusiak <[email protected]>
1 parent 44baf51 commit 922462a

File tree

3 files changed

+29
-7
lines changed

3 files changed

+29
-7
lines changed

include/cib/detail/type_pack_element.hpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <type_traits>
2+
#include <utility>
23

34

45
#ifndef COMPILE_TIME_INIT_BUILD_TYPE_PACK_ELEMENT_HPP
@@ -10,14 +11,19 @@ namespace cib::detail {
1011
template<auto Index, typename... Tn>
1112
using type_pack_element = __type_pack_element<Index, Tn...>;
1213
#else
13-
template<int Index, typename T, typename... Tn>
14+
template<class, int>
15+
struct type_id {};
16+
template<class... Ts> struct inherit : Ts... {};
17+
template<int Index, class T>
18+
auto get_type_pack_element_impl(type_id<T, Index>) -> T;
19+
template<int Index, typename... Ts, auto... Ns>
20+
auto get_type_pack_element_impl(std::index_sequence<Ns...>) ->
21+
decltype(get_type_pack_element_impl<Index>(inherit<type_id<Ts, Ns>...>{}));
22+
template<int Index, typename... Ts>
1423
struct get_type_pack_element {
15-
using type = typename get_type_pack_element<Index - 1, Tn...>::type;
16-
};
17-
18-
template<typename T, typename... Tn>
19-
struct get_type_pack_element<0, T, Tn...> {
20-
using type = T;
24+
using type = decltype(get_type_pack_element_impl<Index, Ts...>(
25+
std::make_index_sequence<sizeof...(Ts)>{})
26+
);
2127
};
2228

2329
template<int Index, typename... Tn>

test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ project(compile_time_init_build)
44

55
add_executable(tests
66
detail/type_list.cpp
7+
detail/type_pack_element.cpp
78
detail/meta.cpp
89
builder_meta.cpp
910
callback.cpp

test/detail/type_pack_element.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#include <cib/cib.hpp>
2+
3+
#include <catch2/catch_test_macros.hpp>
4+
#include <type_traits>
5+
6+
TEST_CASE("type pack element") {
7+
static_assert(std::is_same_v<int, cib::detail::type_pack_element<0, int>>);
8+
static_assert(std::is_same_v<int, cib::detail::type_pack_element<0, int, float>>);
9+
static_assert(std::is_same_v<float, cib::detail::type_pack_element<1, int, float>>);
10+
static_assert(std::is_same_v<void, cib::detail::type_pack_element<0, void, void, void>>);
11+
static_assert(std::is_same_v<void, cib::detail::type_pack_element<1, void, void, void>>);
12+
static_assert(std::is_same_v<void, cib::detail::type_pack_element<2, void, void, void>>);
13+
static_assert(std::is_same_v<const int&, cib::detail::type_pack_element<0, const int&, void*>>);
14+
static_assert(std::is_same_v<void*, cib::detail::type_pack_element<1, const int&, void*>>);
15+
}

0 commit comments

Comments
 (0)