Skip to content

Commit d3916d9

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

File tree

3 files changed

+72
-6
lines changed

3 files changed

+72
-6
lines changed

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

+23-3
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,33 @@ 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_front_into_set(A{}, 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+
1824
// 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};
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_front_into_set(A{}, 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,B,Bs...>(), ctll::list<Ts...>()), subject.parameters };
31+
}
2132
}
2233

34+
// make_alternate [As..]|B => ([As..]|B)
35+
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) {
36+
if constexpr (MatchesCharacter<A>::template value<char32_t>) {
37+
auto new_set = push_front_into_set(A{}, ctre::set<Bs...>{});
38+
return pcre_context{ ctll::push_front(new_set, ctll::list<Ts...>()), subject.parameters };
39+
} else {
40+
return pcre_context{ ctll::push_front(select<A, ctre::set<Bs...>>(), ctll::list<Ts...>()), subject.parameters };
41+
}
42+
}
2343

2444
// make_optional
2545
template <auto V, typename A, typename... Ts, typename Parameters> static constexpr auto apply(pcre::make_optional, ctll::term<V>, pcre_context<ctll::list<A, Ts...>, Parameters> subject) {

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

+46
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,53 @@
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+
template <template <typename...> typename SetType, typename T, typename... As, bool Exists = (std::is_same_v<T, As> || ... || false)> static constexpr auto push_front_into_set(T, SetType<As...>) -> ctll::conditional<Exists, SetType<As...>, SetType<T, As...>> { return {}; }
8+
// merge two sets
9+
template<typename B, typename... As>
10+
static constexpr auto push_back_into_set(B, ctre::set<As...>) {
11+
return push_back_into_set<ctre::set>(B{}, ctre::set<As...>{});
12+
}
13+
14+
template<typename B, typename... As>
15+
static constexpr auto push_back_into_set(ctre::set<As...>, B) {
16+
return push_back_into_set<ctre::set>(B{}, ctre::set<As...>{});
17+
}
18+
19+
template<typename B, typename... Bs, typename... As>
20+
static constexpr auto push_back_into_set(ctre::set<B, Bs...>, ctre::set<As...>) {
21+
if constexpr (sizeof...(Bs) == 0)
22+
return push_back_into_set<ctre::set>(B{}, ctre::set<As...>{});
23+
else
24+
return push_back_into_set(ctre::set<Bs...>{}, push_back_into_set<ctre::set>(B{}, ctre::set<As...>{}));
25+
}
26+
27+
template<typename A, typename B>
28+
static constexpr auto push_back_into_set(A, B) {
29+
return push_back_into_set(A{}, ctre::set<B>{});
30+
}
731

32+
template<typename B, typename... As>
33+
static constexpr auto push_front_into_set(B, ctre::set<As...>) {
34+
return push_front_into_set<ctre::set>(B{}, ctre::set<As...>{});
35+
}
36+
37+
template<typename B, typename... As>
38+
static constexpr auto push_front_into_set(ctre::set<As...>, B) {
39+
return push_front_into_set(ctre::set<As...>{}, ctre::set<B>{});
40+
}
41+
42+
template<typename B, typename... Bs, typename... As>
43+
static constexpr auto push_front_into_set(ctre::set<Bs..., B>, ctre::set<As...>) {
44+
if constexpr (sizeof...(Bs) == 0)
45+
return push_front_into_set<ctre::set>(B{}, ctre::set<As...>{});
46+
else
47+
return push_front_into_set(ctre::set<Bs...>{}, push_front_into_set<ctre::set>(B{}, ctre::set<As...>{}));
48+
}
49+
50+
template<typename A, typename B>
51+
static constexpr auto push_front_into_set(A, B) {
52+
return push_front_into_set(A{}, ctre::set<B>{});
53+
}
854
//template <template <typename...> typename SetType, typename A, typename BHead, typename... Bs> struct set_merge_helper {
955
// using step = decltype(push_back_into_set<SetType>(BHead(), A()));
1056
// using type = ctll::conditional<(sizeof...(Bs) > 0), set_merge_helper<SetType, step, Bs...>, step>;

Diff for: tests/generating.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ static_assert(same_f(CTRE_GEN("[\\x30-\\x39]"), ctre::set<ctre::char_range<'\x30
9999
// alternation
100100
static_assert(same_f(CTRE_GEN("(?:abc|def)"), ctre::select<ctre::string<'a','b','c'>,ctre::string<'d','e','f'>>()));
101101
static_assert(same_f(CTRE_GEN("(?:abc|def|ghi)"), ctre::select<ctre::string<'a','b','c'>,ctre::string<'d','e','f'>,ctre::string<'g','h','i'>>()));
102-
static_assert(same_f(CTRE_GEN("(?:a|b|c|d)"), ctre::select<ctre::character<'a'>,ctre::character<'b'>,ctre::character<'c'>,ctre::character<'d'>>()));
103-
static_assert(same_f(CTRE_GEN("(?:a|b|c|)"), ctre::select<ctre::character<'a'>,ctre::character<'b'>,ctre::character<'c'>,ctre::empty>()));
102+
static_assert(same_f(CTRE_GEN("(?:a|b|c|d)"), ctre::set<ctre::character<'a'>,ctre::character<'b'>,ctre::character<'c'>,ctre::character<'d'>>()));
103+
static_assert(same_f(CTRE_GEN("(?:a|b|c|)"), ctre::select<ctre::set<ctre::character<'a'>,ctre::character<'b'>,ctre::character<'c'>>,ctre::empty>()));
104104

105105
// optional
106106
static_assert(same_f(CTRE_GEN("xx?"), ctre::sequence<ctre::character<'x'>,ctre::optional<ctre::character<'x'>>>()));
@@ -197,7 +197,7 @@ static_assert(same_f(CTRE_GEN("(x[cd])(ab)+"), ctre::sequence<ctre::capture<1,ct
197197
static_assert(same_f(CTRE_GEN("(?<n>x)"), ctre::capture_with_name<1,ctre::id<'n'>,ctre::character<'x'>>()));
198198
static_assert(same_f(CTRE_GEN("(?<name>x)"), ctre::capture_with_name<1,ctre::id<'n','a','m','e'>,ctre::character<'x'>>()));
199199
static_assert(same_f(CTRE_GEN("(?<name>xy)"), ctre::capture_with_name<1,ctre::id<'n','a','m','e'>,ctre::string<'x','y'>>()));
200-
static_assert(same_f(CTRE_GEN("(?<name>x|y)"), ctre::capture_with_name<1,ctre::id<'n','a','m','e'>,ctre::select<ctre::character<'x'>,ctre::character<'y'>>>()));
200+
static_assert(same_f(CTRE_GEN("(?<name>x|y)"), ctre::capture_with_name<1,ctre::id<'n','a','m','e'>,ctre::set<ctre::character<'x'>,ctre::character<'y'>>>()));
201201
static_assert(same_f(CTRE_GEN("(?<xy>[x]y)"), ctre::capture_with_name<1,ctre::id<'x','y'>,ctre::set<ctre::character<'x'>>,ctre::character<'y'>>()));
202202
static_assert(same_f(CTRE_GEN("(?<xy>[x]y)(a)"), ctre::sequence<ctre::capture_with_name<1,ctre::id<'x','y'>,ctre::set<ctre::character<'x'>>,ctre::character<'y'>>, ctre::capture<2,ctre::character<'a'>>>()));
203203

0 commit comments

Comments
 (0)