32#ifndef _GLIBCXX_REGEX_STATE_LIMIT
33#define _GLIBCXX_REGEX_STATE_LIMIT 100000
36#pragma GCC diagnostic push
37#pragma GCC diagnostic ignored "-Wpedantic"
39namespace std _GLIBCXX_VISIBILITY(default)
41_GLIBCXX_BEGIN_NAMESPACE_VERSION
51 typedef long _StateIdT;
52 _GLIBCXX17_INLINE
constexpr _StateIdT _S_invalid_state_id = -1;
54 template<
typename _CharT>
55 using _Matcher = std::function<bool (_CharT)>;
62 _S_opcode_alternative,
65 _S_opcode_line_begin_assertion,
66 _S_opcode_line_end_assertion,
67 _S_opcode_word_boundary,
68 _S_opcode_subexpr_lookahead,
69 _S_opcode_subexpr_begin,
70 _S_opcode_subexpr_end,
86 size_t _M_backref_index;
97 __gnu_cxx::__aligned_membuf<_Matcher<char>> _M_matcher_storage;
101 explicit _State_base(
_Opcode __opcode) noexcept
102 : _M_opcode(__opcode), _M_next(_S_invalid_state_id)
107 _M_has_alt() const noexcept
109 return _M_opcode == _S_opcode_alternative
110 || _M_opcode == _S_opcode_repeat
111 || _M_opcode == _S_opcode_subexpr_lookahead;
124 template<
typename _Char_type>
125 struct _State : _State_base
127 typedef _Matcher<_Char_type> _MatcherT;
128 static_assert(
sizeof(_MatcherT) ==
sizeof(_Matcher<char>),
129 "std::function<bool(T)> has the same size as "
130 "std::function<bool(char)>");
131 static_assert(
alignof(_MatcherT) ==
alignof(_Matcher<char>),
132 "std::function<bool(T)> has the same alignment as "
133 "std::function<bool(char)>");
136 _State(
_Opcode __opcode) noexcept : _State_base(__opcode)
138 if (_M_opcode() == _S_opcode_match)
139 new (this->_M_matcher_storage._M_addr()) _MatcherT();
142 _State(
const _State& __rhs) : _State_base(__rhs)
144 if (__rhs._M_opcode() == _S_opcode_match)
145 new (this->_M_matcher_storage._M_addr())
146 _MatcherT(__rhs._M_get_matcher());
149 _State(_State&& __rhs) noexcept : _State_base(__rhs)
151 if (__rhs._M_opcode() == _S_opcode_match)
152 new (this->_M_matcher_storage._M_addr())
153 _MatcherT(
std::move(__rhs._M_get_matcher()));
157 operator=(
const _State&) =
delete;
161 if (_M_opcode() == _S_opcode_match)
162 _M_get_matcher().~_MatcherT();
168 _M_opcode() const noexcept
169 {
return _State_base::_M_opcode; }
172 _M_matches(_Char_type __char)
const
173 {
return _M_get_matcher()(__char); }
176 _M_get_matcher() noexcept
177 {
return *
static_cast<_MatcherT*
>(this->_M_matcher_storage._M_addr()); }
180 _M_get_matcher() const noexcept
182 return *
static_cast<const _MatcherT*
>(
183 this->_M_matcher_storage._M_addr());
192 _NFA_base(_FlagT __f) noexcept
193 : _M_flags(__f), _M_start_state(0), _M_subexpr_count(0),
194 _M_has_backref(
false)
197 _NFA_base(_NFA_base&&) =
default;
200 ~_NFA_base() =
default;
204 _M_options() const noexcept
208 _M_start() const noexcept
209 {
return _M_start_state; }
212 _M_sub_count() const noexcept
213 {
return _M_subexpr_count; }
215 _GLIBCXX_STD_C::vector<size_t> _M_paren_stack;
217 _StateIdT _M_start_state;
218 size_t _M_subexpr_count;
222 template<
typename _TraitsT>
224 : _NFA_base, _GLIBCXX_STD_C::vector<_State<typename _TraitsT::char_type>>
226 typedef typename _TraitsT::char_type _Char_type;
227 typedef _State<_Char_type> _StateT;
228 typedef _Matcher<_Char_type> _MatcherT;
230 _NFA(
const typename _TraitsT::locale_type& __loc, _FlagT __flags)
232 { _M_traits.imbue(__loc); }
235 _NFA(
const _NFA&) =
delete;
236 _NFA(_NFA&&) =
default;
241 auto __ret = _M_insert_state(_StateT(_S_opcode_accept));
246 _M_insert_alt(_StateIdT __next, _StateIdT __alt,
247 bool __neg __attribute__((__unused__)))
249 _StateT __tmp(_S_opcode_alternative);
252 __tmp._M_next = __next;
253 __tmp._M_alt = __alt;
254 return _M_insert_state(
std::move(__tmp));
258 _M_insert_repeat(_StateIdT __next, _StateIdT __alt,
bool __neg)
260 _StateT __tmp(_S_opcode_repeat);
263 __tmp._M_next = __next;
264 __tmp._M_alt = __alt;
265 __tmp._M_neg = __neg;
266 return _M_insert_state(
std::move(__tmp));
270 _M_insert_matcher(_MatcherT __m)
272 _StateT __tmp(_S_opcode_match);
274 return _M_insert_state(
std::move(__tmp));
278 _M_insert_subexpr_begin()
280 auto __id = this->_M_subexpr_count++;
281 this->_M_paren_stack.push_back(__id);
282 _StateT __tmp(_S_opcode_subexpr_begin);
283 __tmp._M_subexpr = __id;
284 return _M_insert_state(
std::move(__tmp));
288 _M_insert_subexpr_end()
290 _StateT __tmp(_S_opcode_subexpr_end);
291 __tmp._M_subexpr = this->_M_paren_stack.back();
292 this->_M_paren_stack.pop_back();
293 return _M_insert_state(
std::move(__tmp));
297 _M_insert_backref(
size_t __index);
300 _M_insert_line_begin()
301 {
return _M_insert_state(_StateT(_S_opcode_line_begin_assertion)); }
305 {
return _M_insert_state(_StateT(_S_opcode_line_end_assertion)); }
308 _M_insert_word_bound(
bool __neg)
310 _StateT __tmp(_S_opcode_word_boundary);
311 __tmp._M_neg = __neg;
312 return _M_insert_state(
std::move(__tmp));
316 _M_insert_lookahead(_StateIdT __alt,
bool __neg)
318 _StateT __tmp(_S_opcode_subexpr_lookahead);
319 __tmp._M_alt = __alt;
320 __tmp._M_neg = __neg;
321 return _M_insert_state(
std::move(__tmp));
326 {
return _M_insert_state(_StateT(_S_opcode_dummy)); }
329 _M_insert_state(_StateT __s)
332 if (this->
size() > _GLIBCXX_REGEX_STATE_LIMIT)
335 "Number of NFA states exceeds limit. Please use shorter regex "
336 "string, or use smaller brace expression, or make "
337 "_GLIBCXX_REGEX_STATE_LIMIT larger.");
338 return this->
size() - 1;
343 _M_eliminate_dummy();
356 template<
typename _TraitsT>
360 typedef _NFA<_TraitsT> _RegexT;
363 _StateSeq(_RegexT& __nfa, _StateIdT __s)
364 : _M_nfa(__nfa), _M_start(__s), _M_end(__s)
367 _StateSeq(_RegexT& __nfa, _StateIdT __s, _StateIdT __end)
368 : _M_nfa(__nfa), _M_start(__s), _M_end(__end)
373 _M_append(_StateIdT __id)
375 _M_nfa[_M_end]._M_next = __id;
381 _M_append(
const _StateSeq& __s)
383 _M_nfa[_M_end]._M_next = __s._M_start;
400_GLIBCXX_END_NAMESPACE_VERSION
403#pragma GCC diagnostic pop
basic_ostream< char > ostream
Base class for char output streams.
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
_Opcode
Operation codes that define the type of transitions within the base NFA that represents the regular e...
ISO C++ entities toplevel namespace is std.
Implementation details not part of the namespace std interface.
constexpr error_type error_space(_S_error_space)
syntax_option_type
This is a bitmask type indicating how to interpret the regex.
constexpr void push_back(const value_type &__x)
Add data to the end of the vector.
constexpr size_type size() const noexcept