Skip to content

Commit a72dce6

Browse files
author
Hana Dusíková
committed
class nontype template parameter support in GCC9
1 parent eee10a6 commit a72dce6

File tree

7 files changed

+100
-97
lines changed

7 files changed

+100
-97
lines changed

include/ctll/fixed_string.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ template <typename CharT> class basic_fixed_string<CharT, 0> {
5353
};
5454

5555
template <typename CharT, size_t N> basic_fixed_string(const CharT (&)[N]) -> basic_fixed_string<CharT, N>;
56+
template <typename CharT, size_t N> basic_fixed_string(basic_fixed_string<CharT, N>) -> basic_fixed_string<CharT, N>;
5657

5758
}
5859

include/ctll/grammars.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ template <typename Grammar> struct augment_grammar: public Grammar {
9595
static constexpr auto rule(...) -> ctll::reject;
9696

9797
// start stack is just a list<Grammar::_start>;
98-
static constexpr inline auto start_stack = list<typename Grammar::_start>{};
98+
using start_stack = list<typename Grammar::_start>;
9999
};
100100

101101

include/ctll/parser.hpp

Lines changed: 28 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,21 @@ template <typename T> void id(T);
1919

2020
struct placeholder { };
2121

22+
template <bool Correct, typename Subject> struct result_of_parsing {
23+
constexpr operator bool() const noexcept {
24+
return Correct;
25+
}
26+
using output_type = Subject;
27+
};
28+
2229
#if !__cpp_nontype_template_parameter_class
2330
template <typename Grammar, const auto & input, typename ActionSelector = empty_actions, bool IgnoreUnknownActions = false> struct parser {
2431
#else
25-
template <typename Grammar, basic_fixed_string input, typename ActionSelector = empty_actions, bool IgnoreUnknownActions = true> struct parser { // in c++20
32+
template <typename Grammar, ctll::basic_fixed_string input, typename ActionSelector = empty_actions, bool IgnoreUnknownActions = false> struct parser { // in c++20
2633
#endif
2734
using Actions = ctll::conditional<IgnoreUnknownActions, ignore_unknown<ActionSelector>, identity<ActionSelector>>;
28-
static inline constexpr auto grammar = augment_grammar<Grammar>();
35+
using grammar = augment_grammar<Grammar>;
2936

30-
template <size_t Pos, typename Stack = void, typename Subject = void, decision Decision = decision::undecided> struct seed;
3137

3238
template <size_t Pos> static constexpr auto get_current_term() noexcept {
3339
if constexpr (Pos < input.size()) {
@@ -50,17 +56,17 @@ template <typename Grammar, basic_fixed_string input, typename ActionSelector =
5056
// if rule is accept => return true and subject
5157
template <size_t Pos, typename Terminal, typename Stack, typename Subject>
5258
static constexpr auto move(ctll::accept, Terminal, Stack, Subject) noexcept {
53-
return seed<Pos, Stack, Subject, decision::accept>();
59+
return result_of_parsing<true, Subject>{};
5460
}
5561
// if rule is reject => return false and subject
5662
template <size_t Pos, typename Terminal, typename Stack, typename Subject>
5763
static constexpr auto move(ctll::reject, Terminal, Stack, Subject) noexcept {
58-
return seed<Pos, Stack, Subject, decision::reject>();
64+
return result_of_parsing<false, Subject>{};
5965
}
6066
// if rule is pop_input => move to next character
6167
template <size_t Pos, typename Terminal, typename Stack, typename Subject>
62-
static constexpr auto move(ctll::pop_input, Terminal, Stack, Subject) noexcept {
63-
return seed<Pos+1, Stack, Subject, decision::undecided>();
68+
static constexpr auto move(ctll::pop_input, Terminal, Stack stack, Subject subject) noexcept {
69+
return decide<Pos+1>(stack, subject);
6470
}
6571
// if rule is string => push it to the front of stack
6672
template <size_t Pos, typename... Content, typename Terminal, typename Stack, typename Subject>
@@ -75,14 +81,17 @@ template <typename Grammar, basic_fixed_string input, typename ActionSelector =
7581
// if rule is string with current character at the beginning (term<V>) => move to next character
7682
// and push string without the character (quick LL(1))
7783
template <size_t Pos, auto V, typename... Content, typename Stack, typename Subject>
78-
static constexpr auto move(ctll::list<term<V>, Content...>, term<V>, Stack stack, Subject) noexcept {
79-
return seed<Pos+1, decltype(push_front(list<Content...>(), stack)), Subject, decision::undecided>();
84+
static constexpr auto move(ctll::list<term<V>, Content...>, term<V>, Stack stack, Subject subject) noexcept {
85+
return decide<Pos+1>(push_front(list<Content...>(), stack), subject);
86+
//return seed<Pos+1, decltype(push_front(list<Content...>(), stack)), Subject, decision::undecided>();
8087
}
8188
// if rule is string with any character at the beginning (compatible with current term<T>) => move to next character
8289
// and push string without the character (quick LL(1))
8390
template <size_t Pos, auto V, typename... Content, auto T, typename Stack, typename Subject>
84-
static constexpr auto move(ctll::list<anything, Content...>, term<T>, Stack stack, Subject) noexcept {
85-
return seed<Pos+1, decltype(push_front(list<Content...>(), stack)), Subject, decision::undecided>();
91+
static constexpr auto move(ctll::list<anything, Content...>, term<T>, Stack stack, Subject subject) noexcept {
92+
return decide<Pos+1>(push_front(list<Content...>(), stack), subject);
93+
94+
//return seed<Pos+1, decltype(push_front(list<Content...>(), stack)), Subject, decision::undecided>();
8695
}
8796
// decide if we need to take action or move
8897
template <size_t Pos, typename Stack, typename Subject> static constexpr auto decide(Stack previous_stack, Subject previous_subject) noexcept {
@@ -97,49 +106,26 @@ template <typename Grammar, basic_fixed_string input, typename ActionSelector =
97106

98107
// in case that semantic action is error => reject input
99108
if constexpr (std::is_same_v<ctll::reject, decltype(subject)>) {
100-
return seed<Pos, Stack, Subject, decision::reject>();
109+
return result_of_parsing<false, Subject>();
101110
} else {
102111
return decide<Pos>(stack, subject);
103112
}
104113
} else {
105114
// all other cases are ordinary for LL(1) parser
106115
auto current_term = get_current_term<Pos>();
107-
auto rule = decltype(grammar.rule(top_symbol,current_term))();
116+
auto rule = decltype(grammar::rule(top_symbol,current_term))();
108117
return move<Pos>(rule, current_term, stack, previous_subject);
109118
}
110119
}
111-
// helper type for trampoline
112-
113-
template <size_t Pos, typename Stack, typename Subject, decision Decision> struct seed {
114-
constexpr inline CTLL_FORCE_INLINE operator bool() const noexcept {
115-
return Decision == decision::accept;
116-
}
117-
118-
using output_type = Subject;
119-
120-
static constexpr auto parse() noexcept {
121-
// push current position to decide function with current stack and subject
122-
return decide<Pos>(Stack{}, Subject{});
123-
}
124-
125-
constexpr auto operator+(placeholder) const noexcept {
126-
if constexpr (Decision == decision::undecided) {
127-
// parse for current char (RPos) with previous stack and subject :)
128-
return decltype(seed<Pos, Stack, Subject, Decision>::parse()){};
129-
} else {
130-
// if there is decision already => just push it to the end of fold expression
131-
return *this;
132-
}
133-
}
134-
};
135120

136121
template <size_t> using index_placeholder = placeholder;
137122

123+
#if false
138124
// trampolines with folded expression
139125
template <typename Subject, size_t... Pos> static constexpr auto trampoline_decide(Subject, std::index_sequence<Pos...>) noexcept {
140126
// parse everything for first char and than for next and next ...
141127
// Pos+1 is needed as we want to finish calculation with epsilons on stack
142-
auto v = (seed<0, decltype(grammar.start_stack), Subject, decision::undecided>::parse() + ... + index_placeholder<Pos+1>());
128+
auto v = (seed<0, grammar::start_stack, Subject, decision::undecided>::parse() + ... + index_placeholder<Pos+1>());
143129
//id(v);
144130
return v;
145131
}
@@ -148,10 +134,11 @@ template <typename Grammar, basic_fixed_string input, typename ActionSelector =
148134
// there will be no recursion, just sequence long as the input
149135
return trampoline_decide(subject, std::make_index_sequence<input.size()>());
150136
}
137+
#endif
151138

152-
template <typename Subject = empty_subject> using output = decltype(trampoline_decide<Subject>());
153-
static inline constexpr bool correct = trampoline_decide(empty_subject());
154-
template <typename Subject = empty_subject> static inline constexpr bool correct_with = trampoline_decide<Subject>();
139+
template <typename Subject = empty_subject> using output = decltype(decide<0, typename grammar::start_stack, Subject>({}, {}));
140+
static inline constexpr bool correct = decide<0, typename grammar::start_stack, empty_subject>({}, {});
141+
template <typename Subject = empty_subject> static inline constexpr bool correct_with = decide<0, typename grammar::start_stack, Subject>({}, {});
155142
};
156143

157144
} // end of ctll namespace

include/ctre/functions.hpp

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
namespace ctre {
1212

13+
#if !__cpp_nontype_template_parameter_class
1314
// avoiding CTAD limitation in C++17
1415
template <typename CharT, size_t N> class pattern: public ctll::basic_fixed_string<CharT, N> {
1516
using parent = ctll::basic_fixed_string<CharT, N>;
@@ -27,67 +28,73 @@ template <typename CharT, size_t N> class fixed_string: public ctll::basic_fixed
2728
};
2829

2930
template <typename CharT, size_t N> fixed_string(const CharT (&)[N]) -> fixed_string<CharT, N>;
31+
#endif
3032

3133
#if __cpp_nontype_template_parameter_class
32-
template <basic_fixed_string input> CTRE_FLATTEN constexpr CTRE_FORCE_INLINE auto re() noexcept {
34+
template <ctll::basic_fixed_string input> CTRE_FLATTEN constexpr CTRE_FORCE_INLINE auto re() noexcept {
3335
#else
3436
template <auto & input> CTRE_FLATTEN constexpr CTRE_FORCE_INLINE auto re() noexcept {
35-
using tmp = typename ctll::parser<ctre::pcre, input, ctre::pcre_actions>::template output<pcre_context<>>;
37+
#endif
38+
constexpr auto _input = input;
39+
using tmp = typename ctll::parser<ctre::pcre, _input, ctre::pcre_actions>::template output<pcre_context<>>;
3640
static_assert(tmp(), "Regular Expression contains syntax error.");
3741
using re = decltype(front(typename tmp::output_type::stack_type()));
3842
return ctre::regular_expression(re());
3943
}
40-
#endif
44+
4145

4246
// in moment when we get C++20 support this will start to work :)
4347

44-
#if __cpp_nontype_template_parameter_class
45-
template <basic_fixed_string input> CTRE_FLATTEN constexpr CTRE_FORCE_INLINE auto match(std::string_view sv) noexcept {
48+
template <typename T> void identify(T);
4649

47-
using tmp = typename ctll::parser<ctre::pcre, input, ctre::pcre_actions>::template output<pcre_context<>>;
50+
#if __cpp_nontype_template_parameter_class
51+
template <ctll::basic_fixed_string input> CTRE_FLATTEN constexpr CTRE_FORCE_INLINE auto match(std::string_view sv) noexcept {
52+
constexpr auto _input = input;
53+
using tmp = typename ctll::parser<ctre::pcre, _input, ctre::pcre_actions>::template output<pcre_context<>>;
4854
static_assert(tmp(), "Regular Expression contains syntax error.");
49-
using re = decltype(front(typename tmp::output_type::stack_type()));
50-
auto re_obj = ctre::regular_expression(re());
55+
using re = decltype(ctll::front(typename tmp::output_type::stack_type()));
56+
auto re_obj = ctre::regular_expression<re>(re());
5157
return re_obj.match(sv);
5258
}
5359
#else
5460
template <auto & input> CTRE_FLATTEN constexpr CTRE_FORCE_INLINE auto match(std::string_view sv) noexcept {
5561

5662
using tmp = typename ctll::parser<ctre::pcre, input, ctre::pcre_actions>::template output<pcre_context<>>;
5763
static_assert(tmp(), "Regular Expression contains syntax error.");
58-
using re = decltype(front(typename tmp::output_type::stack_type()));
59-
auto re_obj = ctre::regular_expression(re());
64+
using re = decltype(ctll::front(typename tmp::output_type::stack_type()));
65+
auto re_obj = ctre::regular_expression<re>(re());
6066
return re_obj.match(sv);
6167
}
6268
#endif
6369

6470

6571
#if __cpp_nontype_template_parameter_class
66-
template <basic_fixed_string input, typename ForwardIt> CTRE_FLATTEN constexpr CTRE_FORCE_INLINE auto match(ForwardIt first, ForwardIt last) noexcept {
67-
68-
using tmp = typename ctll::parser<ctre::pcre, input, ctre::pcre_actions>::template output<pcre_context<>>;
72+
template <ctll::basic_fixed_string input, typename ForwardIt> CTRE_FLATTEN constexpr CTRE_FORCE_INLINE auto match(ForwardIt first, ForwardIt last) noexcept {
73+
constexpr auto _input = input;
74+
using tmp = typename ctll::parser<ctre::pcre, _input, ctre::pcre_actions>::template output<pcre_context<>>;
6975
static_assert(tmp(), "Regular Expression contains syntax error.");
70-
using re = decltype(front(typename tmp::output_type::stack_type()));
76+
using re = decltype(ctll::front(typename tmp::output_type::stack_type()));
7177
return ctre::regular_expression(re()).match(first, last);
7278
}
7379
#else
7480
template <auto & input, typename ForwardIt> CTRE_FLATTEN constexpr CTRE_FORCE_INLINE auto match(ForwardIt first, ForwardIt last) noexcept {
75-
76-
using tmp = typename ctll::parser<ctre::pcre, input, ctre::pcre_actions>::template output<pcre_context<>>;
81+
constexpr auto _input = input;
82+
using tmp = typename ctll::parser<ctre::pcre, _input, ctre::pcre_actions>::template output<pcre_context<>>;
7783
static_assert(tmp(), "Regular Expression contains syntax error.");
78-
using re = decltype(front(typename tmp::output_type::stack_type()));
84+
using re = decltype(ctll::front(typename tmp::output_type::stack_type()));
7985
auto re_obj = ctre::regular_expression(re());
8086
return re_obj.match(first,last);
8187
}
8288
#endif
8389

8490

8591
#if __cpp_nontype_template_parameter_class
86-
template <basic_fixed_string input> CTRE_FLATTEN constexpr CTRE_FORCE_INLINE auto search(std::string_view sv) noexcept {
92+
template <ctll::basic_fixed_string input> CTRE_FLATTEN constexpr CTRE_FORCE_INLINE auto search(std::string_view sv) noexcept {
8793

88-
using tmp = typename ctll::parser<ctre::pcre, input, ctre::pcre_actions>::template output<pcre_context<>>;
94+
constexpr auto _input = input;
95+
using tmp = typename ctll::parser<ctre::pcre, _input, ctre::pcre_actions>::template output<pcre_context<>>;
8996
static_assert(tmp(), "Regular Expression contains syntax error.");
90-
using re = decltype(front(typename tmp::output_type::stack_type()));
97+
using re = decltype(ctll::front(typename tmp::output_type::stack_type()));
9198
auto re_obj = ctre::regular_expression(re());
9299
return re_obj.search(sv);
93100
}
@@ -96,19 +103,19 @@ template <auto & input> CTRE_FLATTEN constexpr CTRE_FORCE_INLINE auto search(std
96103

97104
using tmp = typename ctll::parser<ctre::pcre, input, ctre::pcre_actions>::template output<pcre_context<>>;
98105
static_assert(tmp(), "Regular Expression contains syntax error.");
99-
using re = decltype(front(typename tmp::output_type::stack_type()));
106+
using re = decltype(ctll::front(typename tmp::output_type::stack_type()));
100107
auto re_obj = ctre::regular_expression(re());
101108
return re_obj.search(sv);
102109
}
103110
#endif
104111

105112

106113
#if __cpp_nontype_template_parameter_class
107-
template <basic_fixed_string input, typename ForwardIt> CTRE_FLATTEN constexpr CTRE_FORCE_INLINE auto search(ForwardIt first, ForwardIt last) noexcept {
108-
109-
using tmp = typename ctll::parser<ctre::pcre, input, ctre::pcre_actions>::template output<pcre_context<>>;
114+
template <ctll::basic_fixed_string input, typename ForwardIt> CTRE_FLATTEN constexpr CTRE_FORCE_INLINE auto search(ForwardIt first, ForwardIt last) noexcept {
115+
constexpr auto _input = input;
116+
using tmp = typename ctll::parser<ctre::pcre, _input, ctre::pcre_actions>::template output<pcre_context<>>;
110117
static_assert(tmp(), "Regular Expression contains syntax error.");
111-
using re = decltype(front(typename tmp::output_type::stack_type()));
118+
using re = decltype(ctll::front(typename tmp::output_type::stack_type()));
112119
auto re_obj = ctre::regular_expression(re());
113120
return re_obj.search(first, last);
114121
}
@@ -117,7 +124,7 @@ template <auto & input, typename ForwardIt> CTRE_FLATTEN constexpr CTRE_FORCE_IN
117124

118125
using tmp = typename ctll::parser<ctre::pcre, input, ctre::pcre_actions>::template output<pcre_context<>>;
119126
static_assert(tmp(), "Regular Expression contains syntax error.");
120-
using re = decltype(front(typename tmp::output_type::stack_type()));
127+
using re = decltype(ctll::front(typename tmp::output_type::stack_type()));
121128
auto re_obj = ctre::regular_expression(re());
122129
return re_obj.search(first, last);
123130
}

include/ctre/iterators.hpp

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,6 @@ template <typename BeginIterator, typename EndIterator, typename RE> constexpr a
5252
return regex_iterator<BeginIterator, EndIterator, RE>(begin, end);
5353
}
5454

55-
#if __cpp_nontype_template_parameter_class
56-
template <basic_fixed_string input, typename Subject> CTRE_FLATTEN constexpr CTRE_FORCE_INLINE auto iterator(BeginIterator begin, EndIterator end) noexcept {
57-
58-
using tmp = typename ctll::parser<ctre::pcre, input, ctre::pcre_actions>::template output<pcre_context<>>;
59-
static_assert(tmp(), "Regular Expression contains syntax error.");
60-
using re = decltype(front(typename tmp::output_type::stack_type()));
61-
return iterator(begin, end, re);
62-
}
63-
#endif
64-
6555
constexpr auto iterator() noexcept {
6656
return regex_end_iterator{};
6757
}
@@ -71,13 +61,25 @@ template <typename Subject, typename RE> constexpr auto iterator(const Subject &
7161
}
7262

7363

64+
7465
#if __cpp_nontype_template_parameter_class
75-
template <basic_fixed_string input, typename Subject> CTRE_FLATTEN constexpr CTRE_FORCE_INLINE auto iterator(const Subject & subject) noexcept {
66+
template <ctll::basic_fixed_string input, typename BeginIterator, typename EndIterator> CTRE_FLATTEN constexpr CTRE_FORCE_INLINE auto iterator(BeginIterator begin, EndIterator end) noexcept {
67+
constexpr auto _input = input;
68+
using tmp = typename ctll::parser<ctre::pcre, _input, ctre::pcre_actions>::template output<pcre_context<>>;
69+
static_assert(tmp(), "Regular Expression contains syntax error.");
70+
using re = decltype(front(typename tmp::output_type::stack_type()));
71+
return iterator(begin, end, re());
72+
}
73+
#endif
7674

77-
using tmp = typename ctll::parser<ctre::pcre, input, ctre::pcre_actions>::template output<pcre_context<>>;
75+
76+
#if __cpp_nontype_template_parameter_class
77+
template <ctll::basic_fixed_string input, typename Subject> CTRE_FLATTEN constexpr CTRE_FORCE_INLINE auto iterator(const Subject & subject) noexcept {
78+
constexpr auto _input = input;
79+
using tmp = typename ctll::parser<ctre::pcre, _input, ctre::pcre_actions>::template output<pcre_context<>>;
7880
static_assert(tmp(), "Regular Expression contains syntax error.");
7981
using re = decltype(front(typename tmp::output_type::stack_type()));
80-
return iterator(subject.begin(), subject.end(), re);
82+
return iterator(subject.begin(), subject.end(), re());
8183
}
8284
#endif
8385

0 commit comments

Comments
 (0)