Skip to content

Commit a770bcb

Browse files
authored
Feature/init algorithm refactor (#62)
improved init algorithm compile-time performance
1 parent cd52820 commit a770bcb

13 files changed

+226
-138
lines changed

benchmark/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
1212
-ferror-limit=8
1313
-ftime-report
1414
-ftime-trace
15+
-ftime-trace-granularity=10
1516
)
1617

1718
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")

include/cib/config.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,9 @@ namespace cib {
8484
* @param args
8585
* Value arguments to be passed to the service's builder add function.
8686
*/
87-
template<typename Service, typename... ServiceTemplateArgs, typename... Args>
87+
template<typename Service, typename... Args>
8888
[[nodiscard]] CIB_CONSTEVAL auto extend(Args const & ... args) {
89-
return detail::extend<detail::path<Service, ServiceTemplateArgs...>, Args...>{args...};
89+
return detail::extend<Service, Args...>{args...};
9090
}
9191

9292
/**

include/cib/detail/components.hpp

+2-14
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,9 @@
1414
namespace cib::detail {
1515
template<typename... Components>
1616
struct components : public detail::config_item {
17-
template<typename Builders, typename... Args>
18-
[[nodiscard]] CIB_CONSTEVAL auto init(
19-
Builders const & builders_tuple,
20-
Args const & ... args
21-
) const {
22-
return detail::fold_right(cib::make_tuple(Components{}...), builders_tuple, [&](auto const & c, auto const & builders){
23-
return c.config.init(builders, args...);
24-
});
25-
}
26-
2717
template<typename... Args>
28-
[[nodiscard]] CIB_CONSTEVAL auto exports_tuple(
29-
Args const & ... args
30-
) const {
31-
return type_list_cat(Components::config.exports_tuple(args...)...);
18+
[[nodiscard]] CIB_CONSTEVAL auto extends_tuple(Args const & ... args) const {
19+
return cib::tuple_cat(Components::config.extends_tuple(args...)...);
3220
}
3321
};
3422
}

include/cib/detail/conditional.hpp

+3-17
Original file line numberDiff line numberDiff line change
@@ -24,26 +24,12 @@ namespace cib::detail {
2424
: body{{}, configs...}
2525
{}
2626

27-
template<
28-
typename Builders,
29-
typename... Args>
30-
CIB_CONSTEVAL auto init(
31-
Builders const & builders_tuple,
32-
Args...
33-
) const {
34-
if constexpr (condition(Args{}...)) {
35-
return body.init(builders_tuple, Args{}...);
36-
} else {
37-
return builders_tuple;
38-
}
39-
}
40-
4127
template<typename... Args>
42-
CIB_CONSTEVAL auto exports_tuple(Args...) const {
28+
[[nodiscard]] CIB_CONSTEVAL auto extends_tuple(Args const & ...) const {
4329
if constexpr (condition(Args{}...)) {
44-
return body.exports_tuple(Args{}...);
30+
return body.extends_tuple(Args{}...);
4531
} else {
46-
return type_list<>{};
32+
return cib::tuple<>{};
4733
}
4834
}
4935
};

include/cib/detail/config_details.hpp

+2-16
Original file line numberDiff line numberDiff line change
@@ -31,25 +31,11 @@ namespace cib::detail {
3131
// pass
3232
}
3333

34-
template<typename BuildersT, typename... Args>
35-
[[nodiscard]] CIB_CONSTEVAL auto init(
36-
BuildersT const & builders_tuple,
37-
Args const & ... args
38-
) const {
39-
return apply([&](auto const & ... config_args){
40-
return fold_right(configs_tuple, builders_tuple, [&](auto const & c, auto builders){
41-
return c.init(builders, args..., config_args...);
42-
});
43-
}, ConfigArgs::value);
44-
}
45-
4634
template<typename... Args>
47-
[[nodiscard]] CIB_CONSTEVAL auto exports_tuple(
48-
Args const & ... args
49-
) const {
35+
[[nodiscard]] CIB_CONSTEVAL auto extends_tuple(Args const & ... args) const {
5036
return apply([&](auto const & ... config_args){
5137
return apply([&](auto const & ... configs_pack){
52-
return type_list_cat(configs_pack.exports_tuple(args..., config_args...)...);
38+
return tuple_cat(configs_pack.extends_tuple(args..., config_args...)...);
5339
}, configs_tuple);
5440
}, ConfigArgs::value);
5541
}

include/cib/detail/config_item.hpp

+3-15
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,17 @@
11
#include "compiler.hpp"
22
#include "type_list.hpp"
3+
#include "../tuple.hpp"
34

45

56
#ifndef COMPILE_TIME_INIT_BUILD_CONFIG_DETAIL_HPP
67
#define COMPILE_TIME_INIT_BUILD_CONFIG_DETAIL_HPP
78

89

910
namespace cib::detail {
10-
template<typename FirstT, typename... PathSegmentTs>
11-
struct path {
12-
using First = FirstT;
13-
};
14-
1511
struct config_item {
16-
template<typename Builders, typename... Args>
17-
[[nodiscard]] CIB_CONSTEVAL auto init(
18-
Builders const & builders_tuple,
19-
Args const & ...
20-
) const {
21-
return builders_tuple;
22-
}
23-
2412
template<typename... Args>
25-
[[nodiscard]] CIB_CONSTEVAL auto exports_tuple(Args const & ...) const {
26-
return type_list<>{};
13+
[[nodiscard]] CIB_CONSTEVAL auto extends_tuple(Args const & ...) const {
14+
return cib::tuple<>{};
2715
}
2816
};
2917
}

include/cib/detail/exports.hpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "config_item.hpp"
33
#include "type_list.hpp"
44
#include "builder_traits.hpp"
5+
#include "extend.hpp"
56

67
#include <utility>
78

@@ -19,16 +20,15 @@ namespace cib::detail {
1920
BuilderT builder;
2021
};
2122

22-
23-
2423
template<typename... Services>
2524
struct exports : public detail::config_item {
26-
template<typename... Args>
27-
[[nodiscard]] CIB_CONSTEVAL auto exports_tuple(Args const & ...) const {
28-
return type_list<service_entry<Services, traits::builder_t<Services>>...>{};
25+
template<typename... InitArgs>
26+
[[nodiscard]] CIB_CONSTEVAL auto extends_tuple(InitArgs const & ...) const {
27+
return cib::make_tuple(extend<Services>{}...);
2928
}
3029
};
3130
}
3231

3332

3433
#endif //COMPILE_TIME_INIT_BUILD_EXPORTS_HPP
34+

include/cib/detail/extend.hpp

+6-57
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@
1010

1111
namespace cib::detail {
1212
template<
13-
typename ExtensionPath,
13+
typename ServiceType,
1414
typename... Args>
1515
struct extend : public config_item {
16+
using service_type = ServiceType;
17+
constexpr static auto builder = cib::traits::builder_v<service_type>;
1618
cib::tuple<Args...> args_tuple;
1719

1820
CIB_CONSTEVAL explicit extend(
@@ -23,63 +25,10 @@ namespace cib::detail {
2325
// pass
2426
}
2527

26-
template<
27-
typename TargetBuilder,
28-
typename Builder>
29-
[[nodiscard]] CIB_CONSTEVAL auto add(
30-
path<TargetBuilder> const &,
31-
Builder const & b
32-
) const {
33-
if constexpr (is_same_v<TargetBuilder, typename std::remove_cv_t<std::remove_reference_t<decltype(b)>>::Service>) {
34-
return apply([&](auto const & ... args){
35-
return service_entry <
36-
typename std::remove_cv_t<std::remove_reference_t<decltype(b)>>::Service,
37-
decltype(b.builder.add(args...))>{b.builder.add(args...)};
38-
}, args_tuple);
39-
} else {
40-
return b;
41-
}
28+
template<typename... InitArgs>
29+
[[nodiscard]] CIB_CONSTEVAL auto extends_tuple(InitArgs const & ...) const {
30+
return cib::make_tuple(*this);
4231
}
43-
44-
template<
45-
typename TargetBuilder,
46-
typename SubBuilder,
47-
typename... SubBuilders,
48-
typename Builder>
49-
[[nodiscard]] CIB_CONSTEVAL auto add(
50-
path<TargetBuilder, SubBuilder, SubBuilders...> const &,
51-
Builder const & b
52-
) const {
53-
if constexpr (is_same_v<TargetBuilder, typename std::remove_cv_t<std::remove_reference_t<decltype(b)>>::Service>) {
54-
return apply([&](auto const & ... args){
55-
return service_entry <
56-
typename std::remove_cv_t<std::remove_reference_t<decltype(b)>>::Service,
57-
decltype(b.builder.template add<SubBuilder, SubBuilders...>(args...))>{b.builder.template add<SubBuilder, SubBuilders...>(args...)};
58-
}, args_tuple);
59-
} else {
60-
return b;
61-
}
62-
}
63-
64-
template<typename Builders, typename... InitArgs>
65-
[[nodiscard]] CIB_CONSTEVAL auto init(
66-
Builders const & builders_tuple,
67-
InitArgs const & ...
68-
) const {
69-
return apply([&](auto const & ... builders){
70-
static_assert(
71-
(is_same_v<typename ExtensionPath::First, typename std::remove_cv_t<std::remove_reference_t<decltype(builders)>>::Service> + ... + 0) > 0,
72-
"Extension didn't match any service");
73-
74-
static_assert(
75-
(is_same_v<typename ExtensionPath::First, typename std::remove_cv_t<std::remove_reference_t<decltype(builders)>>::Service> + ... + 0) <= 1,
76-
"Extension matched more than 1 service");
77-
78-
return cib::make_tuple(index_metafunc_<extract_service_tag>, add(ExtensionPath{}, builders)...);
79-
}, builders_tuple);
80-
}
81-
82-
8332
};
8433
}
8534

include/cib/detail/meta.hpp

+3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ namespace cib::detail {
1212
template<int value>
1313
CIB_CONSTEXPR static auto int_ = std::integral_constant<int, value>{};
1414

15+
template<std::size_t value>
16+
CIB_CONSTEXPR static auto size_ = std::integral_constant<std::size_t, value>{};
17+
1518
template<typename Lhs, typename Rhs>
1619
CIB_CONSTEXPR static auto is_same_v =
1720
std::is_same_v<

include/cib/detail/nexus_details.hpp

+35-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "meta.hpp"
33
#include "type_list.hpp"
44
#include "../tuple.hpp"
5+
#include "../set.hpp"
56
#include "exports.hpp"
67

78

@@ -27,9 +28,42 @@ namespace cib {
2728
template<typename ServiceBuilderList>
2829
constexpr static auto to_tuple_v = to_tuple<ServiceBuilderList>::value;
2930

31+
struct get_service {
32+
template<typename T>
33+
using invoke = typename std::remove_cv_t<std::remove_reference_t<T>>::service_type;
34+
};
35+
36+
struct get_service_from_tuple {
37+
template<typename T>
38+
using invoke =
39+
typename std::remove_cv_t<
40+
std::remove_reference_t<
41+
decltype(
42+
std::declval<T>().get(index_<0>)
43+
)
44+
>
45+
>::service_type;
46+
};
47+
3048
template<typename Config>
3149
struct initialized_builders {
32-
CIB_CONSTEXPR static auto value = Config::config.init(to_tuple_v<decltype(Config::config.exports_tuple())>);
50+
CIB_CONSTEXPR static auto value =
51+
transform(
52+
index_metafunc_<extract_service_tag>,
53+
demux(get_service{}, Config::config.extends_tuple()),
54+
[](auto extensions){
55+
constexpr auto initial_builder = extensions.get(index_<0>).builder;
56+
using service = get_service_from_tuple::invoke<decltype(extensions)>;
57+
auto built_service = detail::fold_right(extensions, initial_builder, [](auto extension, auto outer_builder){
58+
return detail::fold_right(extension.args_tuple, outer_builder, [](auto arg, auto inner_builder) {
59+
return inner_builder.add(arg);
60+
});
61+
});
62+
63+
return detail::service_entry<service, decltype(built_service)>{built_service};
64+
}
65+
);
66+
3367
using type = decltype(value);
3468
};
3569

include/cib/detail/set_details.hpp

+5-10
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ namespace cib::detail {
4747
namespace cib::detail {
4848
struct typename_map_entry {
4949
std::string_view name;
50-
unsigned int index;
51-
unsigned int src;
50+
std::size_t index;
51+
std::size_t src;
5252

5353
constexpr auto operator<(typename_map_entry rhs) const {
5454
return name < rhs.name;
@@ -99,18 +99,18 @@ namespace cib::detail {
9999
}
100100

101101
template<typename MetaFunc, typename... Types>
102-
constexpr static auto create_type_names(unsigned int src) {
102+
constexpr static auto create_type_names(std::size_t src) {
103103
if constexpr (sizeof...(Types) == 0) {
104104
return std::array<typename_map_entry, 0>{};
105105

106106
} else {
107-
unsigned int i = 0;
107+
std::size_t i = 0;
108+
108109
std::array<typename_map_entry, sizeof...(Types)> names = {
109110
typename_map_entry{name<typename MetaFunc::template invoke<Types>>(), i++, src}...
110111
};
111112

112113
detail::quicksort(names);
113-
114114
return names;
115115
}
116116
}
@@ -138,8 +138,6 @@ namespace cib::detail {
138138
typename... LhsElems,
139139
typename... RhsElems>
140140
struct set_operation_impl_t<Algorithm, MetaFunc, tuple_impl<LhsElems...>, tuple_impl<RhsElems...>> {
141-
142-
143141
constexpr static auto result = [](){
144142
constexpr auto lhs_tags = create_type_names<MetaFunc, typename LhsElems::value_type...>(0);
145143
constexpr auto rhs_tags = create_type_names<MetaFunc, typename RhsElems::value_type...>(1);
@@ -173,9 +171,6 @@ namespace cib::detail {
173171
LhsTuple lhs,
174172
RhsTuple rhs
175173
) {
176-
// constexpr auto index_list =
177-
// IndexList::result().data;
178-
179174
auto const tuples =
180175
cib::make_tuple(lhs, rhs);
181176

0 commit comments

Comments
 (0)