Skip to content

Commit f08f646

Browse files
committed
optimization: transform select into set as much as possible
1 parent 9a37e55 commit f08f646

File tree

2 files changed

+49
-4
lines changed

2 files changed

+49
-4
lines changed

Diff for: include/ctre/actions/options.inc.hpp

+33-3
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,41 @@ template <typename Parameters> static constexpr auto apply(pcre::push_empty, ctl
1313

1414
// make_alternate (A|B)
1515
template <auto V, typename A, typename B, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_alternate, ctll::term<V>, pcre_context<ctll::list<B, A, Ts...>, Parameters> subject) {
16-
return pcre_context{ctll::push_front(select<A,B>(), ctll::list<Ts...>()), subject.parameters};
16+
if constexpr (MatchesCharacter<A>::template value<char32_t> && MatchesCharacter<B>::template value<char32_t>) {
17+
auto new_set = push_back_into_set(A(), set<B>());
18+
return pcre_context{ctll::push_front(new_set(), ctll::list<Ts...>()), subject.parameters};
19+
} else {
20+
return pcre_context{ctll::push_front(select<A,B>(), ctll::list<Ts...>()), subject.parameters};
21+
}
1722
}
23+
24+
// make_alternate (As..)|B => (As..|B)
25+
template <auto V, typename A, typename B, typename... Bs, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_alternate, ctll::term<V>, pcre_context<ctll::list<ctre::select<B, Bs...>, A, Ts...>, Parameters> subject) {
26+
if constexpr (MatchesCharacter<A>::template value<char32_t> && MatchesCharacter<B>::template value<char32_t>) {
27+
auto new_set = push_back_into_set(A(), set<B>());
28+
return pcre_context{ctll::push_front(select<decltype(new_set), Bs...>(), ctll::list<Ts...>()), subject.parameters};
29+
} else {
30+
return pcre_context{ctll::push_front(select<A,Bs...>(), ctll::list<Ts...>()), subject.parameters};
31+
}
32+
}
33+
34+
template <auto V, typename A, typename B, typename... Options, typename... Bs, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_alternate, ctll::term<V>, pcre_context<ctll::list<ctre::select<set<Options...>, Bs...>, A, Ts...>, Parameters> subject) {
35+
if constexpr (MatchesCharacter<A>::template value<char32_t> && MatchesCharacter<B>::template value<char32_t>) {
36+
auto new_set = push_back_into_set(A(), set<Options...>());
37+
return pcre_context{ctll::push_front(select<decltype(new_set), Bs...>(), ctll::list<Ts...>()), subject.parameters};
38+
} else {
39+
return pcre_context{ctll::push_front(select<A, set<Options...>, Bs...>(), ctll::list<Ts...>()), subject.parameters};
40+
}
41+
}
42+
1843
// make_alternate (As..)|B => (As..|B)
19-
template <auto V, typename A, typename... Bs, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_alternate, ctll::term<V>, pcre_context<ctll::list<ctre::select<Bs...>, A, Ts...>, Parameters> subject) {
20-
return pcre_context{ctll::push_front(select<A,Bs...>(), ctll::list<Ts...>()), subject.parameters};
44+
template <auto V, typename A, typename... Bs, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_alternate, ctll::term<V>, pcre_context<ctll::list<ctre::set<Bs...>, A, Ts...>, Parameters> subject) {
45+
if constexpr (MatchesCharacter<A>::template value<char32_t>) {
46+
auto new_set = push_back_into_set(A(), set<Bs...>());
47+
return pcre_context{ctll::push_front(new_set, ctll::list<Ts...>()), subject.parameters};
48+
} else {
49+
return pcre_context{ctll::push_front(select<A, set<Bs...>>(), ctll::list<Ts...>()), subject.parameters};
50+
}
2151
}
2252

2353

Diff for: include/ctre/actions/set.inc.hpp

+16-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,22 @@
44
// UTILITY
55
// add into set if not exists
66
template <template <typename...> typename SetType, typename T, typename... As, bool Exists = (std::is_same_v<T, As> || ... || false)> static constexpr auto push_back_into_set(T, SetType<As...>) -> ctll::conditional<Exists, SetType<As...>, SetType<As...,T>> { return {}; }
7-
7+
// merge two sets
8+
template<typename B, typename... Bs, typename... As>
9+
static constexpr auto push_back_into_set(ctre::set<B, Bs...>, ctre::set<As...>) {
10+
if constexpr (sizeof...(Bs) == 0)
11+
return push_back_into_set<ctre::set>(B{}, ctre::set<As...>{});
12+
else
13+
return push_back_into_set(ctre::set<Bs...>{}, push_back_into_set<ctre::set>(B{}, ctre::set<As...>{}));
14+
}
15+
// avoid creating wrapped set
16+
template<typename B, typename... Bs, typename... As>
17+
static constexpr auto push_back_into_set(ctre::set<B, Bs...>, ctre::set<ctre::set<As...>>) {
18+
if constexpr (sizeof...(Bs) == 0)
19+
return push_back_into_set<ctre::set>(B{}, ctre::set<As...>{});
20+
else
21+
return push_back_into_set(ctre::set<Bs...>{}, push_back_into_set<ctre::set>(B{}, ctre::set<As...>{}));
22+
}
823
//template <template <typename...> typename SetType, typename A, typename BHead, typename... Bs> struct set_merge_helper {
924
// using step = decltype(push_back_into_set<SetType>(BHead(), A()));
1025
// using type = ctll::conditional<(sizeof...(Bs) > 0), set_merge_helper<SetType, step, Bs...>, step>;

0 commit comments

Comments
 (0)