LCOV - code coverage report
Current view: top level - usr/include/c++/8/bits - regex_compiler.h (source / functions) Hit Total Coverage
Test: ctest_coverage.info Lines: 63 117 53.8 %
Date: 2023-11-02 14:27:30 Functions: 23 94 24.5 %

          Line data    Source code
       1             : // class template regex -*- C++ -*-
       2             : 
       3             : // Copyright (C) 2010-2018 Free Software Foundation, Inc.
       4             : //
       5             : // This file is part of the GNU ISO C++ Library.  This library is free
       6             : // software; you can redistribute it and/or modify it under the
       7             : // terms of the GNU General Public License as published by the
       8             : // Free Software Foundation; either version 3, or (at your option)
       9             : // any later version.
      10             : 
      11             : // This library is distributed in the hope that it will be useful,
      12             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             : // GNU General Public License for more details.
      15             : 
      16             : // Under Section 7 of GPL version 3, you are granted additional
      17             : // permissions described in the GCC Runtime Library Exception, version
      18             : // 3.1, as published by the Free Software Foundation.
      19             : 
      20             : // You should have received a copy of the GNU General Public License and
      21             : // a copy of the GCC Runtime Library Exception along with this program;
      22             : // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      23             : // <http://www.gnu.org/licenses/>.
      24             : 
      25             : /**
      26             :  *  @file bits/regex_compiler.h
      27             :  *  This is an internal header file, included by other library headers.
      28             :  *  Do not attempt to use it directly. @headername{regex}
      29             :  */
      30             : 
      31             : namespace std _GLIBCXX_VISIBILITY(default)
      32             : {
      33             : _GLIBCXX_BEGIN_NAMESPACE_VERSION
      34             : _GLIBCXX_BEGIN_NAMESPACE_CXX11
      35             : 
      36             :   template<typename>
      37             :     class regex_traits;
      38             : 
      39             : _GLIBCXX_END_NAMESPACE_CXX11
      40             : 
      41             : namespace __detail
      42             : {
      43             :   /**
      44             :    * @addtogroup regex-detail
      45             :    * @{
      46             :    */
      47             : 
      48             :   template<typename, bool, bool>
      49             :     struct _BracketMatcher;
      50             : 
      51             :   /**
      52             :    * @brief Builds an NFA from an input iterator range.
      53             :    *
      54             :    * The %_TraitsT type should fulfill requirements [28.3].
      55             :    */
      56             :   template<typename _TraitsT>
      57             :     class _Compiler
      58             :     {
      59             :     public:
      60             :       typedef typename _TraitsT::char_type        _CharT;
      61             :       typedef const _CharT*                       _IterT;
      62             :       typedef _NFA<_TraitsT>                        _RegexT;
      63             :       typedef regex_constants::syntax_option_type _FlagT;
      64             : 
      65             :       _Compiler(_IterT __b, _IterT __e,
      66             :                 const typename _TraitsT::locale_type& __traits, _FlagT __flags);
      67             : 
      68             :       shared_ptr<const _RegexT>
      69           0 :       _M_get_nfa()
      70           0 :       { return std::move(_M_nfa); }
      71             : 
      72             :     private:
      73             :       typedef _Scanner<_CharT>               _ScannerT;
      74             :       typedef typename _TraitsT::string_type _StringT;
      75             :       typedef typename _ScannerT::_TokenT    _TokenT;
      76             :       typedef _StateSeq<_TraitsT>            _StateSeqT;
      77             :       typedef std::stack<_StateSeqT>         _StackT;
      78             :       typedef std::ctype<_CharT>             _CtypeT;
      79             : 
      80             :       // accepts a specific token or returns false.
      81             :       bool
      82             :       _M_match_token(_TokenT __token);
      83             : 
      84             :       void
      85             :       _M_disjunction();
      86             : 
      87             :       void
      88             :       _M_alternative();
      89             : 
      90             :       bool
      91             :       _M_term();
      92             : 
      93             :       bool
      94             :       _M_assertion();
      95             : 
      96             :       bool
      97             :       _M_quantifier();
      98             : 
      99             :       bool
     100             :       _M_atom();
     101             : 
     102             :       bool
     103             :       _M_bracket_expression();
     104             : 
     105             :       template<bool __icase, bool __collate>
     106             :         void
     107             :         _M_insert_any_matcher_ecma();
     108             : 
     109             :       template<bool __icase, bool __collate>
     110             :         void
     111             :         _M_insert_any_matcher_posix();
     112             : 
     113             :       template<bool __icase, bool __collate>
     114             :         void
     115             :         _M_insert_char_matcher();
     116             : 
     117             :       template<bool __icase, bool __collate>
     118             :         void
     119             :         _M_insert_character_class_matcher();
     120             : 
     121             :       template<bool __icase, bool __collate>
     122             :         void
     123             :         _M_insert_bracket_matcher(bool __neg);
     124             : 
     125             :       // Cache of the last atom seen in a bracketed range expression.
     126             :       struct _BracketState
     127             :       {
     128             :         enum class _Type : char { _None, _Char, _Class } _M_type = _Type::_None;
     129             :         _CharT _M_char;
     130             : 
     131             :         void
     132         523 :         set(_CharT __c) noexcept { _M_type = _Type::_Char; _M_char = __c; }
     133             : 
     134             :         _GLIBCXX_NODISCARD _CharT
     135         523 :         get() const noexcept { return _M_char; }
     136             : 
     137             :         void
     138         210 :         reset(_Type __t = _Type::_None) noexcept { _M_type = __t; }
     139             : 
     140             :         explicit operator bool() const noexcept
     141             :         { return _M_type != _Type::_None; }
     142             : 
     143             :         // Previous token was a single character.
     144             :         _GLIBCXX_NODISCARD bool
     145         769 :         _M_is_char() const noexcept { return _M_type == _Type::_Char; }
     146             : 
     147             :         // Previous token was a character class, equivalent class,
     148             :         // collating symbol etc.
     149             :         _GLIBCXX_NODISCARD bool
     150         174 :         _M_is_class() const noexcept { return _M_type == _Type::_Class; }
     151             :       };
     152             : 
     153             :       template<bool __icase, bool __collate>
     154             :         using _BracketMatcher
     155             :           = std::__detail::_BracketMatcher<_TraitsT, __icase, __collate>;
     156             : 
     157             :       // Returns true if successfully parsed one term and should continue
     158             :       // compiling a bracket expression.
     159             :       // Returns false if the compiler should move on.
     160             :       template<bool __icase, bool __collate>
     161             :         bool
     162             :         _M_expression_term(_BracketState& __last_char,
     163             :                            _BracketMatcher<__icase, __collate>& __matcher);
     164             : 
     165             :       int
     166             :       _M_cur_int_value(int __radix);
     167             : 
     168             :       bool
     169             :       _M_try_char();
     170             : 
     171             :       _StateSeqT
     172     5077949 :       _M_pop()
     173             :       {
     174     5077949 :         auto ret = _M_stack.top();
     175     5077949 :         _M_stack.pop();
     176     5077949 :         return ret;
     177             :       }
     178             : 
     179             :       _FlagT              _M_flags;
     180             :       _ScannerT           _M_scanner;
     181             :       shared_ptr<_RegexT> _M_nfa;
     182             :       _StringT            _M_value;
     183             :       _StackT             _M_stack;
     184             :       const _TraitsT&     _M_traits;
     185             :       const _CtypeT&      _M_ctype;
     186             :     };
     187             : 
     188             :   template<typename _Tp>
     189             :     struct __has_contiguous_iter : std::false_type { };
     190             : 
     191             :   template<typename _Ch, typename _Tr, typename _Alloc>
     192             :     struct __has_contiguous_iter<std::basic_string<_Ch, _Tr, _Alloc>>
     193             :     : std::true_type
     194             :     { };
     195             : 
     196             :   template<typename _Tp, typename _Alloc>
     197             :     struct __has_contiguous_iter<std::vector<_Tp, _Alloc>>
     198             :     : std::true_type
     199             :     { };
     200             : 
     201             :   template<typename _Tp>
     202             :     struct __is_contiguous_normal_iter : std::false_type { };
     203             : 
     204             :   template<typename _CharT>
     205             :     struct __is_contiguous_normal_iter<_CharT*> : std::true_type { };
     206             : 
     207             :   template<typename _Tp, typename _Cont>
     208             :     struct
     209             :     __is_contiguous_normal_iter<__gnu_cxx::__normal_iterator<_Tp, _Cont>>
     210             :     : __has_contiguous_iter<_Cont>::type
     211             :     { };
     212             : 
     213             :   template<typename _Iter, typename _TraitsT>
     214             :     using __enable_if_contiguous_normal_iter
     215             :       = typename enable_if< __is_contiguous_normal_iter<_Iter>::value,
     216             :                            std::shared_ptr<const _NFA<_TraitsT>> >::type;
     217             : 
     218             :   template<typename _Iter, typename _TraitsT>
     219             :     using __disable_if_contiguous_normal_iter
     220             :       = typename enable_if< !__is_contiguous_normal_iter<_Iter>::value,
     221             :                            std::shared_ptr<const _NFA<_TraitsT>> >::type;
     222             : 
     223             :   template<typename _TraitsT, typename _FwdIter>
     224             :     inline __enable_if_contiguous_normal_iter<_FwdIter, _TraitsT>
     225           0 :     __compile_nfa(_FwdIter __first, _FwdIter __last,
     226             :                   const typename _TraitsT::locale_type& __loc,
     227             :                   regex_constants::syntax_option_type __flags)
     228             :     {
     229           0 :       size_t __len = __last - __first;
     230           0 :       const auto* __cfirst = __len ? std::__addressof(*__first) : nullptr;
     231             :       using _Cmplr = _Compiler<_TraitsT>;
     232           0 :       return _Cmplr(__cfirst, __cfirst + __len, __loc, __flags)._M_get_nfa();
     233             :     }
     234             : 
     235             :   template<typename _TraitsT, typename _FwdIter>
     236             :     inline __disable_if_contiguous_normal_iter<_FwdIter, _TraitsT>
     237             :     __compile_nfa(_FwdIter __first, _FwdIter __last,
     238             :                   const typename _TraitsT::locale_type& __loc,
     239             :                   regex_constants::syntax_option_type __flags)
     240             :     {
     241             :       const basic_string<typename _TraitsT::char_type> __str(__first, __last);
     242             :       return __compile_nfa<_TraitsT>(__str.data(), __str.data() + __str.size(),
     243             :                                      __loc, __flags);
     244             :     }
     245             : 
     246             :   // [28.13.14]
     247             :   template<typename _TraitsT, bool __icase, bool __collate>
     248             :     class _RegexTranslatorBase
     249             :     {
     250             :     public:
     251             :       typedef typename _TraitsT::char_type            _CharT;
     252             :       typedef typename _TraitsT::string_type          _StringT;
     253             :       typedef _StringT _StrTransT;
     254             : 
     255             :       explicit
     256           0 :       _RegexTranslatorBase(const _TraitsT& __traits)
     257           0 :       : _M_traits(__traits)
     258           0 :       { }
     259             : 
     260             :       _CharT
     261           0 :       _M_translate(_CharT __ch) const
     262             :       {
     263             :         if (__icase)
     264           0 :           return _M_traits.translate_nocase(__ch);
     265             :         else if (__collate)
     266           0 :           return _M_traits.translate(__ch);
     267             :         else
     268             :           return __ch;
     269             :       }
     270             : 
     271             :       _StrTransT
     272           0 :       _M_transform(_CharT __ch) const
     273             :       {
     274           0 :         _StrTransT __str(1, __ch);
     275           0 :         return _M_traits.transform(__str.begin(), __str.end());
     276             :       }
     277             : 
     278             :       // See LWG 523. It's not efficiently implementable when _TraitsT is not
     279             :       // std::regex_traits<>, and __collate is true. See specializations for
     280             :       // implementations of other cases.
     281             :       bool
     282           0 :       _M_match_range(const _StrTransT& __first, const _StrTransT& __last,
     283             :                      const _StrTransT& __s) const
     284           0 :       { return __first <= __s && __s <= __last; }
     285             : 
     286             :     protected:
     287           0 :       bool _M_in_range_icase(_CharT __first, _CharT __last, _CharT __ch) const
     288             :       {
     289             :         typedef std::ctype<_CharT> __ctype_type;
     290           0 :         const auto& __fctyp = use_facet<__ctype_type>(this->_M_traits.getloc());
     291           0 :         auto __lower = __fctyp.tolower(__ch);
     292           0 :         auto __upper = __fctyp.toupper(__ch);
     293           0 :         return (__first <= __lower && __lower <= __last)
     294           0 :           || (__first <= __upper && __upper <= __last);
     295             :       }
     296             : 
     297             :       const _TraitsT& _M_traits;
     298             :     };
     299             : 
     300             :   template<typename _TraitsT, bool __icase, bool __collate>
     301             :     class _RegexTranslator
     302             :     : public _RegexTranslatorBase<_TraitsT, __icase, __collate>
     303             :     {
     304             :     public:
     305             :       typedef _RegexTranslatorBase<_TraitsT, __icase, __collate> _Base;
     306             :       using _Base::_Base;
     307             :     };
     308             : 
     309             :   template<typename _TraitsT, bool __icase>
     310             :     class _RegexTranslator<_TraitsT, __icase, false>
     311             :     : public _RegexTranslatorBase<_TraitsT, __icase, false>
     312             :     {
     313             :     public:
     314             :       typedef _RegexTranslatorBase<_TraitsT, __icase, false> _Base;
     315             :       typedef typename _Base::_CharT _CharT;
     316             :       typedef _CharT _StrTransT;
     317             : 
     318             :       using _Base::_Base;
     319             : 
     320             :       _StrTransT
     321           0 :       _M_transform(_CharT __ch) const
     322           0 :       { return __ch; }
     323             : 
     324             :       bool
     325           0 :       _M_match_range(_CharT __first, _CharT __last, _CharT __ch) const
     326             :       {
     327             :         if (!__icase)
     328             :           return __first <= __ch && __ch <= __last;
     329           0 :         return this->_M_in_range_icase(__first, __last, __ch);
     330             :       }
     331             :     };
     332             : 
     333             :   template<typename _CharType>
     334             :     class _RegexTranslator<std::regex_traits<_CharType>, true, true>
     335             :     : public _RegexTranslatorBase<std::regex_traits<_CharType>, true, true>
     336             :     {
     337             :     public:
     338             :       typedef _RegexTranslatorBase<std::regex_traits<_CharType>, true, true>
     339             :         _Base;
     340             :       typedef typename _Base::_CharT _CharT;
     341             :       typedef typename _Base::_StrTransT _StrTransT;
     342             : 
     343             :       using _Base::_Base;
     344             : 
     345             :       bool
     346           0 :       _M_match_range(const _StrTransT& __first, const _StrTransT& __last,
     347             :                      const _StrTransT& __str) const
     348             :       {
     349             :         __glibcxx_assert(__first.size() == 1);
     350             :         __glibcxx_assert(__last.size() == 1);
     351             :         __glibcxx_assert(__str.size() == 1);
     352           0 :         return this->_M_in_range_icase(__first[0], __last[0], __str[0]);
     353             :       }
     354             :     };
     355             : 
     356             :   template<typename _TraitsT>
     357             :     class _RegexTranslator<_TraitsT, false, false>
     358             :     {
     359             :     public:
     360             :       typedef typename _TraitsT::char_type _CharT;
     361             :       typedef _CharT                       _StrTransT;
     362             : 
     363             :       explicit
     364     2231101 :       _RegexTranslator(const _TraitsT&)
     365     2231101 :       { }
     366             : 
     367             :       _CharT
     368     2447392 :       _M_translate(_CharT __ch) const
     369     2447392 :       { return __ch; }
     370             : 
     371             :       _StrTransT
     372       66047 :       _M_transform(_CharT __ch) const
     373       66047 :       { return __ch; }
     374             : 
     375             :       bool
     376       42934 :       _M_match_range(_CharT __first, _CharT __last, _CharT __ch) const
     377       42934 :       { return __first <= __ch && __ch <= __last; }
     378             :     };
     379             : 
     380             :   template<typename _TraitsT, bool __is_ecma, bool __icase, bool __collate>
     381             :     struct _AnyMatcher;
     382             : 
     383             :   template<typename _TraitsT, bool __icase, bool __collate>
     384             :     struct _AnyMatcher<_TraitsT, false, __icase, __collate>
     385             :     {
     386             :       typedef _RegexTranslator<_TraitsT, __icase, __collate> _TransT;
     387             :       typedef typename _TransT::_CharT                       _CharT;
     388             : 
     389             :       explicit
     390           0 :       _AnyMatcher(const _TraitsT& __traits)
     391           0 :       : _M_translator(__traits)
     392           0 :       { }
     393             : 
     394             :       bool
     395           0 :       operator()(_CharT __ch) const
     396             :       {
     397           0 :         static auto __nul = _M_translator._M_translate('\0');
     398           0 :         return _M_translator._M_translate(__ch) != __nul;
     399             :       }
     400             : 
     401             :       _TransT _M_translator;
     402             :     };
     403             : 
     404             :   template<typename _TraitsT, bool __icase, bool __collate>
     405             :     struct _AnyMatcher<_TraitsT, true, __icase, __collate>
     406             :     {
     407             :       typedef _RegexTranslator<_TraitsT, __icase, __collate> _TransT;
     408             :       typedef typename _TransT::_CharT                       _CharT;
     409             : 
     410             :       explicit
     411          73 :       _AnyMatcher(const _TraitsT& __traits)
     412          73 :       : _M_translator(__traits)
     413          73 :       { }
     414             : 
     415             :       bool
     416        2522 :       operator()(_CharT __ch) const
     417        2522 :       { return _M_apply(__ch, typename is_same<_CharT, char>::type()); }
     418             : 
     419             :       bool
     420        2522 :       _M_apply(_CharT __ch, true_type) const
     421             :       {
     422        2522 :         auto __c = _M_translator._M_translate(__ch);
     423        2522 :         auto __n = _M_translator._M_translate('\n');
     424        2522 :         auto __r = _M_translator._M_translate('\r');
     425        2522 :         return __c != __n && __c != __r;
     426             :       }
     427             : 
     428             :       bool
     429             :       _M_apply(_CharT __ch, false_type) const
     430             :       {
     431             :         auto __c = _M_translator._M_translate(__ch);
     432             :         auto __n = _M_translator._M_translate('\n');
     433             :         auto __r = _M_translator._M_translate('\r');
     434             :         auto __u2028 = _M_translator._M_translate(u'\u2028');
     435             :         auto __u2029 = _M_translator._M_translate(u'\u2029');
     436             :         return __c != __n && __c != __r && __c != __u2028 && __c != __u2029;
     437             :       }
     438             : 
     439             :       _TransT _M_translator;
     440             :     };
     441             : 
     442             :   template<typename _TraitsT, bool __icase, bool __collate>
     443             :     struct _CharMatcher
     444             :     {
     445             :       typedef _RegexTranslator<_TraitsT, __icase, __collate> _TransT;
     446             :       typedef typename _TransT::_CharT                       _CharT;
     447             : 
     448     2230770 :       _CharMatcher(_CharT __ch, const _TraitsT& __traits)
     449     2230770 :       : _M_translator(__traits), _M_ch(_M_translator._M_translate(__ch))
     450     2230770 :       { }
     451             : 
     452             :       bool
     453      142659 :       operator()(_CharT __ch) const
     454      142659 :       { return _M_ch == _M_translator._M_translate(__ch); }
     455             : 
     456             :       _TransT _M_translator;
     457             :       _CharT  _M_ch;
     458             :     };
     459             : 
     460             :   /// Matches a character range (bracket expression)
     461             :   template<typename _TraitsT, bool __icase, bool __collate>
     462             :     struct _BracketMatcher
     463             :     {
     464             :     public:
     465             :       typedef _RegexTranslator<_TraitsT, __icase, __collate> _TransT;
     466             :       typedef typename _TransT::_CharT                       _CharT;
     467             :       typedef typename _TransT::_StrTransT                   _StrTransT;
     468             :       typedef typename _TraitsT::string_type                 _StringT;
     469             :       typedef typename _TraitsT::char_class_type             _CharClassT;
     470             : 
     471             :     public:
     472         258 :       _BracketMatcher(bool __is_non_matching,
     473             :                       const _TraitsT& __traits)
     474             :       : _M_class_set(0), _M_translator(__traits), _M_traits(__traits),
     475         258 :       _M_is_non_matching(__is_non_matching)
     476         258 :       { }
     477             : 
     478             :       bool
     479        4072 :       operator()(_CharT __ch) const
     480             :       {
     481             :         _GLIBCXX_DEBUG_ASSERT(_M_is_ready);
     482        4072 :         return _M_apply(__ch, _UseCache());
     483             :       }
     484             : 
     485             :       void
     486         349 :       _M_add_char(_CharT __c)
     487             :       {
     488         349 :         _M_char_set.push_back(_M_translator._M_translate(__c));
     489             :         _GLIBCXX_DEBUG_ONLY(_M_is_ready = false);
     490         349 :       }
     491             : 
     492             :       _StringT
     493           0 :       _M_add_collate_element(const _StringT& __s)
     494             :       {
     495           0 :         auto __st = _M_traits.lookup_collatename(__s.data(),
     496           0 :                                                  __s.data() + __s.size());
     497           0 :         if (__st.empty())
     498           0 :           __throw_regex_error(regex_constants::error_collate,
     499             :                               "Invalid collate element.");
     500           0 :         _M_char_set.push_back(_M_translator._M_translate(__st[0]));
     501             :         _GLIBCXX_DEBUG_ONLY(_M_is_ready = false);
     502           0 :         return __st;
     503             :       }
     504             : 
     505             :       void
     506           0 :       _M_add_equivalence_class(const _StringT& __s)
     507             :       {
     508           0 :         auto __st = _M_traits.lookup_collatename(__s.data(),
     509           0 :                                                  __s.data() + __s.size());
     510           0 :         if (__st.empty())
     511           0 :           __throw_regex_error(regex_constants::error_collate,
     512             :                               "Invalid equivalence class.");
     513           0 :         __st = _M_traits.transform_primary(__st.data(),
     514           0 :                                            __st.data() + __st.size());
     515           0 :         _M_equiv_set.push_back(__st);
     516             :         _GLIBCXX_DEBUG_ONLY(_M_is_ready = false);
     517           0 :       }
     518             : 
     519             :       // __neg should be true for \D, \S and \W only.
     520             :       void
     521          36 :       _M_add_character_class(const _StringT& __s, bool __neg)
     522             :       {
     523          36 :         auto __mask = _M_traits.lookup_classname(__s.data(),
     524          36 :                                                  __s.data() + __s.size(),
     525             :                                                  __icase);
     526          36 :         if (__mask == 0)
     527           0 :           __throw_regex_error(regex_constants::error_collate,
     528             :                               "Invalid character class.");
     529          36 :         if (!__neg)
     530          36 :           _M_class_set |= __mask;
     531             :         else
     532           0 :           _M_neg_class_set.push_back(__mask);
     533             :         _GLIBCXX_DEBUG_ONLY(_M_is_ready = false);
     534          36 :       }
     535             : 
     536             :       void
     537         174 :       _M_make_range(_CharT __l, _CharT __r)
     538             :       {
     539         174 :         if (__l > __r)
     540           0 :           __throw_regex_error(regex_constants::error_range,
     541             :                               "Invalid range in bracket expression.");
     542         174 :         _M_range_set.push_back(make_pair(_M_translator._M_transform(__l),
     543             :                                          _M_translator._M_transform(__r)));
     544             :         _GLIBCXX_DEBUG_ONLY(_M_is_ready = false);
     545         174 :       }
     546             : 
     547             :       void
     548         258 :       _M_ready()
     549             :       {
     550         258 :         std::sort(_M_char_set.begin(), _M_char_set.end());
     551         258 :         auto __end = std::unique(_M_char_set.begin(), _M_char_set.end());
     552         258 :         _M_char_set.erase(__end, _M_char_set.end());
     553         258 :         _M_make_cache(_UseCache());
     554             :         _GLIBCXX_DEBUG_ONLY(_M_is_ready = true);
     555         258 :       }
     556             : 
     557             :     private:
     558             :       // Currently we only use the cache for char
     559             :       typedef typename std::is_same<_CharT, char>::type _UseCache;
     560             : 
     561             :       static constexpr size_t
     562             :       _S_cache_size()
     563             :       {
     564             :         return 1ul << (sizeof(_CharT) * __CHAR_BIT__ * int(_UseCache::value));
     565             :       }
     566             : 
     567             :       struct _Dummy { };
     568             :       typedef typename std::conditional<_UseCache::value,
     569             :                                         std::bitset<_S_cache_size()>,
     570             :                                         _Dummy>::type _CacheT;
     571             :       typedef typename std::make_unsigned<_CharT>::type _UnsignedCharT;
     572             : 
     573             :       bool
     574             :       _M_apply(_CharT __ch, false_type) const;
     575             : 
     576             :       bool
     577        4072 :       _M_apply(_CharT __ch, true_type) const
     578        4072 :       { return _M_cache[static_cast<_UnsignedCharT>(__ch)]; }
     579             : 
     580             :       void
     581         258 :       _M_make_cache(true_type)
     582             :       {
     583       66306 :         for (unsigned __i = 0; __i < _M_cache.size(); __i++)
     584       66048 :           _M_cache[__i] = _M_apply(static_cast<_CharT>(__i), false_type());
     585         258 :       }
     586             : 
     587             :       void
     588             :       _M_make_cache(false_type)
     589             :       { }
     590             : 
     591             :     private:
     592             :       std::vector<_CharT>                       _M_char_set;
     593             :       std::vector<_StringT>                     _M_equiv_set;
     594             :       std::vector<pair<_StrTransT, _StrTransT>> _M_range_set;
     595             :       std::vector<_CharClassT>                  _M_neg_class_set;
     596             :       _CharClassT                               _M_class_set;
     597             :       _TransT                                   _M_translator;
     598             :       const _TraitsT&                           _M_traits;
     599             :       bool                                      _M_is_non_matching;
     600             :       _CacheT                                   _M_cache;
     601             : #ifdef _GLIBCXX_DEBUG
     602             :       bool                                      _M_is_ready = false;
     603             : #endif
     604             :     };
     605             : 
     606             :  //@} regex-detail
     607             : } // namespace __detail
     608             : _GLIBCXX_END_NAMESPACE_VERSION
     609             : } // namespace std
     610             : 
     611             : #include <bits/regex_compiler.tcc>

Generated by: LCOV version 1.16