Re: [PATCH 3/3] libstdc++: Optimize std::regex_traits lookup functions
Jonathan Wakely [Tuesday, 10 February 2026 22:59:30 CET]:
> On Tue, 10 Feb 2026 at 14:07, Tomasz Kaminski wrote:
> > That's a really cool idea, to switch on one character.
>
> […]
> 4) ... it's 20 years later, maybe optimizers have changed :-)
I actually looked at this because I wondered whether using SIMD would be
beneficial. But GCC takes the char, subtracts the minimum case ('a'), jumps
behind the block for anything greater than the maximum (unsigned, so anything
below is covered as well) and then does a table lookup for the remaining
(small) integer for an indirect jump. I love it.
The only way to potentially make it more efficient would be to have machine
code sections of equal size for the cases and compute the jump offset via
multiplication rather than table lookup. (If the table entry is not in cache,
it can stall for a long time with no way to do a speculative jump.)
--
──
Dr. Matthias Kretz https://mattkretz.github.io
GSI Helmholtz Center for Heavy Ion Research https://gsi.de
std::simd
──
signature.asc
Description: This is a digitally signed message part.
Re: [PATCH 3/3] libstdc++: Optimize std::regex_traits lookup functions
On Wed, Feb 11, 2026 at 1:21 AM Jonathan Wakely wrote:
> Optimize regex_traits::lookup_collatename and
> regex_traits::lookup_classname.
>
> For lookup_collatename we can hoist the static array into a
> non-dependent function, then call that for the regex_traits
> specialization without performing any narrowing operations via the ctype
> facet. For the regex_traits specialization we populate a
> std::string for the narrowed result, and call the non-dependent function.
>
> For lookup_classname we can avoid the static array entirely, replacing
> the iteration over that array with a nested switch that implements a
> kind of manually-unrolled trie, only match one char at a time until we
> either match a full string or get a mismatch. This avoids narrowing the
> entire input and storing it in a temporary string. This improves
> performance by 2-3x for -O2 and below (the benefit is much smaller for
> -O3).
>
> We can also check the input length for random access iterators, and
> reject any strings longer than "xdigit" without doing any work at all.
> For silly cases like [:xxx:]
> this gives a 100x improvement.
>
> libstdc++-v3/ChangeLog:
>
> * include/bits/regex.tcc (__detail::__lookup_collatename): New
> function.
> (regex_traits::lookup_collatename): Use new function. Elide
> redundant narrowing via ctype facet for regex_traits.
> (regex_traits::lookup_classname): Replace lookup table with
> handwritten prefix match.
>
> Reviewed-by: Tomasz Kamiński
> ---
>
> v2: Added comments to lookup_classname, e.g. "d" or "digit"
>
LGTM
>
> Tested x86_64-linux and aarch64-linux.
>
> libstdc++-v3/include/bits/regex.tcc | 428
> 1 file changed, 252 insertions(+), 176 deletions(-)
>
> diff --git a/libstdc++-v3/include/bits/regex.tcc
> b/libstdc++-v3/include/bits/regex.tcc
> index 7715d653df5d..2e7843537693 100644
> --- a/libstdc++-v3/include/bits/regex.tcc
> +++ b/libstdc++-v3/include/bits/regex.tcc
> @@ -106,163 +106,187 @@ namespace __detail
> }
>return __ret;
> }
> +
> + inline void
> + __lookup_collatename(string& __name) noexcept
> + {
> +static const char* const __collatenames[] =
> + {
> + "NUL",
> + "SOH",
> + "STX",
> + "ETX",
> + "EOT",
> + "ENQ",
> + "ACK",
> + "alert",
> + "backspace",
> + "tab",
> + "newline",
> + "vertical-tab",
> + "form-feed",
> + "carriage-return",
> + "SO",
> + "SI",
> + "DLE",
> + "DC1",
> + "DC2",
> + "DC3",
> + "DC4",
> + "NAK",
> + "SYN",
> + "ETB",
> + "CAN",
> + "EM",
> + "SUB",
> + "ESC",
> + "IS4",
> + "IS3",
> + "IS2",
> + "IS1",
> + "space",
> + "exclamation-mark",
> + "quotation-mark",
> + "number-sign",
> + "dollar-sign",
> + "percent-sign",
> + "ampersand",
> + "apostrophe",
> + "left-parenthesis",
> + "right-parenthesis",
> + "asterisk",
> + "plus-sign",
> + "comma",
> + "hyphen",
> + "period",
> + "slash",
> + "zero",
> + "one",
> + "two",
> + "three",
> + "four",
> + "five",
> + "six",
> + "seven",
> + "eight",
> + "nine",
> + "colon",
> + "semicolon",
> + "less-than-sign",
> + "equals-sign",
> + "greater-than-sign",
> + "question-mark",
> + "commercial-at",
> + "A",
> + "B",
> + "C",
> + "D",
> + "E",
> + "F",
> + "G",
> + "H",
> + "I",
> + "J",
> + "K",
> + "L",
> + "M",
> + "N",
> + "O",
> + "P",
> + "Q",
> + "R",
> + "S",
> + "T",
> + "U",
> + "V",
> + "W",
> + "X",
> + "Y",
> + "Z",
> + "left-square-bracket",
> + "backslash",
> + "right-square-bracket",
> + "circumflex",
> + "underscore",
> + "grave-accent",
> + "a",
> + "b",
> + "c",
> + "d",
> + "e",
> + "f",
> + "g",
> + "h",
> + "i",
> + "j",
> + "k",
> + "l",
> + "m",
> + "n",
> + "o",
> + "p",
> + "q",
> + "r",
> + "s",
> + "t",
> + "u",
> + "v",
> + "w",
> + "x",
> + "y",
> + "z",
> + "left-curly-bracket",
> + "vertical-line",
> + "right-curly-bracket",
> + "tilde",
> + "DEL",
> + };
> +
> +for (const auto& __it : __collatenames)
> + if (__name == __it)
> + {
> + __name.assign(1, static_cast(&__it - __collatenames));
> + return;
> + }
> +
> +__name.clear();
> + }
> +
>/// @endcond
> } // namespace __detail
>
> +#pragma GCC diagnostic push
> +#pragma GC
[PATCH 3/3] libstdc++: Optimize std::regex_traits lookup functions
Optimize regex_traits::lookup_collatename and
regex_traits::lookup_classname.
For lookup_collatename we can hoist the static array into a
non-dependent function, then call that for the regex_traits
specialization without performing any narrowing operations via the ctype
facet. For the regex_traits specialization we populate a
std::string for the narrowed result, and call the non-dependent function.
For lookup_classname we can avoid the static array entirely, replacing
the iteration over that array with a nested switch that implements a
kind of manually-unrolled trie, only match one char at a time until we
either match a full string or get a mismatch. This avoids narrowing the
entire input and storing it in a temporary string. This improves
performance by 2-3x for -O2 and below (the benefit is much smaller for
-O3).
We can also check the input length for random access iterators, and
reject any strings longer than "xdigit" without doing any work at all.
For silly cases like [:xxx:]
this gives a 100x improvement.
libstdc++-v3/ChangeLog:
* include/bits/regex.tcc (__detail::__lookup_collatename): New
function.
(regex_traits::lookup_collatename): Use new function. Elide
redundant narrowing via ctype facet for regex_traits.
(regex_traits::lookup_classname): Replace lookup table with
handwritten prefix match.
Reviewed-by: Tomasz Kamiński
---
v2: Added comments to lookup_classname, e.g. "d" or "digit"
Tested x86_64-linux and aarch64-linux.
libstdc++-v3/include/bits/regex.tcc | 428
1 file changed, 252 insertions(+), 176 deletions(-)
diff --git a/libstdc++-v3/include/bits/regex.tcc
b/libstdc++-v3/include/bits/regex.tcc
index 7715d653df5d..2e7843537693 100644
--- a/libstdc++-v3/include/bits/regex.tcc
+++ b/libstdc++-v3/include/bits/regex.tcc
@@ -106,163 +106,187 @@ namespace __detail
}
return __ret;
}
+
+ inline void
+ __lookup_collatename(string& __name) noexcept
+ {
+static const char* const __collatenames[] =
+ {
+ "NUL",
+ "SOH",
+ "STX",
+ "ETX",
+ "EOT",
+ "ENQ",
+ "ACK",
+ "alert",
+ "backspace",
+ "tab",
+ "newline",
+ "vertical-tab",
+ "form-feed",
+ "carriage-return",
+ "SO",
+ "SI",
+ "DLE",
+ "DC1",
+ "DC2",
+ "DC3",
+ "DC4",
+ "NAK",
+ "SYN",
+ "ETB",
+ "CAN",
+ "EM",
+ "SUB",
+ "ESC",
+ "IS4",
+ "IS3",
+ "IS2",
+ "IS1",
+ "space",
+ "exclamation-mark",
+ "quotation-mark",
+ "number-sign",
+ "dollar-sign",
+ "percent-sign",
+ "ampersand",
+ "apostrophe",
+ "left-parenthesis",
+ "right-parenthesis",
+ "asterisk",
+ "plus-sign",
+ "comma",
+ "hyphen",
+ "period",
+ "slash",
+ "zero",
+ "one",
+ "two",
+ "three",
+ "four",
+ "five",
+ "six",
+ "seven",
+ "eight",
+ "nine",
+ "colon",
+ "semicolon",
+ "less-than-sign",
+ "equals-sign",
+ "greater-than-sign",
+ "question-mark",
+ "commercial-at",
+ "A",
+ "B",
+ "C",
+ "D",
+ "E",
+ "F",
+ "G",
+ "H",
+ "I",
+ "J",
+ "K",
+ "L",
+ "M",
+ "N",
+ "O",
+ "P",
+ "Q",
+ "R",
+ "S",
+ "T",
+ "U",
+ "V",
+ "W",
+ "X",
+ "Y",
+ "Z",
+ "left-square-bracket",
+ "backslash",
+ "right-square-bracket",
+ "circumflex",
+ "underscore",
+ "grave-accent",
+ "a",
+ "b",
+ "c",
+ "d",
+ "e",
+ "f",
+ "g",
+ "h",
+ "i",
+ "j",
+ "k",
+ "l",
+ "m",
+ "n",
+ "o",
+ "p",
+ "q",
+ "r",
+ "s",
+ "t",
+ "u",
+ "v",
+ "w",
+ "x",
+ "y",
+ "z",
+ "left-curly-bracket",
+ "vertical-line",
+ "right-curly-bracket",
+ "tilde",
+ "DEL",
+ };
+
+for (const auto& __it : __collatenames)
+ if (__name == __it)
+ {
+ __name.assign(1, static_cast(&__it - __collatenames));
+ return;
+ }
+
+__name.clear();
+ }
+
/// @endcond
} // namespace __detail
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr
+
template
template
typename regex_traits<_Ch_type>::string_type
regex_traits<_Ch_type>::
lookup_collatename(_Fwd_iter __first, _Fwd_iter __last) const
{
- typedef std::ctype __ctype_type;
- const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
-
- static const char* const __collatenames[] =
- {
- "NUL",
- "SOH",
-
Re: [PATCH 3/3] libstdc++: Optimize std::regex_traits lookup functions
On Tue, 10 Feb 2026 at 14:07, Tomasz Kaminski wrote:
> On Mon, Feb 9, 2026 at 9:43 PM Jonathan Wakely wrote:
>> @@ -278,43 +302,97 @@ namespace __detail
>> regex_traits<_Ch_type>::
>> lookup_classname(_Fwd_iter __first, _Fwd_iter __last, bool __icase)
>> const
>> {
>> + if constexpr (__is_any_random_access_iter<_Fwd_iter>::value)
>> + if ((__last - __first) > 6) [[__unlikely__]]
>> + return {}; // "xdigit" is the longest classname
>> +
>>typedef std::ctype __ctype_type;
>>const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
>>
>> - // Mappings from class name to class mask.
>> - static const pair __classnames[] =
>> - {
>> - {"d", ctype_base::digit},
>> - {"w", {ctype_base::alnum, _RegexMask::_S_under}},
>> - {"s", ctype_base::space},
>> - {"alnum", ctype_base::alnum},
>> - {"alpha", ctype_base::alpha},
>> - {"blank", ctype_base::blank},
>> - {"cntrl", ctype_base::cntrl},
>> - {"digit", ctype_base::digit},
>> - {"graph", ctype_base::graph},
>> - {"lower", ctype_base::lower},
>> - {"print", ctype_base::print},
>> - {"punct", ctype_base::punct},
>> - {"space", ctype_base::space},
>> - {"upper", ctype_base::upper},
>> - {"xdigit", ctype_base::xdigit},
>> + auto __read_ch = [&]() -> char {
>> + if (__first == __last)
>> + return '\0';
>> + char __c = __fctyp.narrow(__fctyp.tolower(*__first), 0);
>> + ++__first;
>> + return __c;
>>};
>>
>> - string __s;
>> - for (; __first != __last; ++__first)
>> - __s += __fctyp.narrow(__fctyp.tolower(*__first), 0);
>> + auto __match = [&](const char* __s) -> bool {
>> + do
>> + if (__read_ch() != *__s)
>> + return false;
>> + while (*++__s);
>> + return __first == __last;
>> + };
>>
>> - for (const auto& __it : __classnames)
>> - if (__s == __it.first)
>> + switch(__read_ch())
>
> That's a really cool idea, to switch on one character.
I first saw this technique about 20 years ago in some autogenerated
code for matching command names in a function dispatcher, where it
provided no performance benefits over just iterating over an array of
names and using strcmp on each one.
But I think it's worth the extra complexity here (and improves
performance) because:
1) We have a fairly small set of strings to match which are defined in
the standard and don't need to change often, so there's not much
maintenance cost.
2) The input string is provided as an iterator pair [begin,end), not
as a char*, so the original code was constructing a std::string to
hold the string before matching it.
3) We aren't just matching the input string to the set of names, we
also need to call ctype.narrow(ctype.tolower(*begin)) on each input
character, so avoiding doing that up-front on the entire string means
we only do that work as needed.
4) ... it's 20 years later, maybe optimizers have changed :-)
I'm testing the PATCH v2 series now ...
Re: [PATCH 3/3] libstdc++: Optimize std::regex_traits lookup functions
On Tue, 10 Feb 2026 at 14:07, Tomasz Kaminski wrote:
>>
>> + {
>> + case 'a':
>> + if (__read_ch() == 'l')
>> + switch (__read_ch())
>> + {
>> + case 'n':
>> + if (__match("um"))
>
> I think adding comments like if (__match("um")) // alnum, would really
> help here. I think they really helps for this two cases, but would
> add them everywhere...
>>
>> + return ctype_base::alnum;
>> + break;
>> + case 'p':
>> + if (__match("ha"))
>>
>> + return ctype_base::alpha;
>> + break;
>> + }
>> + break;
>> + case 'b':
>> + if (__match("lank"))
>> + return ctype_base::blank;
>> + break;
>> + case 'c':
>> + if (__match("ntrl"))
>> + return ctype_base::cntrl;
>> + break;
>> + case 'd':
>> + if (__first == __last || __match("igit"))
>
> And say // d or digit here.
Yes, this would be helpful. I'll add those comments.
Re: [PATCH 3/3] libstdc++: Optimize std::regex_traits lookup functions
On Mon, Feb 9, 2026 at 9:43 PM Jonathan Wakely wrote:
> Optimize std::regex_traits::lookup_collatename and
> std::regex_traits::lookup_classname.
>
> For lookup_collatename we can hoist the static array into a
> non-dependent function, then call that for the regex_traits
> specialization without performing any narrowing operations via the ctype
> facet. For the regex_traits specialization we populate a
> std::string for the narrowed result, and call the non-dependent function.
>
> For lookup_classname we can avoid the static array entirely, replacing
> the iteration over that array with a nested switch that implements a
> kind of manually-unrolled trie, only match one char at a time until we
> either match a full string or get a mismatch. This avoids narrowing the
> entire input and storing it in a temporary string. This improves
> performance by 2-3x for -O2 and below (the benefit is much smaller for
> -O3).
>
> We can also check the input length for random access iterators, and
> reject any strings longer than "xdigit" without doing any work at all.
> For silly cases like [:xxx:]
> this gives a 100x improvement.
>
> libstdc++-v3/ChangeLog:
>
> * include/bits/regex.tcc (__detail::__lookup_collatename): New
> function.
> (regex_traits::lookup_collatename): Use new function. Elide
> redundant narrowing via ctype facet for regex_traits.
> (regex_traits::lookup_classname): Replace lookup table with
> handwritten prefix match.
> ---
>
> This does not need to be backported to release branches.
>
Agreed.
>
> Tested x86_64-linux.
>
LGTM.
>
> libstdc++-v3/include/bits/regex.tcc | 428
> 1 file changed, 252 insertions(+), 176 deletions(-)
>
> diff --git a/libstdc++-v3/include/bits/regex.tcc
> b/libstdc++-v3/include/bits/regex.tcc
> index 71eadd20bfdb..63e4cf79910c 100644
> --- a/libstdc++-v3/include/bits/regex.tcc
> +++ b/libstdc++-v3/include/bits/regex.tcc
> @@ -113,163 +113,187 @@ namespace __detail
> }
>return __ret;
> }
> +
> + inline void
> + __lookup_collatename(string& __name) noexcept
> + {
> +static const char* const __collatenames[] =
> + {
> + "NUL",
> + "SOH",
> + "STX",
> + "ETX",
> + "EOT",
> + "ENQ",
> + "ACK",
> + "alert",
> + "backspace",
> + "tab",
> + "newline",
> + "vertical-tab",
> + "form-feed",
> + "carriage-return",
> + "SO",
> + "SI",
> + "DLE",
> + "DC1",
> + "DC2",
> + "DC3",
> + "DC4",
> + "NAK",
> + "SYN",
> + "ETB",
> + "CAN",
> + "EM",
> + "SUB",
> + "ESC",
> + "IS4",
> + "IS3",
> + "IS2",
> + "IS1",
> + "space",
> + "exclamation-mark",
> + "quotation-mark",
> + "number-sign",
> + "dollar-sign",
> + "percent-sign",
> + "ampersand",
> + "apostrophe",
> + "left-parenthesis",
> + "right-parenthesis",
> + "asterisk",
> + "plus-sign",
> + "comma",
> + "hyphen",
> + "period",
> + "slash",
> + "zero",
> + "one",
> + "two",
> + "three",
> + "four",
> + "five",
> + "six",
> + "seven",
> + "eight",
> + "nine",
> + "colon",
> + "semicolon",
> + "less-than-sign",
> + "equals-sign",
> + "greater-than-sign",
> + "question-mark",
> + "commercial-at",
> + "A",
> + "B",
> + "C",
> + "D",
> + "E",
> + "F",
> + "G",
> + "H",
> + "I",
> + "J",
> + "K",
> + "L",
> + "M",
> + "N",
> + "O",
> + "P",
> + "Q",
> + "R",
> + "S",
> + "T",
> + "U",
> + "V",
> + "W",
> + "X",
> + "Y",
> + "Z",
> + "left-square-bracket",
> + "backslash",
> + "right-square-bracket",
> + "circumflex",
> + "underscore",
> + "grave-accent",
> + "a",
> + "b",
> + "c",
> + "d",
> + "e",
> + "f",
> + "g",
> + "h",
> + "i",
> + "j",
> + "k",
> + "l",
> + "m",
> + "n",
> + "o",
> + "p",
> + "q",
> + "r",
> + "s",
> + "t",
> + "u",
> + "v",
> + "w",
> + "x",
> + "y",
> + "z",
> + "left-curly-bracket",
> + "vertical-line",
> + "right-curly-bracket",
> + "tilde",
> + "DEL",
> + };
> +
> +for (const auto& __it : __collatenames)
> + if (__name == __it)
> + {
> + __name.assign(1, static_cast(&__it - __collatenames));
> + return;
> + }
> +
> +__name.clear();
> + }
> +
>/// @endcond
> } // namespace __detail
>
> +#pragma GCC diagnostic push
> +#pragma GCC diagnostic ignored "-Wc++17-exte
[PATCH 3/3] libstdc++: Optimize std::regex_traits lookup functions
Optimize std::regex_traits::lookup_collatename and
std::regex_traits::lookup_classname.
For lookup_collatename we can hoist the static array into a
non-dependent function, then call that for the regex_traits
specialization without performing any narrowing operations via the ctype
facet. For the regex_traits specialization we populate a
std::string for the narrowed result, and call the non-dependent function.
For lookup_classname we can avoid the static array entirely, replacing
the iteration over that array with a nested switch that implements a
kind of manually-unrolled trie, only match one char at a time until we
either match a full string or get a mismatch. This avoids narrowing the
entire input and storing it in a temporary string. This improves
performance by 2-3x for -O2 and below (the benefit is much smaller for
-O3).
We can also check the input length for random access iterators, and
reject any strings longer than "xdigit" without doing any work at all.
For silly cases like [:xxx:]
this gives a 100x improvement.
libstdc++-v3/ChangeLog:
* include/bits/regex.tcc (__detail::__lookup_collatename): New
function.
(regex_traits::lookup_collatename): Use new function. Elide
redundant narrowing via ctype facet for regex_traits.
(regex_traits::lookup_classname): Replace lookup table with
handwritten prefix match.
---
This does not need to be backported to release branches.
Tested x86_64-linux.
libstdc++-v3/include/bits/regex.tcc | 428
1 file changed, 252 insertions(+), 176 deletions(-)
diff --git a/libstdc++-v3/include/bits/regex.tcc
b/libstdc++-v3/include/bits/regex.tcc
index 71eadd20bfdb..63e4cf79910c 100644
--- a/libstdc++-v3/include/bits/regex.tcc
+++ b/libstdc++-v3/include/bits/regex.tcc
@@ -113,163 +113,187 @@ namespace __detail
}
return __ret;
}
+
+ inline void
+ __lookup_collatename(string& __name) noexcept
+ {
+static const char* const __collatenames[] =
+ {
+ "NUL",
+ "SOH",
+ "STX",
+ "ETX",
+ "EOT",
+ "ENQ",
+ "ACK",
+ "alert",
+ "backspace",
+ "tab",
+ "newline",
+ "vertical-tab",
+ "form-feed",
+ "carriage-return",
+ "SO",
+ "SI",
+ "DLE",
+ "DC1",
+ "DC2",
+ "DC3",
+ "DC4",
+ "NAK",
+ "SYN",
+ "ETB",
+ "CAN",
+ "EM",
+ "SUB",
+ "ESC",
+ "IS4",
+ "IS3",
+ "IS2",
+ "IS1",
+ "space",
+ "exclamation-mark",
+ "quotation-mark",
+ "number-sign",
+ "dollar-sign",
+ "percent-sign",
+ "ampersand",
+ "apostrophe",
+ "left-parenthesis",
+ "right-parenthesis",
+ "asterisk",
+ "plus-sign",
+ "comma",
+ "hyphen",
+ "period",
+ "slash",
+ "zero",
+ "one",
+ "two",
+ "three",
+ "four",
+ "five",
+ "six",
+ "seven",
+ "eight",
+ "nine",
+ "colon",
+ "semicolon",
+ "less-than-sign",
+ "equals-sign",
+ "greater-than-sign",
+ "question-mark",
+ "commercial-at",
+ "A",
+ "B",
+ "C",
+ "D",
+ "E",
+ "F",
+ "G",
+ "H",
+ "I",
+ "J",
+ "K",
+ "L",
+ "M",
+ "N",
+ "O",
+ "P",
+ "Q",
+ "R",
+ "S",
+ "T",
+ "U",
+ "V",
+ "W",
+ "X",
+ "Y",
+ "Z",
+ "left-square-bracket",
+ "backslash",
+ "right-square-bracket",
+ "circumflex",
+ "underscore",
+ "grave-accent",
+ "a",
+ "b",
+ "c",
+ "d",
+ "e",
+ "f",
+ "g",
+ "h",
+ "i",
+ "j",
+ "k",
+ "l",
+ "m",
+ "n",
+ "o",
+ "p",
+ "q",
+ "r",
+ "s",
+ "t",
+ "u",
+ "v",
+ "w",
+ "x",
+ "y",
+ "z",
+ "left-curly-bracket",
+ "vertical-line",
+ "right-curly-bracket",
+ "tilde",
+ "DEL",
+ };
+
+for (const auto& __it : __collatenames)
+ if (__name == __it)
+ {
+ __name.assign(1, static_cast(&__it - __collatenames));
+ return;
+ }
+
+__name.clear();
+ }
+
/// @endcond
} // namespace __detail
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr
+
template
template
typename regex_traits<_Ch_type>::string_type
regex_traits<_Ch_type>::
lookup_collatename(_Fwd_iter __first, _Fwd_iter __last) const
{
- typedef std::ctype __ctype_type;
- const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
-
- static const char* const __collatenames[] =
- {
- "NUL",
- "SOH",
- "STX",
- "ETX",
- "EOT"
