[libcxx-commits] [libcxx] [libc++] Rewrite std::regex (PR #217680)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Fri Aug 21 07:47:40 PDT 2026


https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/217680

>From ebc8633ef43e034580ce83825a7f2df150b24e44 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Wed, 25 Mar 2026 03:36:58 +0100
Subject: [PATCH 01/21] [libc++] Avoid a bunch of allocations when using
 std::regex_search

---
 libcxx/include/regex                   | 33 +++++++++++------
 libcxx/test/benchmarks/regex.bench.cpp | 51 ++++++++++++++++++++++++++
 2 files changed, 72 insertions(+), 12 deletions(-)
 create mode 100644 libcxx/test/benchmarks/regex.bench.cpp

diff --git a/libcxx/include/regex b/libcxx/include/regex
index a11635093ec2b..0be8b4703c725 100644
--- a/libcxx/include/regex
+++ b/libcxx/include/regex
@@ -2615,13 +2615,16 @@ private:
                 regex_constants::match_flag_type __flags) const;
 
   template <class _Allocator>
-  bool __match_at_start(const _CharT* __first,
-                        const _CharT* __last,
-                        match_results<const _CharT*, _Allocator>& __m,
-                        regex_constants::match_flag_type __flags,
-                        bool) const;
+  bool __match_at_start(
+      vector<__state>& __states,
+      const _CharT* __first,
+      const _CharT* __last,
+      match_results<const _CharT*, _Allocator>& __m,
+      regex_constants::match_flag_type __flags,
+      bool) const;
   template <class _Allocator>
   bool __match_at_start_ecma(
+      vector<__state>& __states,
       const _CharT* __first,
       const _CharT* __last,
       match_results<const _CharT*, _Allocator>& __m,
@@ -2636,6 +2639,7 @@ private:
       bool) const;
   template <class _Allocator>
   bool __match_at_start_posix_subs(
+      vector<__state>& __states,
       const _CharT* __first,
       const _CharT* __last,
       match_results<const _CharT*, _Allocator>& __m,
@@ -2758,7 +2762,9 @@ template <class _CharT, class _Traits>
 void __lookahead<_CharT, _Traits>::__exec(__state& __s) const {
   match_results<const _CharT*> __m;
   __m.__init(1 + __exp_.mark_count(), __s.__current_, __s.__last_);
+  vector<__state> __states_buffer;
   bool __matched = __exp_.__match_at_start_ecma(
+      __states_buffer,
       __s.__current_,
       __s.__last_,
       __m,
@@ -4880,12 +4886,13 @@ swap(match_results<_BidirectionalIterator, _Allocator>& __x, match_results<_Bidi
 template <class _CharT, class _Traits>
 template <class _Allocator>
 bool basic_regex<_CharT, _Traits>::__match_at_start_ecma(
+    vector<__state>& __states,
     const _CharT* __first,
     const _CharT* __last,
     match_results<const _CharT*, _Allocator>& __m,
     regex_constants::match_flag_type __flags,
     bool __at_first) const {
-  vector<__state> __states;
+  __states.clear();
   __node* __st = __start_.get();
   if (__st) {
     sub_match<const _CharT*> __unmatched;
@@ -5036,12 +5043,12 @@ bool basic_regex<_CharT, _Traits>::__match_at_start_posix_nosubs(
 template <class _CharT, class _Traits>
 template <class _Allocator>
 bool basic_regex<_CharT, _Traits>::__match_at_start_posix_subs(
+    vector<__state>& __states,
     const _CharT* __first,
     const _CharT* __last,
     match_results<const _CharT*, _Allocator>& __m,
     regex_constants::match_flag_type __flags,
     bool __at_first) const {
-  vector<__state> __states;
   __state __best_state;
   ptrdiff_t __highest_j = 0;
   ptrdiff_t __np        = std::distance(__first, __last);
@@ -5125,16 +5132,17 @@ bool basic_regex<_CharT, _Traits>::__match_at_start_posix_subs(
 template <class _CharT, class _Traits>
 template <class _Allocator>
 bool basic_regex<_CharT, _Traits>::__match_at_start(
+    vector<__state>& __states,
     const _CharT* __first,
     const _CharT* __last,
     match_results<const _CharT*, _Allocator>& __m,
     regex_constants::match_flag_type __flags,
     bool __at_first) const {
   if (__get_grammar(__flags_) == ECMAScript)
-    return __match_at_start_ecma(__first, __last, __m, __flags, __at_first);
+    return __match_at_start_ecma(__states, __first, __last, __m, __flags, __at_first);
   if (mark_count() == 0)
     return __match_at_start_posix_nosubs(__first, __last, __m, __flags, __at_first);
-  return __match_at_start_posix_subs(__first, __last, __m, __flags, __at_first);
+  return __match_at_start_posix_subs(__states, __first, __last, __m, __flags, __at_first);
 }
 
 template <class _CharT, class _Traits>
@@ -5147,8 +5155,9 @@ bool basic_regex<_CharT, _Traits>::__search(
   if (__flags & regex_constants::match_prev_avail)
     __flags &= ~(regex_constants::match_not_bol | regex_constants::match_not_bow);
 
+  vector<__state> __states_buffer;
   __m.__init(1 + mark_count(), __first, __last, __flags & regex_constants::__no_update_pos);
-  if (__match_at_start(__first, __last, __m, __flags, !(__flags & regex_constants::__no_update_pos))) {
+  if (__match_at_start(__states_buffer, __first, __last, __m, __flags, !(__flags & regex_constants::__no_update_pos))) {
     __m.__prefix_.second  = __m[0].first;
     __m.__prefix_.matched = __m.__prefix_.first != __m.__prefix_.second;
     __m.__suffix_.first   = __m[0].second;
@@ -5159,7 +5168,7 @@ bool basic_regex<_CharT, _Traits>::__search(
     __flags |= regex_constants::match_prev_avail;
     for (++__first; __first != __last; ++__first) {
       __m.__matches_.assign(__m.size(), __m.__unmatched_);
-      if (__match_at_start(__first, __last, __m, __flags, false)) {
+      if (__match_at_start(__states_buffer, __first, __last, __m, __flags, false)) {
         __m.__prefix_.second  = __m[0].first;
         __m.__prefix_.matched = __m.__prefix_.first != __m.__prefix_.second;
         __m.__suffix_.first   = __m[0].second;
@@ -5169,7 +5178,7 @@ bool basic_regex<_CharT, _Traits>::__search(
       __m.__matches_.assign(__m.size(), __m.__unmatched_);
     }
     __m.__matches_.assign(__m.size(), __m.__unmatched_);
-    if (__match_at_start(__first, __last, __m, __flags, false)) {
+    if (__match_at_start(__states_buffer, __first, __last, __m, __flags, false)) {
       __m.__prefix_.second  = __m[0].first;
       __m.__prefix_.matched = __m.__prefix_.first != __m.__prefix_.second;
       __m.__suffix_.first   = __m[0].second;
diff --git a/libcxx/test/benchmarks/regex.bench.cpp b/libcxx/test/benchmarks/regex.bench.cpp
new file mode 100644
index 0000000000000..8b218843dedc1
--- /dev/null
+++ b/libcxx/test/benchmarks/regex.bench.cpp
@@ -0,0 +1,51 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+#include <regex>
+
+#include "benchmark/benchmark.h"
+#include "GenerateInput.h"
+
+template <std::regex_constants::syntax_option_type Arg>
+static void BM_regex_construct(benchmark::State& state) {
+  static std::string_view regexes[] = {".*[abcdefghijklmnopqrtuvwxyz]{10,100}", "This is technically a regex."};
+  while (state.KeepRunningBatch(std::size(regexes))) {
+    for (auto& reg : regexes)
+      std::regex r(reg.data(), Arg);
+  }
+}
+BENCHMARK(BM_regex_construct<std::regex::basic>);
+BENCHMARK(BM_regex_construct<std::regex::extended>);
+BENCHMARK(BM_regex_construct<std::regex::awk>);
+BENCHMARK(BM_regex_construct<std::regex::ECMAScript>);
+
+static void BM_regex_run_bad_match(benchmark::State& state) {
+  std::regex r("This is technically a regex.");
+  std::string input = getRandomString(1 << 16);
+
+  for (auto _ : state) {
+    std::regex_search(input, r);
+  }
+}
+BENCHMARK(BM_regex_run_bad_match);
+
+static void BM_regex_run_almost_match(benchmark::State& state) {
+  std::regex r("This is technically a regex.");
+  std::string input;
+  for (size_t i = 0; i != 2500; ++i)
+    input += "This is technically a rege";
+
+  for (auto _ : state) {
+    std::regex_search(input, r);
+  }
+}
+BENCHMARK(BM_regex_run_almost_match);
+
+BENCHMARK_MAIN();

>From 428ae06634d08fbe0dd0b19fb6bcf9487a1bc857 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Wed, 25 Feb 2026 10:06:15 +0100
Subject: [PATCH 02/21] [libc++] A new regex implementation

---
 libcxx/include/CMakeLists.txt                 |   4 +
 libcxx/include/__regex/basic_parser.h         | 262 +++++++++
 libcxx/include/__regex/ecma_parser.h          | 240 ++++++++
 libcxx/include/__regex/interpreter.h          | 555 ++++++++++++++++++
 libcxx/include/__regex/parser_common.h        | 276 +++++++++
 libcxx/include/__regex/regex_error.h          | 176 ++++++
 libcxx/include/regex                          | 555 ++----------------
 .../re/re.alg/re.alg.search/basic.pass.cpp    |  12 +
 .../re.grammar/excessive_brace_count.pass.cpp |   3 +-
 9 files changed, 1564 insertions(+), 519 deletions(-)
 create mode 100644 libcxx/include/__regex/basic_parser.h
 create mode 100644 libcxx/include/__regex/ecma_parser.h
 create mode 100644 libcxx/include/__regex/interpreter.h
 create mode 100644 libcxx/include/__regex/parser_common.h
 create mode 100644 libcxx/include/__regex/regex_error.h

diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index a1d6a09aa6b20..1178b29eaedbe 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -794,6 +794,10 @@ set(files
   __ranges/views.h
   __ranges/zip_transform_view.h
   __ranges/zip_view.h
+  __regex/basic_parser.h
+  __regex/interpreter.h
+  __regex/parser_common.h
+  __regex/regex_error.h
   __split_buffer
   __std_mbstate_t.h
   __stop_token/atomic_unique_lock.h
diff --git a/libcxx/include/__regex/basic_parser.h b/libcxx/include/__regex/basic_parser.h
new file mode 100644
index 0000000000000..d32b957557fc6
--- /dev/null
+++ b/libcxx/include/__regex/basic_parser.h
@@ -0,0 +1,262 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___REGEX_BASIC_PARSER_H
+#define _LIBCPP___REGEX_BASIC_PARSER_H
+
+#include <__algorithm/search.h>
+#include <__config>
+#include <__iterator/next.h>
+#include <__regex/interpreter.h>
+#include <__regex/parser_common.h>
+#include <__regex/regex_error.h>
+#include <__utility/exchange.h>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace __regex::__basic::inline __preserve_none {
+
+template <class _CharT, class _Traits, class _ForwardIterator>
+class __parser {
+  __interpreter<_CharT, _Traits> __machine_;
+  _ForwardIterator __first_;
+  _ForwardIterator __last_;
+  regex_constants::syntax_option_type __flags_ = regex_constants::syntax_option_type();
+  uint8_t __marked_count_                      = 0;
+
+  bool __parse_ord_char(_ForwardIterator& __first, _ForwardIterator __last) {
+    _LIBCPP_ASSERT_INTERNAL(__first != __last, "Expected parseable character");
+    auto __next = std::next(__first);
+    if (__next == __last && *__first == '$')
+      return false;
+    if (*__first == '.' || *__first == '\\' || *__first == '[')
+      return false;
+    __machine_.__push_char_matcher(*__first, __flags_);
+    __first = __next;
+    return true;
+  }
+
+  bool __parse_quoted_char() {
+    _LIBCPP_ASSERT_INTERNAL(__first_ != __last_, "Expected parseable character");
+    auto __next = std::next(__first_);
+    if (__next == __last_)
+      return false;
+    if (*__first_ != '\\')
+      return false;
+    switch (*__next) {
+    case '^':
+    case '.':
+    case '*':
+    case '[':
+    case '$':
+    case '\\':
+      __machine_.__push_char_matcher(*__next, __flags_);
+      __first_ = ++__next;
+      return true;
+    default:
+      return false;
+    }
+  }
+
+  bool __parse_one_char_or_coll_elem() {
+    if (__first_ == __last_)
+      return false;
+
+    if (__parse_ord_char(__first_, __last_))
+      return true;
+    if (__parse_quoted_char())
+      return true;
+
+    if (*__first_ == '.') {
+      __machine_.__push_any_matcher();
+      ++__first_;
+      return true;
+    } else {
+      return __regex::__parse_bracket_expression(__machine_, __first_, __last_, __flags_);
+    }
+  }
+
+  bool __parse_backref() {
+    if (__first_ == __last_)
+      return false;
+
+    auto __next = std::next(__first_);
+    if (__next == __last_)
+      return false;
+    if (*__first_ != '\\' || *__next < '0' || *__next > '9')
+      return false;
+    if (*__next == '0') {
+      __machine_.__push_char_matcher('\0');
+      __first_ = ++__next;
+      return true;
+    }
+    auto __val = *__next - '0';
+    if (__val > __marked_count_)
+      std::__throw_regex_error<regex_constants::error_backref>();
+    __machine_.__push_backref_matcher(__val, __flags_);
+    __first_ = ++__next;
+    return true;
+  }
+
+  bool __parse_escaped_character(_CharT __char) {
+    if (__first_ == __last_)
+      return false;
+    auto __next = std::next(__first_);
+    if (__next == __last_)
+      return false;
+    if (*__first_ != '\\' || *__next != __char)
+      return false;
+    __first_ = ++__next;
+    return true;
+  }
+
+  bool __parse_nondupl() {
+    if (__parse_one_char_or_coll_elem())
+      return true;
+
+    if (__parse_escaped_character('(')) {
+      size_t __subexpr_num = __marked_count_++;
+      __machine_.__push_subexpression_begin(__subexpr_num);
+      __parse_re_expression();
+      if (!__parse_escaped_character(')'))
+        std::__throw_regex_error<regex_constants::error_paren>();
+      __machine_.__push_subexpression_end(__subexpr_num);
+      return true;
+    } else {
+      return __parse_backref();
+    }
+  }
+
+  bool __parse_dupl_symbol(size_t __expr_start) {
+    if (__first_ == __last_)
+      return false;
+
+    if (*__first_ == '*') {
+      __machine_.__push_n_to_m_matcher(__expr_start, 0, numeric_limits<size_t>::max());
+      ++__first_;
+      return true;
+    }
+
+    if (!__parse_escaped_character('{'))
+      return false;
+
+    size_t __min;
+    if (auto __res = __regex::__parse_dup_count(__first_, __last_)) {
+      __min = __res.__num_;
+    } else {
+      std::__throw_regex_error<regex_constants::error_badbrace>();
+    }
+
+    if (__first_ == __last_)
+      std::__throw_regex_error<regex_constants::error_brace>();
+    if (*__first_ == ',') {
+      ++__first_;
+      size_t __max;
+      if (auto __res = __regex::__parse_dup_count(__first_, __last_)) {
+        __max = __res.__num_;
+      } else {
+        __max = numeric_limits<size_t>::max();
+      }
+
+      if (__max < __min || !__parse_escaped_character('}'))
+        std::__throw_regex_error<regex_constants::error_badbrace>();
+      __machine_.__push_n_to_m_matcher(__expr_start, __min, __max);
+      return true;
+    }
+
+    if (!__parse_escaped_character('}'))
+      std::__throw_regex_error<regex_constants::error_brace>();
+    __machine_.__push_n_matcher(__expr_start, __min);
+    return true;
+  }
+
+  bool __parse_simple_re() {
+    if (__first_ == __last_)
+      return false;
+
+    auto __expr_start = __machine_.size();
+    if (__parse_nondupl()) {
+      __parse_dupl_symbol(__expr_start);
+      return true;
+    }
+    return false;
+  }
+
+  void __parse_re_expression() {
+    while (__parse_simple_re())
+      ;
+  }
+
+  void __parse_basic_expr() {
+    if (__first_ == __last_)
+      return;
+
+    if (*__first_ == '^') {
+      __machine_.__push_start_anchor();
+      ++__first_;
+      if (__first_ == __last_)
+        return;
+    }
+
+    __parse_re_expression();
+
+    if (__first_ != __last_) {
+      auto __next = std::next(__first_);
+      if (__next == __last_ && *__first_ == '$') {
+        __machine_.__push_end_anchor();
+        __first_ = __next;
+      }
+    }
+
+    if (__first_ != __last_)
+      std::__throw_regex_error<regex_constants::__re_err_empty>();
+  }
+
+public:
+  __parser(
+      _ForwardIterator __first, _ForwardIterator __last, _Traits __traits, regex_constants::syntax_option_type __flags)
+      : __machine_(__traits), __first_(__first), __last_(__last), __flags_(__flags) {}
+
+  void __parse_basic() {
+    __parse_basic_expr();
+    __machine_.__push_end_state();
+  }
+
+  void __parse_grep() {
+    auto __newline = std::find(__first_, __last_, '\n');
+    if (__newline != __first_) {
+      std::swap(__last_, __newline);
+      __parse_basic_expr();
+      std::swap(__last_, __newline);
+      if (__first_ != __newline)
+        std::__throw_regex_error<regex_constants::__re_err_grammar>();
+    }
+    if (__first_ != __last_)
+      ++__first_;
+    while (__first_ != __last_) {
+      __newline = std::find(__first_, __last_, '\n');
+      std::swap(__last_, __newline);
+      __parse_basic_expr();
+      std::swap(__last_, __newline);
+      if (__first_ != __newline)
+        std::__throw_regex_error<regex_constants::__re_err_grammar>();
+      __machine_.__push_alternative(0, __machine_.size());
+      if (__first_ != __last_)
+        ++__first_;
+    }
+    __machine_.__push_end_state();
+  }
+
+  __interpreter<_CharT, _Traits> __extract_interpreter() { return std::move(__machine_); }
+  size_t mark_count() const { return __marked_count_; }
+};
+} // namespace __regex::__basic::inline __preserve_none
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___REGEX_BASIC_PARSER_H
diff --git a/libcxx/include/__regex/ecma_parser.h b/libcxx/include/__regex/ecma_parser.h
new file mode 100644
index 0000000000000..06fcf75db68ca
--- /dev/null
+++ b/libcxx/include/__regex/ecma_parser.h
@@ -0,0 +1,240 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___REGEX_ECMA_PARSER_H
+#define _LIBCPP___REGEX_ECMA_PARSER_H
+
+#include <__config>
+#include <__regex/regex_error.h>
+#include <__regex/state_machine.h>
+
+#define _LIBCPP_PARSER_FUNCTION [[clang::preserve_none]]
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace __regex::__ecma {
+template <class _ForwardIterator>
+_LIBCPP_PARSER_FUNCTION bool
+__parse_disjunction(__state_machine& __machine, _ForwardIterator& __first, _ForwardIterator __last);
+
+template <class _ForwardIterator>
+_LIBCPP_PARSER_FUNCTION bool
+__parse_assertion(__state_machine& __machine, _ForwardIterator& __first, _ForwardIterator __last) {
+  if (__first == __last)
+    return false;
+  switch (*__first) {
+  case '^': {
+    __machine.push_back(__state::__start_anchor);
+    ++__first;
+    return true;
+  }
+  case '$': {
+    __machine.push_back(__state::__end_anchor);
+    ++__first;
+    return true;
+  }
+  case '\\': {
+    auto __next = std::next(__first);
+    if (__next == __last)
+      return false;
+    if (auto __char = *__next; __char == 'b' || __char == 'B') {
+      __machine.push_back(__char == 'b' ? __state::__match_word_boundary : __state::__match_no_word_boundary);
+      __first = ++__next;
+      return true;
+    }
+    return false;
+  }
+  case '(': {
+    auto __next = std::next(__first);
+    if (__next == __last || *++__next != '?' || __next == __last)
+      return false;
+    auto __char = *__next;
+    if (__char != '=' && __char != '!')
+      return false;
+    __machine.push_back(__char == '=' ? __state::__positive_lookahead_start : __state::__negative_lookahead_start);
+    if (!__ecma::__parse_disjunction(__machine, __first, __last))
+      return false;
+    __machine.push_back(__state::__lookahead_end);
+    if (__first == __last || *__first++ != ')')
+      std::__throw_regex_error<regex_constants::error_paren>();
+    return true;
+  }
+  }
+  return false;
+}
+
+template <class _ForwardIterator>
+_LIBCPP_PARSER_FUNCTION bool
+__parse_decimal_escape(__state_machine& __machine, _ForwardIterator& __first, _ForwardIterator __last) {
+  if (*__first == '0') {
+    __regex::__match_char(__machine, '\0');
+    ++__first;
+    return true;
+  }
+
+  if ('1' <= *__first && *__first <= '9') {
+    unsigned __value = *__first - '0';
+    for (++__first; __first != __last && '0' <= *__first && *__first <= '9'; ++__first) {
+      if (__value >= numeric_limits<unsigned>::max() / 10)
+        std::__throw_regex_error<regex_constants::error_backref>();
+      __value = __value * 10 + *__first - '0';
+    }
+    if (__value == 0)
+      std::__throw_regex_error<regex_constants::error_backref>();
+    __machine.push_back(__state::__match_backref);
+    __regex::__write_uleb(__machine, __value);
+  }
+  return true;
+}
+
+template <class _ForwardIterator>
+_LIBCPP_PARSER_FUNCTION bool
+__parse_character_class_escape(__state_machine& __machine, _ForwardIterator& __first, _ForwardIterator __last) {
+  if (__first == __last)
+    return false;
+  switch (*__first) {
+  case 'd':
+    __machine.push_back(__state::__match_digits);
+    break;
+  case 'D':
+    __machine.push_back(__state::__match_no_digits);
+    break;
+  case 's':
+    __machine.push_back(__state::__match_whitespace);
+    break;
+  case 'S':
+    __machine.push_back(__state::__match_no_whitespace);
+    break;
+  case 'w':
+    __machine.push_back(__state::__match_word_character);
+    break;
+  case 'W':
+    __machine.push_back(__state::__match_no_word_character);
+    break;
+  default:
+    return false;
+  }
+  ++__first;
+  return true;
+}
+
+template <class _ForwardIterator>
+_LIBCPP_PARSER_FUNCTION bool
+__parse_character_escape(__state_machine& __machine, _ForwardIterator& __first, _ForwardIterator __last) {
+  if (__first == __last)
+    return false;
+  switch (*__first) {
+  case 'f':
+    __regex::__match_char(__machine, '\f');
+    break;
+  case 'n':
+    __regex::__match_char(__machine, '\n');
+    break;
+  case 'r':
+    __regex::__match_char(__machine, '\r');
+    break;
+  case 't':
+    __regex::__match_char(__machine, '\t');
+    break;
+  case 'v':
+    __regex::__match_char(__machine, '\v');
+    break;
+
+  case 'c': {
+    auto __next = std::next(__first);
+    if (__next == __last)
+      std::__throw_regex_error<regex_constants::error_escape>();
+    if (('A' <= *__next && *__next <= 'Z') || ('a' <= *__next && *__next <= 'z')) {
+      __regex::__match_char(__machine, *__next % 32);
+      __first += ++__next;
+    } else {
+      std::__throw_regex_error<regex_constants::error_escape>();
+    }
+  }
+  }
+  ++__first;
+  return true;
+}
+
+template <class _ForwardIterator>
+_LIBCPP_PARSER_FUNCTION bool
+__parse_atom_escape(__state_machine& __machine, _ForwardIterator& __first, _ForwardIterator __last) {
+  _LIBCPP_ASSERT_INTERNAL(*__first == '\\', "Parsing escape character without an escape start?");
+  auto __next = std::next(__first);
+  if (__next == __last)
+    std::__throw_regex_error<regex_constants::error_escape>();
+
+  if (__ecma::__parse_decimal_escape(__machine, __next, __last) ||
+      __ecma::__parse_character_class_escape(__machine, __next, __last)) {
+    __first = __next;
+    return true;
+  }
+  return false;
+}
+
+template <class _ForwardIterator>
+_LIBCPP_PARSER_FUNCTION bool
+__parse_atom(__state_machine& __machine, _ForwardIterator& __first, _ForwardIterator __last) {
+  if (__first == __last)
+    return false;
+
+  switch (*__first) {
+  case '.': {
+    __machine.push_back(__state::__match_any);
+    ++__first;
+    return true;
+  }
+  case '\\':
+    return __ecma::__parse_atom_escape(__machine, __first, __last);
+  }
+
+  return false;
+}
+
+template <class _ForwardIterator>
+_LIBCPP_PARSER_FUNCTION bool
+__parse_term(__state_machine& __machine, _ForwardIterator& __first, _ForwardIterator __last) {
+  return __ecma::__parse_assertion(__machine, __first, __last) || __ecma::__parse_atom(__machine, __first, __last);
+}
+
+template <class _ForwardIterator>
+_LIBCPP_PARSER_FUNCTION void
+__parse_alternative(__state_machine& __machine, _ForwardIterator& __first, _ForwardIterator __last) {
+  while (true) {
+    __ecma::__parse_term(__machine, __first, __last);
+  }
+}
+
+template <class _ForwardIterator>
+_LIBCPP_PARSER_FUNCTION bool
+__parse_disjunction(__state_machine& __machine, _ForwardIterator& __first, _ForwardIterator __last) {
+  while (__first != __last) {
+    __ecma::__parse_alternative(__machine, __first, __last);
+  }
+  return true;
+}
+
+template <class _ForwardIterator>
+_LIBCPP_PARSER_FUNCTION void
+__parse_pattern(__state_machine& __machine, _ForwardIterator& __first, _ForwardIterator __last) {
+  __ecma::__parse_disjunction(__machine, __first, __last);
+}
+
+template <class _ForwardIterator>
+__state_machine __parse(_ForwardIterator __first, _ForwardIterator __last) {
+  __state_machine __machine;
+
+  __ecma::__parse_pattern(__machine, __first, __last);
+
+  return __machine;
+}
+} // namespace __regex::__ecma
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___REGEX_ECMA_PARSER_H
diff --git a/libcxx/include/__regex/interpreter.h b/libcxx/include/__regex/interpreter.h
new file mode 100644
index 0000000000000..515ce2cca3e08
--- /dev/null
+++ b/libcxx/include/__regex/interpreter.h
@@ -0,0 +1,555 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___REGEX_INTERPRETER_H
+#define _LIBCPP___REGEX_INTERPRETER_H
+
+#include <__algorithm/copy_if.h>
+#include <__algorithm/equal.h>
+#include <__algorithm/min.h>
+#include <__algorithm/reverse.h>
+#include <__algorithm/transform.h>
+#include <__config>
+#include <__iterator/back_insert_iterator.h>
+#include <__ranges/filter_view.h>
+#include <__ranges/views.h>
+#include <__regex/regex_error.h>
+#include <__utility/pair.h>
+#include <__utility/to_underlying.h>
+#include <__vector/vector.h>
+#include <stack>
+#include <string_view>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _CharT>
+class __node;
+
+template <class _BidirectionalIterator>
+class sub_match;
+
+template <class _BidirectionalIterator, class _Allocator = allocator<sub_match<_BidirectionalIterator> > >
+class match_results;
+
+template <class _CharT>
+struct __state {
+  enum __states {
+    __end_state = -1000,
+    __consume_input,          // -999
+    __begin_marked_expr,      // -998
+    __end_marked_expr,        // -997
+    __pop_state,              // -996
+    __accept_and_consume,     // -995
+    __accept_but_not_consume, // -994
+    __reject,                 // -993
+    __split,
+    __repeat
+  };
+
+  int __do_;
+  const _CharT* __first_;
+  const _CharT* __current_;
+  const _CharT* __last_;
+  vector<sub_match<const _CharT*> > __sub_matches_;
+  vector<pair<size_t, const _CharT*> > __loop_data_;
+  const __node<_CharT>* __node_;
+  regex_constants::match_flag_type __flags_;
+  bool __at_first_;
+
+  _LIBCPP_HIDE_FROM_ABI __state()
+      : __do_(0),
+        __first_(nullptr),
+        __current_(nullptr),
+        __last_(nullptr),
+        __node_(nullptr),
+        __flags_(),
+        __at_first_(false) {}
+};
+
+namespace __regex {
+enum class __state : uint8_t {
+  __start_anchor,
+  __end_anchor,
+  __branch_alternative,
+  __match_any,
+  __match_char,
+  __match_icase_char,
+  __match_backref,
+  __match_icase_backref,
+  __match_character_list,
+  __match_no_character_list,
+  __marked_subexpression_begin,
+  __marked_subexpression_end,
+  __branch_n_to_m_matcher,
+  __match_n_to_m_times,
+  __match_n_times,
+  __relative_jump,
+  __end_state,
+};
+
+template <class _CharT>
+union __interpreter_info {
+  __interpreter_info(__state __st) : __state_(__st) {}
+  __interpreter_info(_CharT __c) : __char_(__c) {}
+  __interpreter_info(uint8_t __int) : __int_(__int) {}
+
+  template <class _Tp>
+  __interpreter_info(_Tp) = delete;
+
+  __state __state_;
+  _CharT __char_;
+  uint8_t __int_;
+};
+
+static_assert(sizeof(__interpreter_info<char>) == 1);
+
+template <class _CharT, class _Traits>
+struct __bracket_expr {
+  vector<_CharT> __chars_;
+  vector<_CharT> __digraphs_;
+  vector<_CharT> __ranges_;
+  vector<typename _Traits::string_type> __equivalences_;
+  typename _Traits::char_class_type __mask_ = 0;
+};
+
+template <class _CharT, class _Traits>
+class __interpreter {
+  vector<__interpreter_info<_CharT> > __machine_;
+  vector<size_t> __initial_loop_values_;
+  _Traits __traits_;
+
+  static size_t __read_uleb(const vector<__interpreter_info<_CharT> >& __machine, size_t& __current_pos) {
+    size_t __result = 0;
+    size_t __shift  = 0;
+
+    uint8_t __byte;
+    do {
+      __byte = __machine[__current_pos++].__int_;
+      __result |= (__byte & 0x7f) << __shift;
+      __shift += 7;
+    } while (__byte & 0x80);
+    return __result;
+  }
+
+  struct __global_execution_state {
+    struct __local_execution_state {
+      const _CharT* __current_;
+      vector<sub_match<const _CharT*> > __sub_matches_;
+      size_t __current_pos_;
+      vector<size_t> __loop_values_;
+      vector<const _CharT*> __loop_starts_;
+
+      bool __execute(const _CharT* __first, const _CharT* __last, __global_execution_state& __gstate) {
+        while (true) {
+          auto __st = __gstate.__machine()[__current_pos_++].__state_;
+          switch (__st) {
+            using enum __state;
+
+          case __start_anchor: {
+            if (!__gstate.__at_first_ || __first != __current_)
+              return false;
+          } break;
+
+          case __end_anchor: {
+            if (__current_ != __last)
+              return false;
+          } break;
+
+          case __end_state: {
+            return true;
+          }
+
+          case __match_any: {
+            if (__current_ == __last)
+              return false;
+            ++__current_;
+          } break;
+
+          case __match_char: {
+            if (__current_ == __last || *__current_ != __gstate.__machine()[__current_pos_++].__char_)
+              return false;
+            ++__current_;
+          } break;
+
+          case __match_icase_char: {
+            if (__current_ == __last || __gstate.__machine_.__traits_.translate_nocase(*__current_) !=
+                                            __gstate.__machine()[__current_pos_++].__char_)
+              return false;
+            ++__current_;
+          } break;
+
+          case __branch_alternative: {
+            auto __offset = __read_uleb(__gstate.__machine(), __current_pos_);
+            auto __cpy    = *this;
+            __cpy.__current_pos_ += __offset;
+            __gstate.__states_.push(std::move(__cpy));
+            break;
+          }
+
+          case __relative_jump: {
+            __current_pos_ += __read_uleb(__gstate.__machine(), __current_pos_);
+            break;
+          }
+
+          case __branch_n_to_m_matcher: {
+            auto __loop_index     = __read_uleb(__gstate.__machine(), __current_pos_);
+            auto __again_pos_base = __current_pos_;
+            auto __again_pos      = __again_pos_base - __read_uleb(__gstate.__machine(), __current_pos_);
+            if (__loop_values_[__loop_index] > 0) {
+              --__loop_values_[__loop_index];
+              __current_pos_ = __again_pos;
+              break;
+            }
+            if (__loop_starts_[__loop_index] != __current_ && __loop_values_[__loop_index + 1] > 0) {
+              --__loop_values_[__loop_index + 1];
+              __loop_starts_[__loop_index] = __current_;
+              __gstate.__states_.push(*this);
+              __current_pos_ = __again_pos;
+              break;
+            }
+            break;
+          }
+
+          case __match_backref: {
+            sub_match<const _CharT*>& __match = __sub_matches_[__read_uleb(__gstate.__machine(), __current_pos_) - 1];
+            if (!__match.matched)
+              return false;
+
+            auto __len = __match.second - __match.first;
+            if (__last - __current_ < __len || !std::equal(__match.first, __match.second, __current_))
+              return false;
+
+            __current_ += __len;
+          } break;
+
+          case __match_icase_backref: {
+            sub_match<const _CharT*>& __match = __sub_matches_[__read_uleb(__gstate.__machine(), __current_pos_) - 1];
+            if (!__match.matched)
+              return false;
+
+            auto __len = __match.second - __match.first;
+            if (__last - __current_ < __len)
+              return false;
+
+            for (ptrdiff_t __i = 0; __i != __len; ++__i) {
+              if (__gstate.__machine_.__traits_.translate_nocase(__match.first[__i]) !=
+                  __gstate.__machine_.__traits_.translate_nocase(__current_[__i]))
+                return false;
+            }
+
+            __current_ += __len;
+          } break;
+
+          case __match_character_list:
+          case __match_no_character_list: {
+            if (__current_ == __last)
+              return false;
+            static const auto __buffer_size =
+                std::max(sizeof(typename _Traits::char_class_type) / sizeof(_CharT), size_t(1));
+            _CharT __buffer[__buffer_size];
+            for (size_t __i = 0; __i != __buffer_size; ++__i)
+              __buffer[__i] = __gstate.__machine()[__current_pos_++].__char_;
+            typename _Traits::char_class_type __mask;
+            __builtin_memcpy(&__mask, __buffer, sizeof(typename _Traits::char_class_type));
+
+            auto __chars       = __read_uleb(__gstate.__machine(), __current_pos_);
+            auto __digraphs    = __read_uleb(__gstate.__machine(), __current_pos_) * 2;
+            auto __ranges      = __read_uleb(__gstate.__machine(), __current_pos_) * 4;
+            auto __equiv_count = __read_uleb(__gstate.__machine(), __current_pos_);
+            auto __equiv_size  = __read_uleb(__gstate.__machine(), __current_pos_);
+
+            bool __found = false;
+
+            for (size_t __i = 0; __i != __chars; ++__i) {
+              if (__gstate.__machine()[__current_pos_ + __i].__char_ == *__current_) {
+                __found = true;
+                break;
+              }
+            }
+
+            __current_pos_ += __chars;
+
+            if (__found) {
+              __current_pos_ += __digraphs + __ranges + __equiv_size;
+              ++__current_;
+              if (__st == __match_no_character_list)
+                return false;
+              break;
+            }
+
+            if (__current_ + 1 != __last) {
+              _CharT __vals[2] = {__current_[0], __current_[1]};
+
+              for (size_t __i = 0; __i != __digraphs; __i += 2) {
+                if (__gstate.__machine()[__current_pos_ + __i].__char_ == __vals[0] &&
+                    __gstate.__machine()[__current_pos_ + __i + 1].__char_ == __vals[1]) {
+                  __found = true;
+                  break;
+                }
+              }
+            }
+
+            __current_pos_ += __digraphs;
+
+            if (__found) {
+              __current_pos_ += __ranges + __equiv_size;
+              __current_ += 2;
+              if (__st == __match_no_character_list)
+                return false;
+              break;
+            }
+
+            auto __cmp = __gstate.__machine_.__traits_.transform(__current_, __current_ + 1);
+            for (size_t __i = 0; __i != __ranges; __i += 4) {
+              _CharT __range_info[4];
+              std::transform(__gstate.__machine_.__machine_.begin() + __current_pos_ + __i,
+                             __gstate.__machine_.__machine_.begin() + __current_pos_ + __i + 4,
+                             __range_info,
+                             [](__interpreter_info<_CharT> __val) { return __val.__char_; });
+              basic_string_view<_CharT> __min(__range_info, __range_info[1] == '\0' ? 1 : 2);
+              basic_string_view<_CharT> __max(__range_info + 2, __range_info[3] == '\0' ? 1 : 2);
+              if (__min <= __cmp && __cmp <= __max) {
+                __found = true;
+                __current_ += __cmp.size();
+                break;
+              }
+            }
+
+            __current_pos_ += __ranges;
+
+            if (__found) {
+              __current_pos_ += __equiv_size;
+              if (__st == __match_no_character_list)
+                return false;
+              break;
+            }
+
+            if (__gstate.__machine_.__traits_.isctype(*__current_, __mask)) {
+              ++__current_;
+              if (__st == __match_no_character_list)
+                return false;
+              break;
+            }
+
+            auto __after_pos   = __current_pos_ + __equiv_size;
+            auto __transformed = __gstate.__machine_.__traits_.transform_primary(__current_, __current_ + 1);
+            for (size_t __i = 0; __i != __equiv_count; ++__i) {
+              auto __size = __read_uleb(__gstate.__machine(), __current_pos_);
+              basic_string<_CharT> __str;
+              std::transform(__gstate.__machine().begin() + __current_pos_,
+                             __gstate.__machine().begin() + __current_pos_ + __size,
+                             std::back_inserter(__str),
+                             [](__interpreter_info<_CharT> __v) { return __v.__char_; });
+              __current_pos_ += __size;
+              if (__transformed == __str) {
+                __found = true;
+                break;
+              }
+            }
+
+            __current_pos_ = __after_pos;
+
+            if (__found) {
+              ++__current_;
+              if (__st == __match_no_character_list)
+                return false;
+              break;
+            }
+
+            if (__st == __match_no_character_list) {
+              ++__current_;
+              break;
+            }
+            return false;
+
+          } break;
+
+          case __marked_subexpression_begin: {
+            auto __match                  = __read_uleb(__gstate.__machine(), __current_pos_);
+            __sub_matches_[__match].first = __current_;
+          } break;
+
+          case __marked_subexpression_end: {
+            auto __match                    = __read_uleb(__gstate.__machine(), __current_pos_);
+            __sub_matches_[__match].second  = __current_;
+            __sub_matches_[__match].matched = true;
+          } break;
+
+          default:
+            std::__libcpp_unreachable();
+          }
+        }
+      }
+    };
+
+    bool __at_first_;
+    stack<__local_execution_state> __states_;
+    const __interpreter& __machine_;
+
+    __global_execution_state(bool __at_first, __local_execution_state __initial_state, const __interpreter& __machine)
+        : __at_first_(__at_first), __machine_(__machine) {
+      __states_.push(std::move(__initial_state));
+    }
+
+    const vector<__interpreter_info<_CharT> >& __machine() { return __machine_.__machine_; }
+
+    bool __execute(const _CharT* __first, const _CharT* __last) {
+      while (!__states_.empty()) {
+        auto __st = std::move(__states_.top());
+        __states_.pop();
+        if (__st.__execute(__first, __last, *this)) {
+          __states_.push(std::move(__st));
+          return true;
+        }
+      }
+      return false;
+    }
+  };
+
+  void push_back(__interpreter_info<_CharT> __info) { __machine_.push_back(__info); }
+
+  template <class _Range>
+  void append_range(_Range&& __range) {
+    __machine_.insert(__machine_.end(), begin(__range), end(__range));
+  }
+
+  void insert(size_t __offset, vector<__interpreter_info<_CharT> >& __info) {
+    __machine_.insert(__machine_.begin() + __offset, __info.begin(), __info.end());
+  }
+
+  template <class _Container>
+  static void __write_uleb(_Container& __machine, size_t __val) {
+    do {
+      uint8_t __byte = __val & 0x7f;
+      __val >>= 7;
+      if (__val)
+        __byte |= 0x80;
+      __machine.push_back(__byte);
+    } while (__val);
+  }
+
+  template <class _Container>
+  void __write_string(_Container& __machine, basic_string_view<_CharT> __val) {
+    __write_uleb(__machine, __val.size());
+    __machine.insert(__machine.end(), __val.begin(), __val.end());
+  }
+
+  template <class _Container>
+  static void __push_relative_jump(_Container& __machine, size_t __offset) {
+    __machine.push_back(__state::__relative_jump);
+    __write_uleb(__machine, __offset);
+  }
+
+public:
+  __interpreter(_Traits __traits) : __traits_(__traits) {}
+
+  void __push_any_matcher() { push_back(__state::__match_any); }
+  void __push_end_state() { push_back(__state::__end_state); }
+  void __push_start_anchor() { push_back(__state::__start_anchor); }
+  void __push_end_anchor() { push_back(__state::__end_anchor); }
+
+  void __push_char_matcher(_CharT __char,
+                           regex_constants::syntax_option_type __flags = regex_constants::syntax_option_type()) {
+    if (__flags & regex_constants::icase) {
+      push_back(__state::__match_icase_char);
+      push_back(__traits_.translate_nocase(__char));
+    } else {
+      push_back(__state::__match_char);
+      push_back(__char);
+    }
+  }
+
+  void __push_subexpression_begin(size_t __num) {
+    push_back(__state::__marked_subexpression_begin);
+    __write_uleb(*this, __num);
+  }
+
+  void __push_subexpression_end(size_t __num) {
+    push_back(__state::__marked_subexpression_end);
+    __write_uleb(*this, __num);
+  }
+
+  void __push_n_matcher(size_t __expr_start, size_t __count) {
+    vector<__interpreter_info<_CharT> > __buffer;
+    __buffer.push_back(__state::__match_n_times);
+    __write_uleb(__buffer, __count);
+    __write_uleb(__buffer, __machine_.size() - __expr_start + 1);
+    insert(__expr_start, __buffer);
+    push_back(__state::__end_state);
+  }
+
+  void __push_n_to_m_matcher(size_t __expr_start, size_t __min, size_t __max) {
+    vector<__interpreter_info<_CharT> > __buffer;
+    __push_relative_jump(__buffer, size() - __expr_start);
+    insert(__expr_start, __buffer);
+    __expr_start += __buffer.size();
+    push_back(__state::__branch_n_to_m_matcher);
+    __write_uleb(__machine_, __initial_loop_values_.size());
+    __write_uleb(__machine_, size() - __expr_start);
+    __initial_loop_values_.push_back(__min);
+    __initial_loop_values_.push_back(__max - __min);
+  }
+
+  void __push_backref_matcher(size_t __ref,
+                              regex_constants::syntax_option_type __flags = regex_constants::syntax_option_type()) {
+    push_back((__flags & regex_constants::icase) ? __state::__match_icase_backref : __state::__match_backref);
+    __write_uleb(*this, __ref);
+  }
+
+  void __push_alternative(size_t __expr1_start, size_t __expr2_start) {
+    vector<__interpreter_info<_CharT> > __buffer;
+    __buffer.push_back(__state::__branch_alternative);
+    __write_uleb(__buffer, __expr2_start - __expr1_start);
+    insert(__expr1_start, __buffer);
+    __expr2_start += __buffer.size();
+    __buffer.clear();
+    __push_relative_jump(__buffer, size() - __expr2_start);
+    insert(__expr2_start, __buffer);
+  }
+
+  void __push_bracket_expr(bool __negate, const __bracket_expr<_CharT, _Traits>& __expr) {
+    push_back(__negate ? __state::__match_no_character_list : __state::__match_character_list);
+
+    _CharT __buffer[std::max(sizeof(typename _Traits::char_class_type) / sizeof(_CharT), size_t(1))];
+    __builtin_memcpy(__buffer, &__expr.__mask_, sizeof(__buffer));
+    append_range(__buffer);
+
+    basic_string<_CharT> __equivalences_buffer;
+    for (auto& __eq : __expr.__equivalences_)
+      __write_string(__equivalences_buffer, __eq);
+    __write_uleb(*this, __expr.__chars_.size());
+    __write_uleb(*this, __expr.__digraphs_.size() / 2);
+    __write_uleb(*this, __expr.__ranges_.size() / 4);
+    __write_uleb(*this, __expr.__equivalences_.size());
+    __write_uleb(*this, __equivalences_buffer.size());
+    append_range(__expr.__chars_);
+    append_range(__expr.__digraphs_);
+    append_range(__expr.__ranges_);
+    append_range(__equivalences_buffer);
+  }
+
+  size_t size() const { return __machine_.size(); }
+
+  __global_execution_state
+  __get_exec_state(vector<sub_match<const _CharT*> >& __sub_matches, const _CharT* __current, bool __at_first) const {
+    typename __global_execution_state::__local_execution_state __base_state;
+    __base_state.__sub_matches_ = __sub_matches;
+    __base_state.__current_     = __current;
+    __base_state.__loop_values_ = __initial_loop_values_;
+    __base_state.__loop_starts_.resize(__initial_loop_values_.size());
+    __base_state.__current_pos_ = 0;
+    return __global_execution_state(__at_first, __base_state, *this);
+  }
+
+  _Traits __get_traits() { return __traits_; }
+};
+} // namespace __regex
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___REGEX_INTERPRETER_H
diff --git a/libcxx/include/__regex/parser_common.h b/libcxx/include/__regex/parser_common.h
new file mode 100644
index 0000000000000..a7c344dcd33bf
--- /dev/null
+++ b/libcxx/include/__regex/parser_common.h
@@ -0,0 +1,276 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___REGEX_ECMA_PARSER_H
+#define _LIBCPP___REGEX_ECMA_PARSER_H
+
+#include <__algorithm/search.h>
+#include <__config>
+#include <__regex/interpreter.h>
+#include <__regex/regex_error.h>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace __regex {
+
+// bracket expression parsing
+
+template <class _CharT, class _Traits, class _ForwardIterator>
+bool __parse_character_class(
+    __interpreter<_CharT, _Traits>& __machine,
+    __bracket_expr<_CharT, _Traits>& __buffer,
+    _ForwardIterator& __first,
+    _ForwardIterator __last,
+    regex_constants::syntax_option_type __flags) {
+  char __equal_close[2]   = {':', ']'};
+  auto __closing_sequence = std::search(__first, __last, __equal_close, __equal_close + 2);
+
+  if (__closing_sequence == __last)
+    std::__throw_regex_error<regex_constants::error_brack>();
+
+  auto __class_type =
+      __machine.__get_traits().lookup_classname(__first, __closing_sequence, __flags & regex_constants::icase);
+
+  if (__class_type == 0)
+    std::__throw_regex_error<regex_constants::error_ctype>();
+
+  __buffer.__mask_ |= __class_type;
+  __first = std::next(__closing_sequence, 2);
+
+  return true;
+}
+
+template <class _CharT, class _Traits, class _ForwardIterator>
+bool __parse_equivalence_class(__interpreter<_CharT, _Traits>& __machine,
+                               __bracket_expr<_CharT, _Traits>& __buffer,
+                               _ForwardIterator& __first,
+                               _ForwardIterator __last) {
+  char __equal_close[2]   = {'=', ']'};
+  auto __closing_sequence = std::search(__first, __last, __equal_close, __equal_close + 2);
+
+  if (__closing_sequence == __last)
+    std::__throw_regex_error<regex_constants::error_brack>();
+
+  auto __collate_name = __machine.__get_traits().lookup_collatename(__first, __closing_sequence);
+  if (__collate_name.empty())
+    std::__throw_regex_error<regex_constants::error_collate>();
+
+  auto __equiv_name = __machine.__get_traits().transform_primary(__collate_name.begin(), __collate_name.end());
+  if (!__equiv_name.empty()) {
+    __buffer.__equivalences_.push_back(std::move(__equiv_name));
+    __first = std::next(__closing_sequence, 2);
+    return true;
+  }
+
+  switch (__collate_name.size()) {
+  case 1:
+    __buffer.__chars_.push_back(__collate_name[0]);
+    break;
+  case 2:
+    __buffer.__digraphs_.push_back(__collate_name[0]);
+    __buffer.__digraphs_.push_back(__collate_name[1]);
+    break;
+  default:
+    std::__throw_regex_error<regex_constants::error_collate>();
+  }
+  __first = std::next(__closing_sequence, 2);
+  return true;
+}
+
+template <class _CharT, class _Traits, class _ForwardIterator>
+void __parse_collating_symbol(__interpreter<_CharT, _Traits>& __machine,
+                              basic_string<_CharT>& __buffer,
+                              _ForwardIterator& __first,
+                              _ForwardIterator __last) {
+  char __equal_close[2]   = {'.', ']'};
+  auto __closing_sequence = std::search(__first, __last, __equal_close, __equal_close + 2);
+
+  if (__closing_sequence == __last)
+    std::__throw_regex_error<regex_constants::error_brack>();
+
+  __buffer = __machine.__get_traits().lookup_collatename(__first, __closing_sequence);
+  switch (__buffer.size()) {
+  case 1:
+  case 2:
+    break;
+  default:
+    std::__throw_regex_error<regex_constants::error_collate>();
+  }
+
+  __first = std::next(__closing_sequence, 2);
+}
+
+template <class _CharT, class _Traits, class _ForwardIterator>
+bool __parse_expression_term(
+    __interpreter<_CharT, _Traits>& __machine,
+    __bracket_expr<_CharT, _Traits>& __buffer,
+    _ForwardIterator& __first,
+    _ForwardIterator __last,
+    regex_constants::syntax_option_type __flags) {
+  _LIBCPP_ASSERT_INTERNAL(__first != __last, "Expected parseable character");
+
+  if (*__first == ']')
+    return false;
+  auto __next = std::next(__first);
+  if (__next == __last)
+    return false;
+
+  if (*__first == '[') {
+    if (*__next == '=') {
+      __first = ++__next;
+      return __regex::__parse_equivalence_class(__machine, __buffer, __first, __last);
+    }
+
+    if (*__next == ':') {
+      __first = ++__next;
+      return __regex::__parse_character_class(__machine, __buffer, __first, __last, __flags);
+    }
+  }
+
+  basic_string<_CharT> __start_range;
+  if (*__first == '[' && *__next == '.') {
+    __first = ++__next;
+    __regex::__parse_collating_symbol(__machine, __start_range, __first, __last);
+  } else {
+    __start_range = *__first;
+    ++__first;
+  }
+
+  if (__first == __last)
+    return false;
+
+  if (*__first == ']') {
+    if (__start_range.size() == 1) {
+      __buffer.__chars_.push_back(__start_range[0]);
+    } else {
+      _LIBCPP_ASSERT_INTERNAL(__start_range.size() == 2, "Unexpected range");
+      __buffer.__digraphs_.insert(__buffer.__digraphs_.end(), __start_range.begin(), __start_range.end());
+    }
+    return true;
+  }
+
+  __next = std::next(__first);
+  if (__next == __last)
+    return false;
+
+  if (*__first != '-' || *__next == ']') {
+    if (__start_range.size() == 1) {
+      __buffer.__chars_.push_back(__start_range[0]);
+    } else {
+      _LIBCPP_ASSERT_INTERNAL(__start_range.size() == 2, "Unexpected range");
+      __buffer.__digraphs_.insert(__buffer.__digraphs_.end(), __start_range.begin(), __start_range.end());
+    }
+    return true;
+  }
+
+  basic_string<_CharT> __end_range;
+  __first = __next;
+  ++__next;
+  if (__next == __last)
+    return false;
+  if (*__first == '[' && *__next == '.') {
+    __first = ++__next;
+    __parse_collating_symbol(__machine, __end_range, __first, __last);
+  } else {
+    __end_range = *__first;
+    ++__first;
+  }
+  __buffer.__ranges_.push_back(__start_range[0]);
+  __buffer.__ranges_.push_back(__start_range.size() == 2 ? __start_range[1] : '\0');
+  __buffer.__ranges_.push_back(__end_range[0]);
+  __buffer.__ranges_.push_back(__end_range.size() == 2 ? __end_range[1] : '\0');
+
+  return true;
+}
+
+template <class _CharT, class _Traits, class _ForwardIterator>
+void __parse_follow_list(
+    __interpreter<_CharT, _Traits>& __machine,
+    __bracket_expr<_CharT, _Traits>& __buffer,
+    _ForwardIterator& __first,
+    _ForwardIterator __last,
+    regex_constants::syntax_option_type __flags) {
+  _LIBCPP_ASSERT_INTERNAL(__first != __last, "Expected parseable character");
+
+  while (__regex::__parse_expression_term(__machine, __buffer, __first, __last, __flags))
+    ;
+}
+
+template <class _CharT, class _Traits, class _ForwardIterator>
+bool __parse_bracket_expression(
+    __interpreter<_CharT, _Traits>& __machine,
+    _ForwardIterator& __first,
+    _ForwardIterator __last,
+    regex_constants::syntax_option_type __flags) {
+  _LIBCPP_ASSERT_INTERNAL(__first != __last, "Expected parseable character");
+  if (*__first != '[')
+    return false;
+  ++__first;
+  if (__first == __last)
+    std::__throw_regex_error<regex_constants::error_brack>();
+  bool __negate = false;
+  if (*__first == '^') {
+    ++__first;
+    if (__first == __last)
+      std::__throw_regex_error<regex_constants::error_brack>();
+    __negate = true;
+  }
+  __bracket_expr<_CharT, _Traits> __buffer;
+
+  if (*__first == ']') {
+    __buffer.__chars_.push_back(']');
+    ++__first;
+    if (__first == __last)
+      std::__throw_regex_error<regex_constants::error_brack>();
+  }
+
+  __regex::__parse_follow_list(__machine, __buffer, __first, __last, __flags);
+  if (__first == __last)
+    std::__throw_regex_error<regex_constants::error_brack>();
+  if (*__first == '-') {
+    __buffer.__chars_.push_back('-');
+    ++__first;
+  }
+  if (__first == __last || *__first != ']')
+    std::__throw_regex_error<regex_constants::error_brack>();
+  ++__first;
+  __machine.__push_bracket_expr(__negate, __buffer);
+  return true;
+}
+
+// dup count parsing
+
+struct __dup_count_result {
+  size_t __num_;
+  bool __success_ = false;
+
+  __dup_count_result() = default;
+  __dup_count_result(size_t __num, bool __success) : __num_(__num), __success_(__success) {}
+
+  operator bool() const { return __success_; }
+};
+
+template <class _ForwardIterator>
+__dup_count_result __parse_dup_count(_ForwardIterator& __first, _ForwardIterator __last) {
+  if (__first == __last || *__first < '0' || *__first > '9')
+    return __dup_count_result();
+  size_t __num = 0;
+  for (; __first != __last && *__first >= '0' && *__first <= '9'; ++__first) {
+    if (__num >= numeric_limits<size_t>::max() / 10)
+      std::__throw_regex_error<regex_constants::error_badbrace>();
+    __num *= 10;
+    __num += *__first - '0';
+  }
+  return __dup_count_result(__num, true);
+}
+
+} // namespace __regex
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___REGEX_BASIC_PARSER_H
diff --git a/libcxx/include/__regex/regex_error.h b/libcxx/include/__regex/regex_error.h
new file mode 100644
index 0000000000000..925074ccc2485
--- /dev/null
+++ b/libcxx/include/__regex/regex_error.h
@@ -0,0 +1,176 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___REGEX_REGEX_ERROR_H
+#define _LIBCPP___REGEX_REGEX_ERROR_H
+
+#include <__config>
+#include <stdexcept>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace regex_constants {
+
+// syntax_option_type
+
+enum syntax_option_type {
+  icase    = 1 << 0,
+  nosubs   = 1 << 1,
+  optimize = 1 << 2,
+  collate  = 1 << 3,
+#ifdef _LIBCPP_ABI_REGEX_CONSTANTS_NONZERO
+  ECMAScript = 1 << 9,
+#else
+  ECMAScript = 0,
+#endif
+  basic    = 1 << 4,
+  extended = 1 << 5,
+  awk      = 1 << 6,
+  grep     = 1 << 7,
+  egrep    = 1 << 8,
+  // 1 << 9 may be used by ECMAScript
+  multiline = 1 << 10
+};
+
+_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR syntax_option_type __get_grammar(syntax_option_type __g) {
+#ifdef _LIBCPP_ABI_REGEX_CONSTANTS_NONZERO
+  return static_cast<syntax_option_type>(__g & 0x3F0);
+#else
+  return static_cast<syntax_option_type>(__g & 0x1F0);
+#endif
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR syntax_option_type operator~(syntax_option_type __x) {
+  return syntax_option_type(~int(__x) & 0x1FF);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR syntax_option_type
+operator&(syntax_option_type __x, syntax_option_type __y) {
+  return syntax_option_type(int(__x) & int(__y));
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR syntax_option_type
+operator|(syntax_option_type __x, syntax_option_type __y) {
+  return syntax_option_type(int(__x) | int(__y));
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR syntax_option_type
+operator^(syntax_option_type __x, syntax_option_type __y) {
+  return syntax_option_type(int(__x) ^ int(__y));
+}
+
+inline _LIBCPP_HIDE_FROM_ABI syntax_option_type& operator&=(syntax_option_type& __x, syntax_option_type __y) {
+  __x = __x & __y;
+  return __x;
+}
+
+inline _LIBCPP_HIDE_FROM_ABI syntax_option_type& operator|=(syntax_option_type& __x, syntax_option_type __y) {
+  __x = __x | __y;
+  return __x;
+}
+
+inline _LIBCPP_HIDE_FROM_ABI syntax_option_type& operator^=(syntax_option_type& __x, syntax_option_type __y) {
+  __x = __x ^ __y;
+  return __x;
+}
+
+// match_flag_type
+
+enum match_flag_type {
+  match_default     = 0,
+  match_not_bol     = 1 << 0,
+  match_not_eol     = 1 << 1,
+  match_not_bow     = 1 << 2,
+  match_not_eow     = 1 << 3,
+  match_any         = 1 << 4,
+  match_not_null    = 1 << 5,
+  match_continuous  = 1 << 6,
+  match_prev_avail  = 1 << 7,
+  format_default    = 0,
+  format_sed        = 1 << 8,
+  format_no_copy    = 1 << 9,
+  format_first_only = 1 << 10,
+  __no_update_pos   = 1 << 11,
+  __full_match      = 1 << 12
+};
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR match_flag_type operator~(match_flag_type __x) {
+  return match_flag_type(~int(__x) & 0x0FFF);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR match_flag_type operator&(match_flag_type __x, match_flag_type __y) {
+  return match_flag_type(int(__x) & int(__y));
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR match_flag_type operator|(match_flag_type __x, match_flag_type __y) {
+  return match_flag_type(int(__x) | int(__y));
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR match_flag_type operator^(match_flag_type __x, match_flag_type __y) {
+  return match_flag_type(int(__x) ^ int(__y));
+}
+
+inline _LIBCPP_HIDE_FROM_ABI match_flag_type& operator&=(match_flag_type& __x, match_flag_type __y) {
+  __x = __x & __y;
+  return __x;
+}
+
+inline _LIBCPP_HIDE_FROM_ABI match_flag_type& operator|=(match_flag_type& __x, match_flag_type __y) {
+  __x = __x | __y;
+  return __x;
+}
+
+inline _LIBCPP_HIDE_FROM_ABI match_flag_type& operator^=(match_flag_type& __x, match_flag_type __y) {
+  __x = __x ^ __y;
+  return __x;
+}
+
+enum error_type {
+  error_collate = 1,
+  error_ctype,
+  error_escape,
+  error_backref,
+  error_brack,
+  error_paren,
+  error_brace,
+  error_badbrace,
+  error_range,
+  error_space,
+  error_badrepeat,
+  error_complexity,
+  error_stack,
+  __re_err_grammar,
+  __re_err_empty,
+  __re_err_unknown,
+  __re_err_parse
+};
+
+} // namespace regex_constants
+
+class _LIBCPP_EXPORTED_FROM_ABI regex_error : public runtime_error {
+  regex_constants::error_type __code_;
+
+public:
+  explicit regex_error(regex_constants::error_type __ecode);
+  _LIBCPP_HIDE_FROM_ABI regex_error(const regex_error&) _NOEXCEPT = default;
+  ~regex_error() _NOEXCEPT override;
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI regex_constants::error_type code() const { return __code_; }
+};
+
+template <regex_constants::error_type _Ev>
+[[__noreturn__]] inline _LIBCPP_HIDE_FROM_ABI void __throw_regex_error() {
+#if _LIBCPP_HAS_EXCEPTIONS
+  throw regex_error(_Ev);
+#else
+  _LIBCPP_VERBOSE_ABORT("regex_error was thrown in -fno-exceptions mode");
+#endif
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___REGEX_REGEX_ERROR_H
diff --git a/libcxx/include/regex b/libcxx/include/regex
index 0be8b4703c725..7cdde4ecd52a3 100644
--- a/libcxx/include/regex
+++ b/libcxx/include/regex
@@ -823,6 +823,8 @@ typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;
 #    include <__memory/pointer_traits.h>
 #    include <__memory/shared_ptr.h>
 #    include <__memory_resource/polymorphic_allocator.h>
+#    include <__regex/basic_parser.h>
+#    include <__regex/regex_error.h>
 #    include <__type_traits/is_swappable.h>
 #    include <__utility/move.h>
 #    include <__utility/pair.h>
@@ -846,163 +848,6 @@ _LIBCPP_PUSH_MACROS
 _LIBCPP_BEGIN_NAMESPACE_STD
 _LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS
 
-namespace regex_constants {
-
-// syntax_option_type
-
-enum syntax_option_type {
-  icase    = 1 << 0,
-  nosubs   = 1 << 1,
-  optimize = 1 << 2,
-  collate  = 1 << 3,
-#    ifdef _LIBCPP_ABI_REGEX_CONSTANTS_NONZERO
-  ECMAScript = 1 << 9,
-#    else
-  ECMAScript = 0,
-#    endif
-  basic    = 1 << 4,
-  extended = 1 << 5,
-  awk      = 1 << 6,
-  grep     = 1 << 7,
-  egrep    = 1 << 8,
-  // 1 << 9 may be used by ECMAScript
-  multiline = 1 << 10
-};
-
-_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR syntax_option_type __get_grammar(syntax_option_type __g) {
-#    ifdef _LIBCPP_ABI_REGEX_CONSTANTS_NONZERO
-  return static_cast<syntax_option_type>(__g & 0x3F0);
-#    else
-  return static_cast<syntax_option_type>(__g & 0x1F0);
-#    endif
-}
-
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR syntax_option_type operator~(syntax_option_type __x) {
-  return syntax_option_type(~int(__x) & 0x1FF);
-}
-
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR syntax_option_type
-operator&(syntax_option_type __x, syntax_option_type __y) {
-  return syntax_option_type(int(__x) & int(__y));
-}
-
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR syntax_option_type
-operator|(syntax_option_type __x, syntax_option_type __y) {
-  return syntax_option_type(int(__x) | int(__y));
-}
-
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR syntax_option_type
-operator^(syntax_option_type __x, syntax_option_type __y) {
-  return syntax_option_type(int(__x) ^ int(__y));
-}
-
-inline _LIBCPP_HIDE_FROM_ABI syntax_option_type& operator&=(syntax_option_type& __x, syntax_option_type __y) {
-  __x = __x & __y;
-  return __x;
-}
-
-inline _LIBCPP_HIDE_FROM_ABI syntax_option_type& operator|=(syntax_option_type& __x, syntax_option_type __y) {
-  __x = __x | __y;
-  return __x;
-}
-
-inline _LIBCPP_HIDE_FROM_ABI syntax_option_type& operator^=(syntax_option_type& __x, syntax_option_type __y) {
-  __x = __x ^ __y;
-  return __x;
-}
-
-// match_flag_type
-
-enum match_flag_type {
-  match_default     = 0,
-  match_not_bol     = 1 << 0,
-  match_not_eol     = 1 << 1,
-  match_not_bow     = 1 << 2,
-  match_not_eow     = 1 << 3,
-  match_any         = 1 << 4,
-  match_not_null    = 1 << 5,
-  match_continuous  = 1 << 6,
-  match_prev_avail  = 1 << 7,
-  format_default    = 0,
-  format_sed        = 1 << 8,
-  format_no_copy    = 1 << 9,
-  format_first_only = 1 << 10,
-  __no_update_pos   = 1 << 11,
-  __full_match      = 1 << 12
-};
-
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR match_flag_type operator~(match_flag_type __x) {
-  return match_flag_type(~int(__x) & 0x0FFF);
-}
-
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR match_flag_type operator&(match_flag_type __x, match_flag_type __y) {
-  return match_flag_type(int(__x) & int(__y));
-}
-
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR match_flag_type operator|(match_flag_type __x, match_flag_type __y) {
-  return match_flag_type(int(__x) | int(__y));
-}
-
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR match_flag_type operator^(match_flag_type __x, match_flag_type __y) {
-  return match_flag_type(int(__x) ^ int(__y));
-}
-
-inline _LIBCPP_HIDE_FROM_ABI match_flag_type& operator&=(match_flag_type& __x, match_flag_type __y) {
-  __x = __x & __y;
-  return __x;
-}
-
-inline _LIBCPP_HIDE_FROM_ABI match_flag_type& operator|=(match_flag_type& __x, match_flag_type __y) {
-  __x = __x | __y;
-  return __x;
-}
-
-inline _LIBCPP_HIDE_FROM_ABI match_flag_type& operator^=(match_flag_type& __x, match_flag_type __y) {
-  __x = __x ^ __y;
-  return __x;
-}
-
-enum error_type {
-  error_collate = 1,
-  error_ctype,
-  error_escape,
-  error_backref,
-  error_brack,
-  error_paren,
-  error_brace,
-  error_badbrace,
-  error_range,
-  error_space,
-  error_badrepeat,
-  error_complexity,
-  error_stack,
-  __re_err_grammar,
-  __re_err_empty,
-  __re_err_unknown,
-  __re_err_parse
-};
-
-} // namespace regex_constants
-
-class _LIBCPP_EXPORTED_FROM_ABI regex_error : public runtime_error {
-  regex_constants::error_type __code_;
-
-public:
-  explicit regex_error(regex_constants::error_type __ecode);
-  _LIBCPP_HIDE_FROM_ABI regex_error(const regex_error&) _NOEXCEPT = default;
-  ~regex_error() _NOEXCEPT override;
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI regex_constants::error_type code() const { return __code_; }
-};
-
-template <regex_constants::error_type _Ev>
-[[__noreturn__]] inline _LIBCPP_HIDE_FROM_ABI void __throw_regex_error() {
-#    if _LIBCPP_HAS_EXCEPTIONS
-  throw regex_error(_Ev);
-#    else
-  _LIBCPP_VERBOSE_ABORT("regex_error was thrown in -fno-exceptions mode");
-#    endif
-}
-
 template <class _CharT>
 struct regex_traits {
 public:
@@ -1339,50 +1184,6 @@ inline int regex_traits<_CharT>::__regex_traits_value(wchar_t __ch, int __radix)
 }
 #    endif
 
-template <class _CharT>
-class __node;
-
-template <class _BidirectionalIterator>
-class sub_match;
-
-template <class _BidirectionalIterator, class _Allocator = allocator<sub_match<_BidirectionalIterator> > >
-class match_results;
-
-template <class _CharT>
-struct __state {
-  enum {
-    __end_state = -1000,
-    __consume_input,          // -999
-    __begin_marked_expr,      // -998
-    __end_marked_expr,        // -997
-    __pop_state,              // -996
-    __accept_and_consume,     // -995
-    __accept_but_not_consume, // -994
-    __reject,                 // -993
-    __split,
-    __repeat
-  };
-
-  int __do_;
-  const _CharT* __first_;
-  const _CharT* __current_;
-  const _CharT* __last_;
-  vector<sub_match<const _CharT*> > __sub_matches_;
-  vector<pair<size_t, const _CharT*> > __loop_data_;
-  const __node<_CharT>* __node_;
-  regex_constants::match_flag_type __flags_;
-  bool __at_first_;
-
-  _LIBCPP_HIDE_FROM_ABI __state()
-      : __do_(0),
-        __first_(nullptr),
-        __current_(nullptr),
-        __last_(nullptr),
-        __node_(nullptr),
-        __flags_(),
-        __at_first_(false) {}
-};
-
 // __node
 
 template <class _CharT>
@@ -1871,6 +1672,28 @@ void __word_boundary<_CharT, _Traits>::__exec(__state& __s) const {
   }
 }
 
+template <class _CharT, class _Traits>
+class __interpreter_state : public __owns_one_state<_CharT> {
+  __regex::__interpreter<_CharT, _Traits> __machine_;
+
+public:
+  _LIBCPP_HIDE_FROM_ABI __interpreter_state(__regex::__interpreter<_CharT, _Traits> __machine, __node<_CharT>* __s)
+      : __owns_one_state<_CharT>(__s), __machine_(std::move(__machine)) {}
+
+  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __exec(__state<_CharT>& __state) const override {
+    auto __exec_state = __machine_.__get_exec_state(__state.__sub_matches_, __state.__current_, __state.__at_first_);
+    if (!__exec_state.__execute(__state.__first_, __state.__last_)) {
+      __state.__do_ = std::__state<_CharT>::__reject;
+      __state.__node_ = nullptr;
+      return;
+    }
+    __state.__do_          = std::__state<_CharT>::__end_state;
+    auto& __matched_state  = __exec_state.__states_.top();
+    __state.__current_     = __matched_state.__current_;
+    __state.__sub_matches_ = __matched_state.__sub_matches_;
+  }
+};
+
 // __l_anchor
 
 template <class _CharT>
@@ -2475,37 +2298,6 @@ private:
   template <class _ForwardIterator>
   _ForwardIterator __parse(_ForwardIterator __first, _ForwardIterator __last);
   template <class _ForwardIterator>
-  _ForwardIterator __parse_basic_reg_exp(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_RE_expression(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_simple_RE(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_nondupl_RE(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_one_char_or_coll_elem_RE(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_Back_open_paren(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_Back_close_paren(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_Back_open_brace(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_Back_close_brace(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_BACKREF(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_ORD_CHAR(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_QUOTED_CHAR(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_RE_dupl_symbol(
-      _ForwardIterator __first,
-      _ForwardIterator __last,
-      __owns_one_state<_CharT>* __s,
-      unsigned __mexp_begin,
-      unsigned __mexp_end);
-  template <class _ForwardIterator>
   _ForwardIterator __parse_ERE_dupl_symbol(
       _ForwardIterator __first,
       _ForwardIterator __last,
@@ -2565,8 +2357,6 @@ private:
   template <class _ForwardIterator>
   _ForwardIterator __parse_pattern_character(_ForwardIterator __first, _ForwardIterator __last);
   template <class _ForwardIterator>
-  _ForwardIterator __parse_grep(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
   _ForwardIterator __parse_egrep(_ForwardIterator __first, _ForwardIterator __last);
   template <class _ForwardIterator>
   _ForwardIterator __parse_class_escape(
@@ -2806,15 +2596,21 @@ _ForwardIterator basic_regex<_CharT, _Traits>::__parse(_ForwardIterator __first,
     __first = __parse_ecma_exp(__first, __last);
     break;
   case basic:
-    __first = __parse_basic_reg_exp(__first, __last);
-    break;
+  case grep: {
+    __regex::__basic::__parser<_CharT, _Traits, _ForwardIterator> __parser(__first, __last, __traits_, flags());
+    if (__get_grammar(__flags_) == basic)
+      __parser.__parse_basic();
+    else
+      __parser.__parse_grep();
+    __end_->first() = new __interpreter_state<_CharT, _Traits>(__parser.__extract_interpreter(), __end_->first());
+    __end_          = static_cast<__owns_one_state<_CharT>*>(__end_->first());
+    __marked_count_ = __parser.mark_count();
+    return __last;
+  }
   case extended:
   case awk:
     __first = __parse_extended_reg_exp(__first, __last);
     break;
-  case grep:
-    __first = __parse_grep(__first, __last);
-    break;
   case egrep:
     __first = __parse_egrep(__first, __last);
     break;
@@ -2824,31 +2620,6 @@ _ForwardIterator basic_regex<_CharT, _Traits>::__parse(_ForwardIterator __first,
   return __first;
 }
 
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator
-basic_regex<_CharT, _Traits>::__parse_basic_reg_exp(_ForwardIterator __first, _ForwardIterator __last) {
-  if (__first != __last) {
-    if (*__first == '^') {
-      __push_l_anchor();
-      ++__first;
-    }
-    if (__first != __last) {
-      __first = __parse_RE_expression(__first, __last);
-      if (__first != __last) {
-        _ForwardIterator __temp = std::next(__first);
-        if (__temp == __last && *__first == '$') {
-          __push_r_anchor();
-          ++__first;
-        }
-      }
-    }
-    if (__first != __last)
-      std::__throw_regex_error<regex_constants::__re_err_empty>();
-  }
-  return __first;
-}
-
 template <class _CharT, class _Traits>
 template <class _ForwardIterator>
 _ForwardIterator
@@ -2918,73 +2689,6 @@ basic_regex<_CharT, _Traits>::__parse_ERE_expression(_ForwardIterator __first, _
   return __first;
 }
 
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator
-basic_regex<_CharT, _Traits>::__parse_RE_expression(_ForwardIterator __first, _ForwardIterator __last) {
-  while (true) {
-    _ForwardIterator __temp = __parse_simple_RE(__first, __last);
-    if (__temp == __first)
-      break;
-    __first = __temp;
-  }
-  return __first;
-}
-
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator basic_regex<_CharT, _Traits>::__parse_simple_RE(_ForwardIterator __first, _ForwardIterator __last) {
-  if (__first != __last) {
-    __owns_one_state<_CharT>* __e = __end_;
-    unsigned __mexp_begin         = __marked_count_;
-    _ForwardIterator __temp       = __parse_nondupl_RE(__first, __last);
-    if (__temp != __first)
-      __first = __parse_RE_dupl_symbol(__temp, __last, __e, __mexp_begin + 1, __marked_count_ + 1);
-  }
-  return __first;
-}
-
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator basic_regex<_CharT, _Traits>::__parse_nondupl_RE(_ForwardIterator __first, _ForwardIterator __last) {
-  _ForwardIterator __temp = __first;
-  __first                 = __parse_one_char_or_coll_elem_RE(__first, __last);
-  if (__temp == __first) {
-    __temp = __parse_Back_open_paren(__first, __last);
-    if (__temp != __first) {
-      __push_begin_marked_subexpression();
-      unsigned __temp_count = __marked_count_;
-      __first               = __parse_RE_expression(__temp, __last);
-      __temp                = __parse_Back_close_paren(__first, __last);
-      if (__temp == __first)
-        std::__throw_regex_error<regex_constants::error_paren>();
-      __push_end_marked_subexpression(__temp_count);
-      __first = __temp;
-    } else
-      __first = __parse_BACKREF(__first, __last);
-  }
-  return __first;
-}
-
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator
-basic_regex<_CharT, _Traits>::__parse_one_char_or_coll_elem_RE(_ForwardIterator __first, _ForwardIterator __last) {
-  _ForwardIterator __temp = __parse_ORD_CHAR(__first, __last);
-  if (__temp == __first) {
-    __temp = __parse_QUOTED_CHAR(__first, __last);
-    if (__temp == __first) {
-      if (__temp != __last && *__temp == '.') {
-        __push_match_any();
-        ++__temp;
-      } else
-        __temp = __parse_bracket_expression(__first, __last);
-    }
-  }
-  __first = __temp;
-  return __first;
-}
-
 template <class _CharT, class _Traits>
 template <class _ForwardIterator>
 _ForwardIterator
@@ -3004,89 +2708,6 @@ basic_regex<_CharT, _Traits>::__parse_one_char_or_coll_elem_ERE(_ForwardIterator
   return __first;
 }
 
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator
-basic_regex<_CharT, _Traits>::__parse_Back_open_paren(_ForwardIterator __first, _ForwardIterator __last) {
-  if (__first != __last) {
-    _ForwardIterator __temp = std::next(__first);
-    if (__temp != __last) {
-      if (*__first == '\\' && *__temp == '(')
-        __first = ++__temp;
-    }
-  }
-  return __first;
-}
-
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator
-basic_regex<_CharT, _Traits>::__parse_Back_close_paren(_ForwardIterator __first, _ForwardIterator __last) {
-  if (__first != __last) {
-    _ForwardIterator __temp = std::next(__first);
-    if (__temp != __last) {
-      if (*__first == '\\' && *__temp == ')')
-        __first = ++__temp;
-    }
-  }
-  return __first;
-}
-
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator
-basic_regex<_CharT, _Traits>::__parse_Back_open_brace(_ForwardIterator __first, _ForwardIterator __last) {
-  if (__first != __last) {
-    _ForwardIterator __temp = std::next(__first);
-    if (__temp != __last) {
-      if (*__first == '\\' && *__temp == '{')
-        __first = ++__temp;
-    }
-  }
-  return __first;
-}
-
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator
-basic_regex<_CharT, _Traits>::__parse_Back_close_brace(_ForwardIterator __first, _ForwardIterator __last) {
-  if (__first != __last) {
-    _ForwardIterator __temp = std::next(__first);
-    if (__temp != __last) {
-      if (*__first == '\\' && *__temp == '}')
-        __first = ++__temp;
-    }
-  }
-  return __first;
-}
-
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator basic_regex<_CharT, _Traits>::__parse_BACKREF(_ForwardIterator __first, _ForwardIterator __last) {
-  if (__first != __last) {
-    _ForwardIterator __temp = std::next(__first);
-    if (__temp != __last && *__first == '\\' && __test_back_ref(*__temp))
-      __first = ++__temp;
-  }
-  return __first;
-}
-
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator basic_regex<_CharT, _Traits>::__parse_ORD_CHAR(_ForwardIterator __first, _ForwardIterator __last) {
-  if (__first != __last) {
-    _ForwardIterator __temp = std::next(__first);
-    if (__temp == __last && *__first == '$')
-      return __first;
-    // Not called inside a bracket
-    if (*__first == '.' || *__first == '\\' || *__first == '[')
-      return __first;
-    __push_char(*__first);
-    ++__first;
-  }
-  return __first;
-}
-
 template <class _CharT, class _Traits>
 template <class _ForwardIterator>
 _ForwardIterator basic_regex<_CharT, _Traits>::__parse_ORD_CHAR_ERE(_ForwardIterator __first, _ForwardIterator __last) {
@@ -3119,30 +2740,6 @@ _ForwardIterator basic_regex<_CharT, _Traits>::__parse_ORD_CHAR_ERE(_ForwardIter
   return __first;
 }
 
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator basic_regex<_CharT, _Traits>::__parse_QUOTED_CHAR(_ForwardIterator __first, _ForwardIterator __last) {
-  if (__first != __last) {
-    _ForwardIterator __temp = std::next(__first);
-    if (__temp != __last) {
-      if (*__first == '\\') {
-        switch (*__temp) {
-        case '^':
-        case '.':
-        case '*':
-        case '[':
-        case '$':
-        case '\\':
-          __push_char(*__temp);
-          __first = ++__temp;
-          break;
-        }
-      }
-    }
-  }
-  return __first;
-}
-
 template <class _CharT, class _Traits>
 template <class _ForwardIterator>
 _ForwardIterator
@@ -3181,57 +2778,6 @@ basic_regex<_CharT, _Traits>::__parse_QUOTED_CHAR_ERE(_ForwardIterator __first,
   return __first;
 }
 
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator basic_regex<_CharT, _Traits>::__parse_RE_dupl_symbol(
-    _ForwardIterator __first,
-    _ForwardIterator __last,
-    __owns_one_state<_CharT>* __s,
-    unsigned __mexp_begin,
-    unsigned __mexp_end) {
-  if (__first != __last) {
-    if (*__first == '*') {
-      __push_greedy_inf_repeat(0, __s, __mexp_begin, __mexp_end);
-      ++__first;
-    } else {
-      _ForwardIterator __temp = __parse_Back_open_brace(__first, __last);
-      if (__temp != __first) {
-        int __min = 0;
-        __first   = __temp;
-        __temp    = __parse_DUP_COUNT(__first, __last, __min);
-        if (__temp == __first)
-          std::__throw_regex_error<regex_constants::error_badbrace>();
-        __first = __temp;
-        if (__first == __last)
-          std::__throw_regex_error<regex_constants::error_brace>();
-        if (*__first != ',') {
-          __temp = __parse_Back_close_brace(__first, __last);
-          if (__temp == __first)
-            std::__throw_regex_error<regex_constants::error_brace>();
-          __push_loop(__min, __min, __s, __mexp_begin, __mexp_end, true);
-          __first = __temp;
-        } else {
-          ++__first; // consume ','
-          int __max = -1;
-          __first   = __parse_DUP_COUNT(__first, __last, __max);
-          __temp    = __parse_Back_close_brace(__first, __last);
-          if (__temp == __first)
-            std::__throw_regex_error<regex_constants::error_brace>();
-          if (__max == -1)
-            __push_greedy_inf_repeat(__min, __s, __mexp_begin, __mexp_end);
-          else {
-            if (__max < __min)
-              std::__throw_regex_error<regex_constants::error_badbrace>();
-            __push_loop(__min, __max, __s, __mexp_begin, __mexp_end, true);
-          }
-          __first = __temp;
-        }
-      }
-    }
-  }
-  return __first;
-}
-
 template <class _CharT, class _Traits>
 template <class _ForwardIterator>
 _ForwardIterator basic_regex<_CharT, _Traits>::__parse_ERE_dupl_symbol(
@@ -4044,33 +3590,6 @@ basic_regex<_CharT, _Traits>::__parse_pattern_character(_ForwardIterator __first
   return __first;
 }
 
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator basic_regex<_CharT, _Traits>::__parse_grep(_ForwardIterator __first, _ForwardIterator __last) {
-  __owns_one_state<_CharT>* __sa = __end_;
-  _ForwardIterator __t1          = std::find(__first, __last, _CharT('\n'));
-  if (__t1 != __first)
-    __parse_basic_reg_exp(__first, __t1);
-  else
-    __push_empty();
-  __first = __t1;
-  if (__first != __last)
-    ++__first;
-  while (__first != __last) {
-    __t1                           = std::find(__first, __last, _CharT('\n'));
-    __owns_one_state<_CharT>* __sb = __end_;
-    if (__t1 != __first)
-      __parse_basic_reg_exp(__first, __t1);
-    else
-      __push_empty();
-    __push_alternation(__sa, __sb);
-    __first = __t1;
-    if (__first != __last)
-      ++__first;
-  }
-  return __first;
-}
-
 template <class _CharT, class _Traits>
 template <class _ForwardIterator>
 _ForwardIterator basic_regex<_CharT, _Traits>::__parse_egrep(_ForwardIterator __first, _ForwardIterator __last) {
@@ -5384,8 +4903,8 @@ typedef regex_iterator<wstring::const_iterator> wsregex_iterator;
 
 template <class _BidirectionalIterator, class _CharT, class _Traits>
 class _LIBCPP_PREFERRED_NAME(cregex_iterator) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wcregex_iterator))
-    _LIBCPP_PREFERRED_NAME(sregex_iterator)
-        _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wsregex_iterator)) regex_iterator {
+    _LIBCPP_PREFERRED_NAME(sregex_iterator) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wsregex_iterator))
+        regex_iterator {
 public:
   typedef basic_regex<_CharT, _Traits> regex_type;
   typedef match_results<_BidirectionalIterator> value_type;
diff --git a/libcxx/test/std/re/re.alg/re.alg.search/basic.pass.cpp b/libcxx/test/std/re/re.alg/re.alg.search/basic.pass.cpp
index 74b4d6341e9de..80918d2b2958a 100644
--- a/libcxx/test/std/re/re.alg/re.alg.search/basic.pass.cpp
+++ b/libcxx/test/std/re/re.alg/re.alg.search/basic.pass.cpp
@@ -29,6 +29,18 @@ int main(int, char**)
         assert(m.size() == 0);
         assert(m.empty());
     }
+    {
+        std::cmatch m;
+        assert(!std::regex_search("a", m, std::regex("\\0", std::regex_constants::basic)));
+        assert(m.size() == 0);
+        assert(m.empty());
+    }
+    {
+        std::cmatch m;
+        assert(!std::regex_search("a", m, std::regex("[a-[.hyphen.]]", std::regex_constants::basic)));
+        assert(m.size() == 0);
+        assert(m.empty());
+    }
     {
         std::cmatch m;
         const char s[] = "a";
diff --git a/libcxx/test/std/re/re.grammar/excessive_brace_count.pass.cpp b/libcxx/test/std/re/re.grammar/excessive_brace_count.pass.cpp
index 6ed2645be89b5..0435ca29c94b0 100644
--- a/libcxx/test/std/re/re.grammar/excessive_brace_count.pass.cpp
+++ b/libcxx/test/std/re/re.grammar/excessive_brace_count.pass.cpp
@@ -20,7 +20,8 @@ int main(int, char**) {
   for (std::regex_constants::syntax_option_type op :
        {std::regex::basic, std::regex::grep}) {
     try {
-      TEST_IGNORE_NODISCARD std::regex("a\\{100000000000000000\\}", op);
+      auto regex = "a\\{" + std::to_string(std::numeric_limits<size_t>::max()) + "1\\}";
+      TEST_IGNORE_NODISCARD std::regex(regex, op);
       assert(false);
     } catch (const std::regex_error &e) {
       assert(e.code() == std::regex_constants::error_badbrace);

>From 7bbeb0e2e53afaa53fbac8d79e8e16a831502bbc Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Thu, 5 Mar 2026 12:05:32 +0100
Subject: [PATCH 03/21] [libc++] Regex extended syntax

---
 libcxx/include/CMakeLists.txt                 |   1 +
 libcxx/include/__regex/basic_parser.h         |  11 +-
 libcxx/include/__regex/extended_parser.h      | 287 ++++++++++++++++++
 libcxx/include/__regex/interpreter.h          |  87 ++++--
 libcxx/include/__regex/parser_common.h        |  60 ++++
 libcxx/include/__regex/regex_error.h          |   2 +
 libcxx/include/regex                          | 223 +-------------
 .../re.grammar/excessive_brace_count.pass.cpp |   3 +-
 8 files changed, 433 insertions(+), 241 deletions(-)
 create mode 100644 libcxx/include/__regex/extended_parser.h

diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 1178b29eaedbe..24a4bb24d3c6f 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -795,6 +795,7 @@ set(files
   __ranges/zip_transform_view.h
   __ranges/zip_view.h
   __regex/basic_parser.h
+  __regex/extended_parser.h
   __regex/interpreter.h
   __regex/parser_common.h
   __regex/regex_error.h
diff --git a/libcxx/include/__regex/basic_parser.h b/libcxx/include/__regex/basic_parser.h
index d32b957557fc6..f744df1e40274 100644
--- a/libcxx/include/__regex/basic_parser.h
+++ b/libcxx/include/__regex/basic_parser.h
@@ -121,11 +121,13 @@ class __parser {
 
     if (__parse_escaped_character('(')) {
       size_t __subexpr_num = __marked_count_++;
-      __machine_.__push_subexpression_begin(__subexpr_num);
+      if (!(__flags_ & regex_constants::nosubs))
+        __machine_.__push_subexpression_begin(__subexpr_num);
       __parse_re_expression();
       if (!__parse_escaped_character(')'))
         std::__throw_regex_error<regex_constants::error_paren>();
-      __machine_.__push_subexpression_end(__subexpr_num);
+      if (!(__flags_ & regex_constants::nosubs))
+        __machine_.__push_subexpression_end(__subexpr_num);
       return true;
     } else {
       return __parse_backref();
@@ -220,7 +222,7 @@ class __parser {
 public:
   __parser(
       _ForwardIterator __first, _ForwardIterator __last, _Traits __traits, regex_constants::syntax_option_type __flags)
-      : __machine_(__traits), __first_(__first), __last_(__last), __flags_(__flags) {}
+      : __machine_(__traits, true), __first_(__first), __last_(__last), __flags_(__flags) {}
 
   void __parse_basic() {
     __parse_basic_expr();
@@ -241,11 +243,12 @@ class __parser {
     while (__first_ != __last_) {
       __newline = std::find(__first_, __last_, '\n');
       std::swap(__last_, __newline);
+      auto __expr2_start = __machine_.size();
       __parse_basic_expr();
       std::swap(__last_, __newline);
       if (__first_ != __newline)
         std::__throw_regex_error<regex_constants::__re_err_grammar>();
-      __machine_.__push_alternative(0, __machine_.size());
+      __machine_.__push_alternative(0, __expr2_start);
       if (__first_ != __last_)
         ++__first_;
     }
diff --git a/libcxx/include/__regex/extended_parser.h b/libcxx/include/__regex/extended_parser.h
new file mode 100644
index 0000000000000..92906880eec44
--- /dev/null
+++ b/libcxx/include/__regex/extended_parser.h
@@ -0,0 +1,287 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___REGEX_EXTENDED_PARSER_H
+#define _LIBCPP___REGEX_EXTENDED_PARSER_H
+
+#include <__algorithm/search.h>
+#include <__config>
+#include <__iterator/next.h>
+#include <__regex/interpreter.h>
+#include <__regex/parser_common.h>
+#include <__regex/regex_error.h>
+#include <__utility/exchange.h>
+#include <string>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace __regex::__extended {
+
+template <class _CharT, class _Traits, class _ForwardIterator>
+class __parser {
+  __interpreter<_CharT, _Traits> __machine_;
+  _ForwardIterator __first_;
+  _ForwardIterator __last_;
+  regex_constants::syntax_option_type __flags_ = {};
+  uint8_t __marked_count_                      = 0;
+  size_t __open_count_                         = 0;
+
+  bool __parse_ord_char() {
+    _LIBCPP_ASSERT_INTERNAL(__first_ != __last_, "Expected valid character");
+    switch (*__first_) {
+    case '^':
+    case '.':
+    case '[':
+    case '$':
+    case '(':
+    case '|':
+    case '*':
+    case '+':
+    case '?':
+    case '{':
+    case '\\':
+      return false;
+    case ')':
+      if (__open_count_ != 0)
+        return false;
+      [[__fallthrough__]];
+    default:
+      __machine_.__push_char_matcher(*__first_, __flags_);
+      ++__first_;
+      return true;
+    }
+  }
+  bool __parse_quoted_char() {
+    _LIBCPP_ASSERT_INTERNAL(__first_ != __last_, "Expected valid character");
+    auto __next = std::next(__first_);
+    if (__next == __last_ || *__first_ != '\\')
+      return false;
+    switch (*__next) {
+    case '^':
+    case '.':
+    case '*':
+    case '[':
+    case '$':
+    case '\\':
+    case '(':
+    case ')':
+    case '|':
+    case '+':
+    case '?':
+    case '{':
+    case '}':
+      __machine_.__push_char_matcher(*__next, __flags_);
+      __first_ = ++__next;
+      return true;
+    default:
+      if (regex_constants::__get_grammar(__flags_) == regex_constants::awk) {
+        __first_ = __next;
+        __machine_.__push_char_matcher(__parse_awk_escape<_CharT>(__first_, __last_));
+        return true;
+      }
+      auto __val = __machine_.__get_traits().value(*__next, 10);
+      if (__val < 1 || __val > 9)
+        return false;
+      if (__val > __marked_count_)
+        std::__throw_regex_error<regex_constants::error_backref>();
+      __machine_.__push_backref_matcher(__val);
+      __first_ = ++__next;
+      return true;
+    }
+  }
+
+  bool __parse_one_char_or_coll_elem() {
+    if (__first_ == __last_)
+      return false;
+    if (__parse_ord_char() || __parse_quoted_char())
+      return true;
+    if (*__first_ == '.') {
+      __machine_.__push_any_matcher();
+      ++__first_;
+      return true;
+    }
+    return __regex::__parse_bracket_expression(__machine_, __first_, __last_, __flags_);
+  }
+
+  bool __parse_dupl_symbol(size_t __expr_start) {
+    if (__first_ == __last_)
+      return false;
+    switch (*__first_) {
+    case '*': {
+      ++__first_;
+      __machine_.__push_n_to_m_matcher(__expr_start, 0, numeric_limits<size_t>::max());
+    } break;
+
+    case '+': {
+      ++__first_;
+      __machine_.__push_n_to_m_matcher(__expr_start, 1, numeric_limits<size_t>::max());
+    } break;
+
+    case '?': {
+      ++__first_;
+      __machine_.__push_n_to_m_matcher(__expr_start, 0, 1);
+    } break;
+
+    case '{': {
+      ++__first_;
+      size_t __min;
+      if (auto __res = __regex::__parse_dup_count(__first_, __last_)) {
+        __min = __res.__num_;
+      } else {
+        std::__throw_regex_error<regex_constants::error_badbrace>();
+      }
+      if (__first_ == __last_)
+        std::__throw_regex_error<regex_constants::error_brace>();
+
+      switch (*__first_) {
+      case '}': {
+        ++__first_;
+        __machine_.__push_n_matcher(__expr_start, __min);
+        return true;
+      } break;
+
+      case ',': {
+        ++__first_;
+        if (__first_ == __last_)
+          std::__throw_regex_error<regex_constants::error_badbrace>();
+        if (*__first_ == '}') {
+          ++__first_;
+          __machine_.__push_n_to_m_matcher(__expr_start, __min, numeric_limits<size_t>::max());
+          return true;
+        }
+
+        size_t __max;
+        if (auto __res = __regex::__parse_dup_count(__first_, __last_)) {
+          __max = __res.__num_;
+        } else {
+          std::__throw_regex_error<regex_constants::error_brace>();
+        }
+        if (__first_ == __last_ || *__first_ != '}')
+          std::__throw_regex_error<regex_constants::error_brace>();
+        ++__first_;
+        if (__max < __min)
+          std::__throw_regex_error<regex_constants::error_badbrace>();
+        __machine_.__push_n_to_m_matcher(__expr_start, __min, __max);
+        return true;
+      } break;
+      default:
+        std::__throw_regex_error<regex_constants::error_badbrace>();
+      }
+    } break;
+    }
+    return false;
+  }
+
+  bool __parse_expression() {
+    if (__first_ == __last_)
+      return false;
+    size_t __expr_start = __machine_.size();
+    if (!__parse_one_char_or_coll_elem()) {
+      switch (*__first_) {
+      case '^':
+        ++__first_;
+        __machine_.__push_start_anchor();
+        break;
+      case '$':
+        ++__first_;
+        __machine_.__push_end_anchor();
+        break;
+      case '(': {
+        ++__first_;
+        size_t __subexpr_num = __marked_count_;
+        __marked_count_ += !(__flags_ & regex_constants::nosubs);
+        ++__open_count_;
+        if (!(__flags_ & regex_constants::nosubs))
+          __machine_.__push_subexpression_begin(__subexpr_num);
+        __parse_reg_exp(__machine_.size());
+        if (__first_ == __last_ || *__first_ != ')')
+          std::__throw_regex_error<regex_constants::error_paren>();
+        ++__first_;
+        --__open_count_;
+        if (!(__flags_ & regex_constants::nosubs))
+          __machine_.__push_subexpression_end(__subexpr_num);
+      } break;
+      default:
+        return false;
+      }
+    }
+    __parse_dupl_symbol(__expr_start);
+    return true;
+  }
+
+  bool __parse_branch() {
+    if (!__parse_expression())
+      std::__throw_regex_error<regex_constants::__re_err_empty>();
+    while (__parse_expression())
+      ;
+    return true;
+  }
+
+  void __parse_reg_exp(size_t __expr_start) {
+    if (!__parse_branch())
+      std::__throw_regex_error<regex_constants::__re_err_empty>();
+
+    while (__first_ != __last_ && *__first_ == '|') {
+      ++__first_;
+      auto __expr2_start = __machine_.size();
+      if (!__parse_branch())
+        std::__throw_regex_error<regex_constants::__re_err_empty>();
+      __machine_.__push_alternative(__expr_start, __expr2_start);
+    }
+  }
+
+public:
+  __parser(
+      _ForwardIterator __first, _ForwardIterator __last, _Traits __traits, regex_constants::syntax_option_type __flags)
+      : __machine_(__traits, true), __first_(__first), __last_(__last), __flags_(__flags) {}
+
+  void __parse_extended() {
+    __parse_reg_exp(0);
+    if (__first_ != __last_)
+      std::__throw_regex_error<regex_constants::__re_err_parse>();
+    __machine_.__push_end_state();
+  }
+
+  void __parse_egrep() {
+    auto __newline = std::find(__first_, __last_, '\n');
+    if (__newline != __first_) {
+      std::swap(__last_, __newline);
+      __parse_extended();
+      std::swap(__last_, __newline);
+      if (__first_ != __newline)
+        std::__throw_regex_error<regex_constants::__re_err_grammar>();
+    }
+    if (__first_ != __last_)
+      ++__first_;
+    while (__first_ != __last_) {
+      __newline = std::find(__first_, __last_, '\n');
+      auto __expr2_start = __machine_.size();
+      if (__newline != __first_) {
+        std::swap(__last_, __newline);
+        __parse_extended();
+        std::swap(__last_, __newline);
+        if (__first_ != __newline)
+          std::__throw_regex_error<regex_constants::__re_err_grammar>();
+      } else {
+        __machine_.__push_end_state();
+      }
+      __machine_.__push_alternative(0, __expr2_start);
+      if (__first_ != __last_)
+        ++__first_;
+    }
+    __machine_.__push_end_state();
+  }
+
+  __interpreter<_CharT, _Traits> __extract_interpreter() { return std::move(__machine_); }
+  size_t mark_count() const { return __marked_count_; }
+};
+} // namespace __regex::__extended
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___REGEX_EXTENDED_PARSER_H
diff --git a/libcxx/include/__regex/interpreter.h b/libcxx/include/__regex/interpreter.h
index 515ce2cca3e08..4bcff9d7c7f79 100644
--- a/libcxx/include/__regex/interpreter.h
+++ b/libcxx/include/__regex/interpreter.h
@@ -122,6 +122,7 @@ class __interpreter {
   vector<__interpreter_info<_CharT> > __machine_;
   vector<size_t> __initial_loop_values_;
   _Traits __traits_;
+  bool __find_longest_;
 
   static size_t __read_uleb(const vector<__interpreter_info<_CharT> >& __machine, size_t& __current_pos) {
     size_t __result = 0;
@@ -137,6 +138,14 @@ class __interpreter {
   }
 
   struct __global_execution_state {
+    struct __local_execution_state;
+
+    bool __at_first_;
+    stack<__local_execution_state> __states_;
+    const __interpreter& __machine_;
+    regex_constants::match_flag_type __flags_;
+    size_t __counter_ = 0;
+
     struct __local_execution_state {
       const _CharT* __current_;
       vector<sub_match<const _CharT*> > __sub_matches_;
@@ -146,6 +155,7 @@ class __interpreter {
 
       bool __execute(const _CharT* __first, const _CharT* __last, __global_execution_state& __gstate) {
         while (true) {
+          ++__gstate.__counter_;
           auto __st = __gstate.__machine()[__current_pos_++].__state_;
           switch (__st) {
             using enum __state;
@@ -161,7 +171,7 @@ class __interpreter {
           } break;
 
           case __end_state: {
-            return true;
+            return !(__gstate.__flags_ & regex_constants::match_flag_type::__full_match) || __current_ == __last;
           }
 
           case __match_any: {
@@ -185,9 +195,8 @@ class __interpreter {
 
           case __branch_alternative: {
             auto __offset = __read_uleb(__gstate.__machine(), __current_pos_);
-            auto __cpy    = *this;
-            __cpy.__current_pos_ += __offset;
-            __gstate.__states_.push(std::move(__cpy));
+            __gstate.__states_.push(*this);
+            __current_pos_ += __offset;
             break;
           }
 
@@ -387,27 +396,43 @@ class __interpreter {
       }
     };
 
-    bool __at_first_;
-    stack<__local_execution_state> __states_;
-    const __interpreter& __machine_;
-
-    __global_execution_state(bool __at_first, __local_execution_state __initial_state, const __interpreter& __machine)
-        : __at_first_(__at_first), __machine_(__machine) {
-      __states_.push(std::move(__initial_state));
-    }
-
-    const vector<__interpreter_info<_CharT> >& __machine() { return __machine_.__machine_; }
+    const vector<__interpreter_info<_CharT>>& __machine() { return __machine_.__machine_; }
 
     bool __execute(const _CharT* __first, const _CharT* __last) {
-      while (!__states_.empty()) {
-        auto __st = std::move(__states_.top());
-        __states_.pop();
-        if (__st.__execute(__first, __last, *this)) {
-          __states_.push(std::move(__st));
-          return true;
+      size_t __length = __last - __first + 1;
+      if (__machine_.__find_longest_) {
+        __local_execution_state __best_state;
+        bool __found_match = false;
+        while (!__states_.empty()) {
+          if (__counter_ / _LIBCPP_REGEX_COMPLEXITY_FACTOR >= __length)
+            std::__throw_regex_error<regex_constants::error_complexity>();
+          auto __state = std::move(__states_.top());
+          __states_.pop();
+          if (__state.__execute(__first, __last, *this)) {
+            if (!__found_match || __best_state.__current_ < __state.__current_)
+              __best_state = std::move(__state);
+            if (__best_state.__current_ == __last) {
+              __states_.push(std::move(__best_state));
+              return true;
+            }
+            __found_match = true;
+          }
+        }
+        __states_.push(std::move(__best_state));
+        return __found_match;
+      } else {
+        while (!__states_.empty()) {
+          if (__counter_ / _LIBCPP_REGEX_COMPLEXITY_FACTOR >= __length)
+            std::__throw_regex_error<regex_constants::error_complexity>();
+          auto __state = std::move(__states_.top());
+          __states_.pop();
+          if (__state.__execute(__first, __last, *this)) {
+            __states_.push(std::move(__state));
+            return true;
+          }
         }
+        return false;
       }
-      return false;
     }
   };
 
@@ -446,7 +471,7 @@ class __interpreter {
   }
 
 public:
-  __interpreter(_Traits __traits) : __traits_(__traits) {}
+  __interpreter(_Traits __traits, bool __find_longest) : __traits_(__traits), __find_longest_(__find_longest) {}
 
   void __push_any_matcher() { push_back(__state::__match_any); }
   void __push_end_state() { push_back(__state::__end_state); }
@@ -503,13 +528,14 @@ class __interpreter {
 
   void __push_alternative(size_t __expr1_start, size_t __expr2_start) {
     vector<__interpreter_info<_CharT> > __buffer;
+    __push_relative_jump(__buffer, size() - __expr2_start);
+    insert(__expr2_start, __buffer);
+    __expr2_start += __buffer.size();
+    __buffer.clear();
     __buffer.push_back(__state::__branch_alternative);
     __write_uleb(__buffer, __expr2_start - __expr1_start);
     insert(__expr1_start, __buffer);
     __expr2_start += __buffer.size();
-    __buffer.clear();
-    __push_relative_jump(__buffer, size() - __expr2_start);
-    insert(__expr2_start, __buffer);
   }
 
   void __push_bracket_expr(bool __negate, const __bracket_expr<_CharT, _Traits>& __expr) {
@@ -535,15 +561,20 @@ class __interpreter {
 
   size_t size() const { return __machine_.size(); }
 
-  __global_execution_state
-  __get_exec_state(vector<sub_match<const _CharT*> >& __sub_matches, const _CharT* __current, bool __at_first) const {
+  __global_execution_state __get_exec_state(
+      vector<sub_match<const _CharT*>>& __sub_matches,
+      const _CharT* __current,
+      bool __at_first,
+      regex_constants::match_flag_type __flags) const {
     typename __global_execution_state::__local_execution_state __base_state;
     __base_state.__sub_matches_ = __sub_matches;
     __base_state.__current_     = __current;
     __base_state.__loop_values_ = __initial_loop_values_;
     __base_state.__loop_starts_.resize(__initial_loop_values_.size());
     __base_state.__current_pos_ = 0;
-    return __global_execution_state(__at_first, __base_state, *this);
+    stack<typename __global_execution_state::__local_execution_state> __s;
+    __s.push(__base_state);
+    return __global_execution_state{__at_first, __s, *this, __flags};
   }
 
   _Traits __get_traits() { return __traits_; }
diff --git a/libcxx/include/__regex/parser_common.h b/libcxx/include/__regex/parser_common.h
index a7c344dcd33bf..44b5ebd563f05 100644
--- a/libcxx/include/__regex/parser_common.h
+++ b/libcxx/include/__regex/parser_common.h
@@ -18,6 +18,56 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace __regex {
 
+template <class _CharT, class _ForwardIterator>
+_CharT __parse_awk_escape(_ForwardIterator& __first, _ForwardIterator __last) {
+  switch (*__first) {
+  case '\\':
+  case '"':
+  case '/':
+    return *__first++;
+
+  case 'a':
+    ++__first;
+    return '\a';
+
+  case 'b':
+    ++__first;
+    return '\b';
+
+  case 'f':
+    ++__first;
+    return '\f';
+
+  case 'n':
+    ++__first;
+    return '\n';
+
+  case 'r':
+    ++__first;
+    return '\r';
+
+  case 't':
+    ++__first;
+    return '\t';
+
+  case 'v':
+    ++__first;
+    return '\v';
+  }
+
+  auto __is_base_8_char = [](_CharT __c) { return __c >= '0' && __c <= '7'; };
+
+  if (!__is_base_8_char(*__first))
+    std::__throw_regex_error<regex_constants::error_escape>();
+  unsigned __val = *__first - '0';
+  if (++__first != __last && __is_base_8_char(*__first)) {
+    __val = 8 * __val + *__first - '0';
+    if (++__first != __last && __is_base_8_char(*__first))
+      __val = 8 * __val + *__first++ - '0';
+  }
+  return _CharT(__val);
+}
+
 // bracket expression parsing
 
 template <class _CharT, class _Traits, class _ForwardIterator>
@@ -136,6 +186,11 @@ bool __parse_expression_term(
   if (*__first == '[' && *__next == '.') {
     __first = ++__next;
     __regex::__parse_collating_symbol(__machine, __start_range, __first, __last);
+  } else if (auto __grammar = regex_constants::__get_grammar(__flags);
+             __grammar == regex_constants::awk && *__first == '\\') {
+    if (++__first == __last)
+      return false;
+    __start_range = __parse_awk_escape<_CharT>(__first, __last);
   } else {
     __start_range = *__first;
     ++__first;
@@ -176,6 +231,11 @@ bool __parse_expression_term(
   if (*__first == '[' && *__next == '.') {
     __first = ++__next;
     __parse_collating_symbol(__machine, __end_range, __first, __last);
+  } else if (auto __grammar = regex_constants::__get_grammar(__flags);
+             __grammar == regex_constants::awk && *__first == '\\') {
+    if (++__first == __last)
+      return false;
+    __start_range = __parse_awk_escape<_CharT>(__first, __last);
   } else {
     __end_range = *__first;
     ++__first;
diff --git a/libcxx/include/__regex/regex_error.h b/libcxx/include/__regex/regex_error.h
index 925074ccc2485..ee7811cd8edbd 100644
--- a/libcxx/include/__regex/regex_error.h
+++ b/libcxx/include/__regex/regex_error.h
@@ -14,6 +14,8 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+#define _LIBCPP_REGEX_COMPLEXITY_FACTOR 4096
+
 namespace regex_constants {
 
 // syntax_option_type
diff --git a/libcxx/include/regex b/libcxx/include/regex
index 7cdde4ecd52a3..7f3449bd92500 100644
--- a/libcxx/include/regex
+++ b/libcxx/include/regex
@@ -824,6 +824,7 @@ typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;
 #    include <__memory/shared_ptr.h>
 #    include <__memory_resource/polymorphic_allocator.h>
 #    include <__regex/basic_parser.h>
+#    include <__regex/extended_parser.h>
 #    include <__regex/regex_error.h>
 #    include <__type_traits/is_swappable.h>
 #    include <__utility/move.h>
@@ -843,8 +844,6 @@ typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;
 _LIBCPP_PUSH_MACROS
 #    include <__undef_macros>
 
-#    define _LIBCPP_REGEX_COMPLEXITY_FACTOR 4096
-
 _LIBCPP_BEGIN_NAMESPACE_STD
 _LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS
 
@@ -1681,7 +1680,8 @@ public:
       : __owns_one_state<_CharT>(__s), __machine_(std::move(__machine)) {}
 
   _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __exec(__state<_CharT>& __state) const override {
-    auto __exec_state = __machine_.__get_exec_state(__state.__sub_matches_, __state.__current_, __state.__at_first_);
+    auto __exec_state =
+        __machine_.__get_exec_state(__state.__sub_matches_, __state.__current_, __state.__at_first_, __state.__flags_);
     if (!__exec_state.__execute(__state.__first_, __state.__last_)) {
       __state.__do_ = std::__state<_CharT>::__reject;
       __state.__node_ = nullptr;
@@ -2324,18 +2324,6 @@ private:
   template <class _ForwardIterator>
   _ForwardIterator __parse_DUP_COUNT(_ForwardIterator __first, _ForwardIterator __last, int& __c);
   template <class _ForwardIterator>
-  _ForwardIterator __parse_extended_reg_exp(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_ERE_branch(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_ERE_expression(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_one_char_or_coll_elem_ERE(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_ORD_CHAR_ERE(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_QUOTED_CHAR_ERE(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
   _ForwardIterator __parse_ecma_exp(_ForwardIterator __first, _ForwardIterator __last);
   template <class _ForwardIterator>
   _ForwardIterator __parse_alternative(_ForwardIterator __first, _ForwardIterator __last);
@@ -2357,8 +2345,6 @@ private:
   template <class _ForwardIterator>
   _ForwardIterator __parse_pattern_character(_ForwardIterator __first, _ForwardIterator __last);
   template <class _ForwardIterator>
-  _ForwardIterator __parse_egrep(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
   _ForwardIterator __parse_class_escape(
       _ForwardIterator __first,
       _ForwardIterator __last,
@@ -2607,177 +2593,25 @@ _ForwardIterator basic_regex<_CharT, _Traits>::__parse(_ForwardIterator __first,
     __marked_count_ = __parser.mark_count();
     return __last;
   }
-  case extended:
   case awk:
-    __first = __parse_extended_reg_exp(__first, __last);
-    break;
-  case egrep:
-    __first = __parse_egrep(__first, __last);
-    break;
+  case extended:
+  case egrep: {
+    __regex::__extended::__parser<_CharT, _Traits, _ForwardIterator> __parser(__first, __last, __traits_, flags());
+    if (auto __grammar = __get_grammar(__flags_); __grammar == extended || __grammar == awk)
+      __parser.__parse_extended();
+    else
+      __parser.__parse_egrep();
+    __end_->first() = new __interpreter_state<_CharT, _Traits>(__parser.__extract_interpreter(), __end_->first());
+    __end_          = static_cast<__owns_one_state<_CharT>*>(__end_->first());
+    __marked_count_ = __parser.mark_count();
+    return __last;
+  }
   default:
     std::__throw_regex_error<regex_constants::__re_err_grammar>();
   }
   return __first;
 }
 
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator
-basic_regex<_CharT, _Traits>::__parse_extended_reg_exp(_ForwardIterator __first, _ForwardIterator __last) {
-  __owns_one_state<_CharT>* __sa = __end_;
-  _ForwardIterator __temp        = __parse_ERE_branch(__first, __last);
-  if (__temp == __first)
-    std::__throw_regex_error<regex_constants::__re_err_empty>();
-  __first = __temp;
-  while (__first != __last && *__first == '|') {
-    __owns_one_state<_CharT>* __sb = __end_;
-    __temp                         = __parse_ERE_branch(++__first, __last);
-    if (__temp == __first)
-      std::__throw_regex_error<regex_constants::__re_err_empty>();
-    __push_alternation(__sa, __sb);
-    __first = __temp;
-  }
-  return __first;
-}
-
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator basic_regex<_CharT, _Traits>::__parse_ERE_branch(_ForwardIterator __first, _ForwardIterator __last) {
-  _ForwardIterator __temp = __parse_ERE_expression(__first, __last);
-  if (__temp == __first)
-    std::__throw_regex_error<regex_constants::__re_err_empty>();
-  do {
-    __first = __temp;
-    __temp  = __parse_ERE_expression(__first, __last);
-  } while (__temp != __first);
-  return __first;
-}
-
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator
-basic_regex<_CharT, _Traits>::__parse_ERE_expression(_ForwardIterator __first, _ForwardIterator __last) {
-  __owns_one_state<_CharT>* __e = __end_;
-  unsigned __mexp_begin         = __marked_count_;
-  _ForwardIterator __temp       = __parse_one_char_or_coll_elem_ERE(__first, __last);
-  if (__temp == __first && __temp != __last) {
-    switch (*__temp) {
-    case '^':
-      __push_l_anchor();
-      ++__temp;
-      break;
-    case '$':
-      __push_r_anchor();
-      ++__temp;
-      break;
-    case '(':
-      __push_begin_marked_subexpression();
-      unsigned __temp_count = __marked_count_;
-      ++__open_count_;
-      __temp = __parse_extended_reg_exp(++__temp, __last);
-      if (__temp == __last || *__temp != ')')
-        std::__throw_regex_error<regex_constants::error_paren>();
-      __push_end_marked_subexpression(__temp_count);
-      --__open_count_;
-      ++__temp;
-      break;
-    }
-  }
-  if (__temp != __first)
-    __temp = __parse_ERE_dupl_symbol(__temp, __last, __e, __mexp_begin + 1, __marked_count_ + 1);
-  __first = __temp;
-  return __first;
-}
-
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator
-basic_regex<_CharT, _Traits>::__parse_one_char_or_coll_elem_ERE(_ForwardIterator __first, _ForwardIterator __last) {
-  _ForwardIterator __temp = __parse_ORD_CHAR_ERE(__first, __last);
-  if (__temp == __first) {
-    __temp = __parse_QUOTED_CHAR_ERE(__first, __last);
-    if (__temp == __first) {
-      if (__temp != __last && *__temp == '.') {
-        __push_match_any();
-        ++__temp;
-      } else
-        __temp = __parse_bracket_expression(__first, __last);
-    }
-  }
-  __first = __temp;
-  return __first;
-}
-
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator basic_regex<_CharT, _Traits>::__parse_ORD_CHAR_ERE(_ForwardIterator __first, _ForwardIterator __last) {
-  if (__first != __last) {
-    switch (*__first) {
-    case '^':
-    case '.':
-    case '[':
-    case '$':
-    case '(':
-    case '|':
-    case '*':
-    case '+':
-    case '?':
-    case '{':
-    case '\\':
-      break;
-    case ')':
-      if (__open_count_ == 0) {
-        __push_char(*__first);
-        ++__first;
-      }
-      break;
-    default:
-      __push_char(*__first);
-      ++__first;
-      break;
-    }
-  }
-  return __first;
-}
-
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator
-basic_regex<_CharT, _Traits>::__parse_QUOTED_CHAR_ERE(_ForwardIterator __first, _ForwardIterator __last) {
-  if (__first != __last) {
-    _ForwardIterator __temp = std::next(__first);
-    if (__temp != __last) {
-      if (*__first == '\\') {
-        switch (*__temp) {
-        case '^':
-        case '.':
-        case '*':
-        case '[':
-        case '$':
-        case '\\':
-        case '(':
-        case ')':
-        case '|':
-        case '+':
-        case '?':
-        case '{':
-        case '}':
-          __push_char(*__temp);
-          __first = ++__temp;
-          break;
-        default:
-          if (__get_grammar(__flags_) == awk)
-            __first = __parse_awk_escape(++__first, __last);
-          else if (__test_back_ref(*__temp))
-            __first = ++__temp;
-          break;
-        }
-      }
-    }
-  }
-  return __first;
-}
-
 template <class _CharT, class _Traits>
 template <class _ForwardIterator>
 _ForwardIterator basic_regex<_CharT, _Traits>::__parse_ERE_dupl_symbol(
@@ -3590,33 +3424,6 @@ basic_regex<_CharT, _Traits>::__parse_pattern_character(_ForwardIterator __first
   return __first;
 }
 
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator basic_regex<_CharT, _Traits>::__parse_egrep(_ForwardIterator __first, _ForwardIterator __last) {
-  __owns_one_state<_CharT>* __sa = __end_;
-  _ForwardIterator __t1          = std::find(__first, __last, _CharT('\n'));
-  if (__t1 != __first)
-    __parse_extended_reg_exp(__first, __t1);
-  else
-    __push_empty();
-  __first = __t1;
-  if (__first != __last)
-    ++__first;
-  while (__first != __last) {
-    __t1                           = std::find(__first, __last, _CharT('\n'));
-    __owns_one_state<_CharT>* __sb = __end_;
-    if (__t1 != __first)
-      __parse_extended_reg_exp(__first, __t1);
-    else
-      __push_empty();
-    __push_alternation(__sa, __sb);
-    __first = __t1;
-    if (__first != __last)
-      ++__first;
-  }
-  return __first;
-}
-
 template <class _CharT, class _Traits>
 bool basic_regex<_CharT, _Traits>::__test_back_ref(_CharT __c) {
   unsigned __val = __traits_.value(__c, 10);
diff --git a/libcxx/test/std/re/re.grammar/excessive_brace_count.pass.cpp b/libcxx/test/std/re/re.grammar/excessive_brace_count.pass.cpp
index 0435ca29c94b0..473428e0930db 100644
--- a/libcxx/test/std/re/re.grammar/excessive_brace_count.pass.cpp
+++ b/libcxx/test/std/re/re.grammar/excessive_brace_count.pass.cpp
@@ -31,7 +31,8 @@ int main(int, char**) {
        {std::regex::ECMAScript, std::regex::extended, std::regex::egrep,
         std::regex::awk}) {
     try {
-      TEST_IGNORE_NODISCARD std::regex("a{100000000000000000}", op);
+      auto regex = "a{" + std::to_string(std::numeric_limits<size_t>::max()) + "1}";
+      TEST_IGNORE_NODISCARD std::regex(regex, op);
       assert(false);
     } catch (const std::regex_error &e) {
       assert(e.code() == std::regex_constants::error_badbrace);

>From 885f6d60edd0d6f05cc26286684e1f641c68cb05 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Tue, 24 Mar 2026 15:11:58 +0100
Subject: [PATCH 04/21] [libc++] ECMAScript parser

---
 libcxx/include/CMakeLists.txt                 |    1 +
 libcxx/include/__regex/basic_parser.h         |    8 +-
 libcxx/include/__regex/ecma_parser.h          |  446 +--
 libcxx/include/__regex/extended_parser.h      |   71 +-
 libcxx/include/__regex/interpreter.h          |  707 +++--
 libcxx/include/__regex/parser_common.h        |  223 +-
 libcxx/include/__regex/regex_error.h          |    3 +-
 libcxx/include/regex                          | 2550 +++--------------
 libcxx/src/regex.cpp                          |   14 +-
 .../re/re.alg/re.alg.search/basic.pass.cpp    |    2 +-
 10 files changed, 1310 insertions(+), 2715 deletions(-)

diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 24a4bb24d3c6f..70e7ee1aa503b 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -795,6 +795,7 @@ set(files
   __ranges/zip_transform_view.h
   __ranges/zip_view.h
   __regex/basic_parser.h
+  __regex/ecma_parser.h
   __regex/extended_parser.h
   __regex/interpreter.h
   __regex/parser_common.h
diff --git a/libcxx/include/__regex/basic_parser.h b/libcxx/include/__regex/basic_parser.h
index f744df1e40274..9b8caeb688f4a 100644
--- a/libcxx/include/__regex/basic_parser.h
+++ b/libcxx/include/__regex/basic_parser.h
@@ -173,7 +173,7 @@ class __parser {
 
     if (!__parse_escaped_character('}'))
       std::__throw_regex_error<regex_constants::error_brace>();
-    __machine_.__push_n_matcher(__expr_start, __min);
+    __machine_.__push_n_to_m_matcher(__expr_start, __min, __min);
     return true;
   }
 
@@ -220,8 +220,10 @@ class __parser {
   }
 
 public:
-  __parser(
-      _ForwardIterator __first, _ForwardIterator __last, _Traits __traits, regex_constants::syntax_option_type __flags)
+  __parser(_ForwardIterator __first,
+           _ForwardIterator __last,
+           const _Traits& __traits,
+           regex_constants::syntax_option_type __flags)
       : __machine_(__traits, true), __first_(__first), __last_(__last), __flags_(__flags) {}
 
   void __parse_basic() {
diff --git a/libcxx/include/__regex/ecma_parser.h b/libcxx/include/__regex/ecma_parser.h
index 06fcf75db68ca..6499349410a0e 100644
--- a/libcxx/include/__regex/ecma_parser.h
+++ b/libcxx/include/__regex/ecma_parser.h
@@ -10,229 +10,295 @@
 #define _LIBCPP___REGEX_ECMA_PARSER_H
 
 #include <__config>
+#include <__regex/interpreter.h>
 #include <__regex/regex_error.h>
-#include <__regex/state_machine.h>
-
-#define _LIBCPP_PARSER_FUNCTION [[clang::preserve_none]]
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace __regex::__ecma {
-template <class _ForwardIterator>
-_LIBCPP_PARSER_FUNCTION bool
-__parse_disjunction(__state_machine& __machine, _ForwardIterator& __first, _ForwardIterator __last);
-
-template <class _ForwardIterator>
-_LIBCPP_PARSER_FUNCTION bool
-__parse_assertion(__state_machine& __machine, _ForwardIterator& __first, _ForwardIterator __last) {
-  if (__first == __last)
-    return false;
-  switch (*__first) {
-  case '^': {
-    __machine.push_back(__state::__start_anchor);
-    ++__first;
-    return true;
-  }
-  case '$': {
-    __machine.push_back(__state::__end_anchor);
-    ++__first;
-    return true;
+
+template <class _CharT, class _Traits, class _ForwardIterator>
+class __parser {
+  __interpreter<_CharT, _Traits> __machine_;
+  _ForwardIterator __first_;
+  _ForwardIterator __last_;
+  regex_constants::syntax_option_type __flags_ = {};
+  uint8_t __marked_count_                      = 0;
+  size_t __open_count_                         = 0;
+
+  bool __parse_assertion() {
+    switch (*__first_) {
+    case '^':
+      if (__flags_ & regex_constants::multiline)
+        __machine_.__push_multiline_start_anchor();
+      else
+        __machine_.__push_start_anchor();
+      ++__first_;
+      return true;
+
+    case '$':
+      if (__flags_ & regex_constants::multiline)
+        __machine_.__push_multiline_end_anchor();
+      else
+        __machine_.__push_end_anchor();
+      ++__first_;
+      return true;
+
+    case '\\': {
+      auto __next = std::next(__first_);
+      if (__next == __last_)
+        return false;
+      switch (*__next) {
+      case 'b':
+        __machine_.__push_word_boundary();
+        break;
+
+      case 'B':
+        __machine_.__push_no_word_boundary();
+        break;
+
+      default:
+        return false;
+      }
+      __first_ = ++__next;
+      return true;
+    }
+
+    case '(': {
+      auto __next = std::next(__first_);
+      if (__next == __last_ || *__next != '?' || ++__next == __last_)
+        return false;
+      switch (*__next) {
+      case '=':
+      case '!': {
+        bool __is_positive    = *__next == '=';
+        auto __lookahead_info = __machine_.__start_lookahead();
+        auto __marked_count   = std::exchange(__marked_count_, 0);
+        __first_              = ++__next;
+        __parse_exp();
+        if (__first_ == __last_ || *__first_ != ')')
+          std::__throw_regex_error<regex_constants::error_paren>();
+        ++__first_;
+        __machine_.__push_lookahead(__is_positive, __lookahead_info, __marked_count, __marked_count_);
+        __marked_count_ += __marked_count;
+        return true;
+      }
+
+      default:
+        return false;
+      }
+    }
+
+    default:
+      return false;
+    }
   }
-  case '\\': {
-    auto __next = std::next(__first);
-    if (__next == __last)
+
+  bool __parse_pattern_character() {
+    switch (*__first_) {
+    case '^':
+    case '$':
+    case '\\':
+    case '.':
+    case '*':
+    case '+':
+    case '?':
+    case '(':
+    case ')':
+    case '[':
+    case ']':
+    case '{':
+    case '}':
+    case '|':
       return false;
-    if (auto __char = *__next; __char == 'b' || __char == 'B') {
-      __machine.push_back(__char == 'b' ? __state::__match_word_boundary : __state::__match_no_word_boundary);
-      __first = ++__next;
+    default:
+      __machine_.__push_char_matcher(*__first_++);
       return true;
     }
-    return false;
   }
-  case '(': {
-    auto __next = std::next(__first);
-    if (__next == __last || *++__next != '?' || __next == __last)
-      return false;
-    auto __char = *__next;
-    if (__char != '=' && __char != '!')
-      return false;
-    __machine.push_back(__char == '=' ? __state::__positive_lookahead_start : __state::__negative_lookahead_start);
-    if (!__ecma::__parse_disjunction(__machine, __first, __last))
+
+  bool __parse_decimal_escape() {
+    if (*__first_ == '0') {
+      __machine_.__push_char_matcher('\0');
+      ++__first_;
+      return true;
+    }
+
+    if (*__first_ < '1' || *__first_ > '9')
       return false;
-    __machine.push_back(__state::__lookahead_end);
-    if (__first == __last || *__first++ != ')')
-      std::__throw_regex_error<regex_constants::error_paren>();
-    return true;
-  }
-  }
-  return false;
-}
-
-template <class _ForwardIterator>
-_LIBCPP_PARSER_FUNCTION bool
-__parse_decimal_escape(__state_machine& __machine, _ForwardIterator& __first, _ForwardIterator __last) {
-  if (*__first == '0') {
-    __regex::__match_char(__machine, '\0');
-    ++__first;
-    return true;
-  }
 
-  if ('1' <= *__first && *__first <= '9') {
-    unsigned __value = *__first - '0';
-    for (++__first; __first != __last && '0' <= *__first && *__first <= '9'; ++__first) {
-      if (__value >= numeric_limits<unsigned>::max() / 10)
+    size_t __val = *__first_ - '0';
+
+    for (++__first_; __first_ != __last_ && *__first_ >= '0' && *__first_ <= '0'; ++__first_) {
+      if (__val >= numeric_limits<size_t>::max() / 10)
         std::__throw_regex_error<regex_constants::error_backref>();
-      __value = __value * 10 + *__first - '0';
+      __val = 10 * __val + *__first_ - '0';
     }
-    if (__value == 0)
+    if (__val == 0 || __val > __marked_count_)
       std::__throw_regex_error<regex_constants::error_backref>();
-    __machine.push_back(__state::__match_backref);
-    __regex::__write_uleb(__machine, __value);
+    __machine_.__push_backref_matcher(__val);
+    return true;
   }
-  return true;
-}
 
-template <class _ForwardIterator>
-_LIBCPP_PARSER_FUNCTION bool
-__parse_character_class_escape(__state_machine& __machine, _ForwardIterator& __first, _ForwardIterator __last) {
-  if (__first == __last)
-    return false;
-  switch (*__first) {
-  case 'd':
-    __machine.push_back(__state::__match_digits);
-    break;
-  case 'D':
-    __machine.push_back(__state::__match_no_digits);
-    break;
-  case 's':
-    __machine.push_back(__state::__match_whitespace);
-    break;
-  case 'S':
-    __machine.push_back(__state::__match_no_whitespace);
-    break;
-  case 'w':
-    __machine.push_back(__state::__match_word_character);
-    break;
-  case 'W':
-    __machine.push_back(__state::__match_no_word_character);
-    break;
-  default:
+  bool __parse_character_class_escape() {
+    __bracket_expr<_CharT, _Traits> __expr;
+    switch (*__first_) {
+    case 'd': {
+      ++__first_;
+      __expr.__mask_ = ctype_base::digit;
+      __machine_.__push_bracket_expr(false, __expr);
+      return true;
+    }
+
+    case 'D': {
+      ++__first_;
+      __expr.__mask_ = ctype_base::digit;
+      __machine_.__push_bracket_expr(true, __expr);
+      return true;
+    }
+
+    case 's': {
+      ++__first_;
+      __expr.__mask_ = ctype_base::space;
+      __machine_.__push_bracket_expr(false, __expr);
+      return true;
+    }
+
+    case 'S': {
+      ++__first_;
+      __expr.__mask_ = ctype_base::space;
+      __machine_.__push_bracket_expr(true, __expr);
+      return true;
+    }
+
+    case 'w': {
+      ++__first_;
+      __expr.__mask_ = ctype_base::alnum;
+      __machine_.__push_bracket_expr(false, __expr);
+      return true;
+    }
+
+    case 'W': {
+      ++__first_;
+      __expr.__mask_ = ctype_base::alnum;
+      __machine_.__push_bracket_expr(true, __expr);
+      return true;
+    }
+    }
     return false;
   }
-  ++__first;
-  return true;
-}
-
-template <class _ForwardIterator>
-_LIBCPP_PARSER_FUNCTION bool
-__parse_character_escape(__state_machine& __machine, _ForwardIterator& __first, _ForwardIterator __last) {
-  if (__first == __last)
-    return false;
-  switch (*__first) {
-  case 'f':
-    __regex::__match_char(__machine, '\f');
-    break;
-  case 'n':
-    __regex::__match_char(__machine, '\n');
-    break;
-  case 'r':
-    __regex::__match_char(__machine, '\r');
-    break;
-  case 't':
-    __regex::__match_char(__machine, '\t');
-    break;
-  case 'v':
-    __regex::__match_char(__machine, '\v');
-    break;
-
-  case 'c': {
-    auto __next = std::next(__first);
-    if (__next == __last)
-      std::__throw_regex_error<regex_constants::error_escape>();
-    if (('A' <= *__next && *__next <= 'Z') || ('a' <= *__next && *__next <= 'z')) {
-      __regex::__match_char(__machine, *__next % 32);
-      __first += ++__next;
-    } else {
-      std::__throw_regex_error<regex_constants::error_escape>();
+
+  bool __parse_atom() {
+    switch (*__first_) {
+    case '.':
+      __machine_.__push_any_except_newline_matcher();
+      ++__first_;
+      return true;
+
+    case '\\': {
+      ++__first_;
+      if (__first_ == __last_)
+        std::__throw_regex_error<regex_constants::error_escape>();
+
+      if (__parse_decimal_escape())
+        return true;
+
+      if (__parse_character_class_escape())
+        return true;
+
+      __machine_.__push_char_matcher(__regex::__parse_character_escape(__machine_, __first_, __last_));
+      return true;
     }
-  }
-  }
-  ++__first;
-  return true;
-}
-
-template <class _ForwardIterator>
-_LIBCPP_PARSER_FUNCTION bool
-__parse_atom_escape(__state_machine& __machine, _ForwardIterator& __first, _ForwardIterator __last) {
-  _LIBCPP_ASSERT_INTERNAL(*__first == '\\', "Parsing escape character without an escape start?");
-  auto __next = std::next(__first);
-  if (__next == __last)
-    std::__throw_regex_error<regex_constants::error_escape>();
-
-  if (__ecma::__parse_decimal_escape(__machine, __next, __last) ||
-      __ecma::__parse_character_class_escape(__machine, __next, __last)) {
-    __first = __next;
-    return true;
-  }
-  return false;
-}
 
-template <class _ForwardIterator>
-_LIBCPP_PARSER_FUNCTION bool
-__parse_atom(__state_machine& __machine, _ForwardIterator& __first, _ForwardIterator __last) {
-  if (__first == __last)
-    return false;
+    case '[':
+      return __parse_bracket_expression(__machine_, __first_, __last_, __flags_);
 
-  switch (*__first) {
-  case '.': {
-    __machine.push_back(__state::__match_any);
-    ++__first;
-    return true;
-  }
-  case '\\':
-    return __ecma::__parse_atom_escape(__machine, __first, __last);
+    case '(': {
+      ++__first_;
+      if (__first_ == __last_)
+        std::__throw_regex_error<regex_constants::error_paren>();
+      auto __next = std::next(__first_);
+
+      bool __explicit_unmarked = (__next != __last_ && *__first_ == '?' && *__next == ':');
+      bool __marked            = !(__flags_ & regex_constants::nosubs) && !__explicit_unmarked;
+      auto __subexpr_num       = __marked_count_;
+
+      if (__marked) {
+        ++__marked_count_;
+        __machine_.__push_subexpression_begin(__subexpr_num);
+      } else if (__explicit_unmarked) {
+        __first_ = ++__next;
+      }
+
+      ++__open_count_;
+      __parse_exp();
+      if (__first_ == __last_ || *__first_ != ')')
+        std::__throw_regex_error<regex_constants::error_paren>();
+      --__open_count_;
+      ++__first_;
+      if (__marked)
+        __machine_.__push_subexpression_end(__subexpr_num);
+      return true;
+    }
+
+    case '*':
+    case '+':
+    case '?':
+    case '{':
+      std::__throw_regex_error<regex_constants::error_badrepeat>();
+
+    default:
+      return __parse_pattern_character();
+    }
   }
 
-  return false;
-}
+  bool __parse_term() {
+    if (__first_ == __last_)
+      return false;
 
-template <class _ForwardIterator>
-_LIBCPP_PARSER_FUNCTION bool
-__parse_term(__state_machine& __machine, _ForwardIterator& __first, _ForwardIterator __last) {
-  return __ecma::__parse_assertion(__machine, __first, __last) || __ecma::__parse_atom(__machine, __first, __last);
-}
+    if (__parse_assertion())
+      return true;
 
-template <class _ForwardIterator>
-_LIBCPP_PARSER_FUNCTION void
-__parse_alternative(__state_machine& __machine, _ForwardIterator& __first, _ForwardIterator __last) {
-  while (true) {
-    __ecma::__parse_term(__machine, __first, __last);
+    size_t __expr_start = __machine_.size();
+
+    if (!__parse_atom())
+      return false;
+    __parse_dupl_symbol(__machine_, __first_, __last_, __expr_start, true);
+    return true;
   }
-}
 
-template <class _ForwardIterator>
-_LIBCPP_PARSER_FUNCTION bool
-__parse_disjunction(__state_machine& __machine, _ForwardIterator& __first, _ForwardIterator __last) {
-  while (__first != __last) {
-    __ecma::__parse_alternative(__machine, __first, __last);
+  void __parse_alternative() {
+    while (__parse_term())
+      ;
   }
-  return true;
-}
 
-template <class _ForwardIterator>
-_LIBCPP_PARSER_FUNCTION void
-__parse_pattern(__state_machine& __machine, _ForwardIterator& __first, _ForwardIterator __last) {
-  __ecma::__parse_disjunction(__machine, __first, __last);
-}
+  void __parse_exp() {
+    auto __expr1_start = __machine_.size();
+    __parse_alternative();
 
-template <class _ForwardIterator>
-__state_machine __parse(_ForwardIterator __first, _ForwardIterator __last) {
-  __state_machine __machine;
+    while (__first_ != __last_ && *__first_ == '|') {
+      ++__first_;
+      auto __expr2_start = __machine_.size();
+      __parse_alternative();
+      __machine_.__push_alternative(__expr1_start, __expr2_start);
+    }
+  }
 
-  __ecma::__parse_pattern(__machine, __first, __last);
+public:
+  __parser(
+      _ForwardIterator __first, _ForwardIterator __last, _Traits __traits, regex_constants::syntax_option_type __flags)
+      : __machine_(__traits, false), __first_(__first), __last_(__last), __flags_(__flags) {}
+
+  void __parse_ecma() {
+    __parse_exp();
+    if (__first_ != __last_)
+      std::__throw_regex_error<regex_constants::__re_err_parse>();
+    __machine_.__push_end_state();
+  }
 
-  return __machine;
-}
+  __interpreter<_CharT, _Traits> __extract_interpreter() { return std::move(__machine_); }
+  size_t mark_count() const { return __marked_count_; }
+};
 } // namespace __regex::__ecma
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__regex/extended_parser.h b/libcxx/include/__regex/extended_parser.h
index 92906880eec44..76e2fa411a422 100644
--- a/libcxx/include/__regex/extended_parser.h
+++ b/libcxx/include/__regex/extended_parser.h
@@ -108,75 +108,6 @@ class __parser {
     return __regex::__parse_bracket_expression(__machine_, __first_, __last_, __flags_);
   }
 
-  bool __parse_dupl_symbol(size_t __expr_start) {
-    if (__first_ == __last_)
-      return false;
-    switch (*__first_) {
-    case '*': {
-      ++__first_;
-      __machine_.__push_n_to_m_matcher(__expr_start, 0, numeric_limits<size_t>::max());
-    } break;
-
-    case '+': {
-      ++__first_;
-      __machine_.__push_n_to_m_matcher(__expr_start, 1, numeric_limits<size_t>::max());
-    } break;
-
-    case '?': {
-      ++__first_;
-      __machine_.__push_n_to_m_matcher(__expr_start, 0, 1);
-    } break;
-
-    case '{': {
-      ++__first_;
-      size_t __min;
-      if (auto __res = __regex::__parse_dup_count(__first_, __last_)) {
-        __min = __res.__num_;
-      } else {
-        std::__throw_regex_error<regex_constants::error_badbrace>();
-      }
-      if (__first_ == __last_)
-        std::__throw_regex_error<regex_constants::error_brace>();
-
-      switch (*__first_) {
-      case '}': {
-        ++__first_;
-        __machine_.__push_n_matcher(__expr_start, __min);
-        return true;
-      } break;
-
-      case ',': {
-        ++__first_;
-        if (__first_ == __last_)
-          std::__throw_regex_error<regex_constants::error_badbrace>();
-        if (*__first_ == '}') {
-          ++__first_;
-          __machine_.__push_n_to_m_matcher(__expr_start, __min, numeric_limits<size_t>::max());
-          return true;
-        }
-
-        size_t __max;
-        if (auto __res = __regex::__parse_dup_count(__first_, __last_)) {
-          __max = __res.__num_;
-        } else {
-          std::__throw_regex_error<regex_constants::error_brace>();
-        }
-        if (__first_ == __last_ || *__first_ != '}')
-          std::__throw_regex_error<regex_constants::error_brace>();
-        ++__first_;
-        if (__max < __min)
-          std::__throw_regex_error<regex_constants::error_badbrace>();
-        __machine_.__push_n_to_m_matcher(__expr_start, __min, __max);
-        return true;
-      } break;
-      default:
-        std::__throw_regex_error<regex_constants::error_badbrace>();
-      }
-    } break;
-    }
-    return false;
-  }
-
   bool __parse_expression() {
     if (__first_ == __last_)
       return false;
@@ -210,7 +141,7 @@ class __parser {
         return false;
       }
     }
-    __parse_dupl_symbol(__expr_start);
+    __regex::__parse_dupl_symbol(__machine_, __first_, __last_, __expr_start);
     return true;
   }
 
diff --git a/libcxx/include/__regex/interpreter.h b/libcxx/include/__regex/interpreter.h
index 4bcff9d7c7f79..fc7aefa7db8a4 100644
--- a/libcxx/include/__regex/interpreter.h
+++ b/libcxx/include/__regex/interpreter.h
@@ -16,8 +16,7 @@
 #include <__algorithm/transform.h>
 #include <__config>
 #include <__iterator/back_insert_iterator.h>
-#include <__ranges/filter_view.h>
-#include <__ranges/views.h>
+#include <__locale>
 #include <__regex/regex_error.h>
 #include <__utility/pair.h>
 #include <__utility/to_underlying.h>
@@ -75,8 +74,11 @@ namespace __regex {
 enum class __state : uint8_t {
   __start_anchor,
   __end_anchor,
+  __multiline_start_anchor,
+  __multiline_end_anchor,
   __branch_alternative,
   __match_any,
+  __match_any_except_newline,
   __match_char,
   __match_icase_char,
   __match_backref,
@@ -86,8 +88,12 @@ enum class __state : uint8_t {
   __marked_subexpression_begin,
   __marked_subexpression_end,
   __branch_n_to_m_matcher,
+  __branch_nongreedy_n_to_m_matcher,
   __match_n_to_m_times,
-  __match_n_times,
+  __match_word_boundary,
+  __match_no_word_boundary,
+  __positive_lookahead,
+  __negative_lookahead,
   __relative_jump,
   __end_state,
 };
@@ -111,10 +117,12 @@ static_assert(sizeof(__interpreter_info<char>) == 1);
 template <class _CharT, class _Traits>
 struct __bracket_expr {
   vector<_CharT> __chars_;
+  vector<_CharT> __neg_chars_;
   vector<_CharT> __digraphs_;
   vector<_CharT> __ranges_;
   vector<typename _Traits::string_type> __equivalences_;
-  typename _Traits::char_class_type __mask_ = 0;
+  typename _Traits::char_class_type __mask_     = 0;
+  typename _Traits::char_class_type __neg_mask_ = 0;
 };
 
 template <class _CharT, class _Traits>
@@ -124,7 +132,8 @@ class __interpreter {
   _Traits __traits_;
   bool __find_longest_;
 
-  static size_t __read_uleb(const vector<__interpreter_info<_CharT> >& __machine, size_t& __current_pos) {
+  static pair<size_t, size_t>
+  __read_uleb_impl(_LIBCPP_NOESCAPE const __interpreter_info<_CharT>* __machine, size_t __current_pos) {
     size_t __result = 0;
     size_t __shift  = 0;
 
@@ -134,261 +143,428 @@ class __interpreter {
       __result |= (__byte & 0x7f) << __shift;
       __shift += 7;
     } while (__byte & 0x80);
-    return __result;
+    return {__result, __current_pos};
+  }
+
+  static size_t __read_uleb(const __interpreter_info<_CharT>* __machine, size_t& __current_pos) {
+    auto __val = __machine[__current_pos++].__int_;
+    if (__val & 0x80) {
+      auto __res    = __read_uleb_impl(__machine, __current_pos);
+      __current_pos = __res.second;
+      return __res.first;
+    }
+    return __val;
   }
 
   struct __global_execution_state {
     struct __local_execution_state;
 
-    bool __at_first_;
-    stack<__local_execution_state> __states_;
+    vector<__local_execution_state> __states_;
     const __interpreter& __machine_;
     regex_constants::match_flag_type __flags_;
-    size_t __counter_ = 0;
 
     struct __local_execution_state {
       const _CharT* __current_;
       vector<sub_match<const _CharT*> > __sub_matches_;
       size_t __current_pos_;
-      vector<size_t> __loop_values_;
-      vector<const _CharT*> __loop_starts_;
+      unique_ptr<size_t[]> __loop_values_;
+      unique_ptr<const _CharT*[]> __loop_starts_;
+
+      void __copy_to(const _CharT* const __current,
+                     vector<__local_execution_state>& __vec,
+                     __global_execution_state& __gstate) {
+        auto __loop_value_count = __gstate.__machine_.__initial_loop_values_.size();
+        auto __loop_values_copy = std::make_unique_for_overwrite<size_t[]>(__loop_value_count);
+        std::copy_n(__loop_values_.get(), __loop_value_count, __loop_values_copy.get());
+        auto __loop_starts_copy = std::make_unique_for_overwrite<const _CharT*[]>(__loop_value_count);
+        std::copy_n(__loop_starts_.get(), __loop_value_count, __loop_starts_copy.get());
+        __vec.emplace_back(
+            __current, __sub_matches_, __current_pos_, std::move(__loop_values_copy), std::move(__loop_starts_copy));
+      }
+
+      static bool __is_word_boundary(const _CharT* __first,
+                                     const _CharT* __last,
+                                     const _CharT* const __current,
+                                     __global_execution_state& __gstate) {
+        auto __is_word_char = [&](char __c) {
+          return __c == '_' || __gstate.__machine_.__traits_.isctype(__c, ctype_base::alnum);
+        };
+
+        if (__first == __last)
+          return false;
+
+        if (__current == __last) {
+          return !(__gstate.__flags_ & regex_constants::match_not_eow) && __is_word_char(__current[-1]);
+        }
+
+        if (__current == __first && !(__gstate.__flags_ & regex_constants::match_prev_avail)) {
+          return !(__gstate.__flags_ & regex_constants::match_not_bow) && __is_word_char(__current[0]);
+        }
+
+        return __is_word_char(__current[-1]) != __is_word_char(__current[0]);
+      }
+
+      struct __charlist_result {
+        bool __matched;
+        bool __matched_digraph;
+        size_t __new_pos;
+      };
+
+      static __charlist_result __exec_match_character_list(
+          const __interpreter_info<_CharT>* const __code,
+          const _CharT* const __last,
+          const _CharT* const __current,
+          const __global_execution_state& __gstate,
+          size_t __current_pos) {
+        static constexpr auto __buffer_size =
+            std::max(sizeof(typename _Traits::char_class_type) / sizeof(_CharT), size_t(1));
+        _CharT __buffer[__buffer_size];
+        for (size_t __i = 0; __i != __buffer_size; ++__i)
+          __buffer[__i] = __code[__current_pos++].__char_;
+        typename _Traits::char_class_type __mask;
+        __builtin_memcpy(&__mask, __buffer, sizeof(typename _Traits::char_class_type));
+
+        for (size_t __i = 0; __i != __buffer_size; ++__i)
+          __buffer[__i] = __code[__current_pos++].__char_;
+        typename _Traits::char_class_type __neg_mask;
+        __builtin_memcpy(&__neg_mask, __buffer, sizeof(typename _Traits::char_class_type));
+
+        auto __chars       = __read_uleb(__code, __current_pos);
+        auto __digraphs    = __read_uleb(__code, __current_pos) * 2;
+        auto __ranges      = __read_uleb(__code, __current_pos) * 4;
+        auto __neg_chars   = __read_uleb(__code, __current_pos);
+        auto __equiv_count = __read_uleb(__code, __current_pos);
+        auto __equiv_size  = __read_uleb(__code, __current_pos);
+
+        bool __found = false;
+
+        for (size_t __i = 0; __i != __chars; ++__i) {
+          if (__code[__current_pos + __i].__char_ == *__current) {
+            __found = true;
+            break;
+          }
+        }
+
+        __current_pos += __chars;
 
-      bool __execute(const _CharT* __first, const _CharT* __last, __global_execution_state& __gstate) {
+        if (__found) {
+          __current_pos += __digraphs + __ranges + __neg_chars + __equiv_size;
+          return {true, false, __current_pos};
+        }
+
+        if (__current + 1 != __last) {
+          _CharT __vals[2] = {__current[0], __current[1]};
+
+          for (size_t __i = 0; __i != __digraphs; __i += 2) {
+            if (__code[__current_pos + __i].__char_ == __vals[0] &&
+                __code[__current_pos + __i + 1].__char_ == __vals[1]) {
+              __found = true;
+              break;
+            }
+          }
+        }
+
+        __current_pos += __digraphs;
+
+        if (__found) {
+          __current_pos += __ranges + __neg_chars + __equiv_size;
+          return {true, true, __current_pos};
+        }
+
+        auto __cmp = __gstate.__machine_.__traits_.transform(__current, __current + 1);
+        for (size_t __i = 0; __i != __ranges; __i += 4) {
+          _CharT __range_info[4];
+          std::transform(__gstate.__machine_.__machine_.begin() + __current_pos + __i,
+                         __gstate.__machine_.__machine_.begin() + __current_pos + __i + 4,
+                         __range_info,
+                         [](__interpreter_info<_CharT> __val) { return __val.__char_; });
+          basic_string_view<_CharT> __min(__range_info, __range_info[1] == '\0' ? 1 : 2);
+          basic_string_view<_CharT> __max(__range_info + 2, __range_info[3] == '\0' ? 1 : 2);
+          if (__min <= __cmp && __cmp <= __max) {
+            __found = true;
+            break;
+          }
+        }
+
+        __current_pos += __ranges;
+
+        if (__found) {
+          __current_pos += __neg_chars + __equiv_size;
+          return {true, false, __current_pos};
+        }
+
+        if (__gstate.__machine_.__traits_.isctype(*__current, __mask)) {
+          return {true, false, __current_pos};
+        }
+
+        bool __none_match = true;
+        for (size_t __i = 0; __i != __neg_chars; ++__i) {
+          if (__code[__current_pos + __i].__char_ == *__current) {
+            __none_match = false;
+            break;
+          }
+        }
+
+        __current_pos += __neg_chars;
+
+        if (__none_match && __neg_mask != 0 && !__gstate.__machine_.__traits_.isctype(*__current, __neg_mask)) {
+          return {true, false, __current_pos};
+        }
+
+        if (__found) {
+          __current_pos += __equiv_size;
+          return {true, false, __current_pos};
+        }
+
+        auto __after_pos   = __current_pos + __equiv_size;
+        auto __transformed = __gstate.__machine_.__traits_.transform_primary(__current, __current + 1);
+        for (size_t __i = 0; __i != __equiv_count; ++__i) {
+          auto __size = __read_uleb(__code, __current_pos);
+          basic_string<_CharT> __str;
+          std::transform(__code + __current_pos,
+                         __code + __current_pos + __size,
+                         std::back_inserter(__str),
+                         [](__interpreter_info<_CharT> __v) { return __v.__char_; });
+          __current_pos += __size;
+          if (__transformed == __str) {
+            __found = true;
+            break;
+          }
+        }
+
+        __current_pos = __after_pos;
+
+        return {__found, false, __current_pos};
+      }
+
+      pair<bool, size_t> __exec_lookahead(
+          const _CharT* const __first,
+          const _CharT* const __last,
+          const __global_execution_state& __gstate,
+          const __interpreter_info<_CharT>* const __code,
+          size_t __current_pos,
+          bool __is_positive) {
+        auto __jump_offset    = __read_uleb(__code, __current_pos);
+        auto __submatch_count = __read_uleb(__code, __current_pos);
+        auto __submatch_base  = __read_uleb(__code, __current_pos);
+        auto __loop_count     = __read_uleb(__code, __current_pos);
+
+        unique_ptr<size_t[]> __initial_loop_values = std::make_unique_for_overwrite<size_t[]>(__loop_count);
+
+        for (size_t __i = 0; __i != __loop_count; ++__i)
+          __initial_loop_values[__i] = __read_uleb(__code, __current_pos);
+
+        __global_execution_state __gexec_state{{}, __gstate.__machine_, __gstate.__flags_};
+        __gexec_state.__flags_ &= ~regex_constants::__full_match;
+        auto& __s = __gexec_state.__states_.emplace_back();
+        if (__loop_count > 0)
+          __s.__sub_matches_.resize(__submatch_count);
+        __s.__current_     = __current_;
+        __s.__loop_values_ = std::move(__initial_loop_values);
+        __s.__loop_starts_ = std::make_unique<const _CharT*[]>(__loop_count);
+        __s.__current_pos_ = __current_pos;
+        if (__gexec_state.__execute(__first, __last) != __is_positive)
+          return {false, __current_pos};
+        if (__is_positive) {
+          auto& __matched_state = __gexec_state.__states_.back();
+          std::copy(__matched_state.__sub_matches_.begin(),
+                    __matched_state.__sub_matches_.end(),
+                    __sub_matches_.begin() + __submatch_base);
+        }
+        __current_pos += __jump_offset;
+        return {true, __current_pos};
+      }
+
+      size_t __exec_branch_n_to_m_matcher(
+          __global_execution_state& __gstate,
+          const __interpreter_info<_CharT>* const __code,
+          const _CharT* const __current,
+          size_t __current_pos,
+          bool __is_greedy) {
+        auto __loop_index     = __read_uleb(__code, __current_pos);
+        auto __again_pos_base = __current_pos;
+        auto __again_pos      = __again_pos_base - __read_uleb(__code, __current_pos);
+        if (__loop_values_[__loop_index] > 0) {
+          --__loop_values_[__loop_index];
+          __current_pos = __again_pos;
+          return __current_pos;
+        }
+        if (__loop_starts_[__loop_index] != __current && __loop_values_[__loop_index + 1] > 0) {
+          --__loop_values_[__loop_index + 1];
+          __loop_starts_[__loop_index] = __current;
+          __copy_to(__current, __gstate.__states_, __gstate);
+          if (!__is_greedy) {
+            __gstate.__states_.back().__current_pos_ = __again_pos;
+          } else {
+            __gstate.__states_.back().__current_pos_ = __current_pos;
+            __current_pos                            = __again_pos;
+          }
+          return __current_pos;
+        }
+        return __current_pos;
+      }
+
+      pair<bool, size_t> __execute(const _CharT* __first, const _CharT* __last, __global_execution_state& __gstate) {
+        const __interpreter_info<_CharT>* const __code = __gstate.__machine().data();
+        auto __current_pos                             = __current_pos_;
+        auto __counter                                 = 0;
+        auto __current                                 = __current_;
+        auto __commit_current                          = std::__make_scope_guard([&] { __current_ = __current; });
         while (true) {
-          ++__gstate.__counter_;
-          auto __st = __gstate.__machine()[__current_pos_++].__state_;
+          ++__counter;
+          auto __st = __code[__current_pos++].__state_;
           switch (__st) {
             using enum __state;
 
+          case __multiline_start_anchor:
+            if (!(__gstate.__flags_ & regex_constants::__at_first) && (__current[-1] == '\n' || __current[-1] == '\r'))
+              break;
+            [[__fallthrough__]];
           case __start_anchor: {
-            if (!__gstate.__at_first_ || __first != __current_)
-              return false;
+            if (__gstate.__flags_ & regex_constants::match_not_bol ||
+                !(__gstate.__flags_ & regex_constants::__at_first) || __first != __current)
+              return {false, __counter};
           } break;
 
+          case __multiline_end_anchor:
+            if (__current[0] == '\r' || __current[0] == '\n')
+              break;
+            [[__fallthrough__]];
           case __end_anchor: {
-            if (__current_ != __last)
-              return false;
+            if (__gstate.__flags_ & regex_constants::match_not_eol || __current != __last)
+              return {false, __counter};
           } break;
 
           case __end_state: {
-            return !(__gstate.__flags_ & regex_constants::match_flag_type::__full_match) || __current_ == __last;
+            return {(!(__gstate.__flags_ & regex_constants::match_not_null) || __current != __first) &&
+                        (!(__gstate.__flags_ & regex_constants::match_flag_type::__full_match) || __current == __last),
+                    __counter};
           }
 
           case __match_any: {
-            if (__current_ == __last)
-              return false;
-            ++__current_;
+            if (__current == __last)
+              return {false, __counter};
+            ++__current;
+          } break;
+
+          case __match_any_except_newline: {
+            if (__current == __last || *__current == '\r' || *__current == '\n')
+              return {false, __counter};
+            if constexpr (__is_same(_CharT, wchar_t)) {
+              if (*__current == 0x2028 || *__current == 0x2029)
+                return {false, __counter};
+            }
+            ++__current;
           } break;
 
           case __match_char: {
-            if (__current_ == __last || *__current_ != __gstate.__machine()[__current_pos_++].__char_)
-              return false;
-            ++__current_;
+            if (__current == __last || *__current != __code[__current_pos++].__char_)
+              return {false, __counter};
+            ++__current;
           } break;
 
           case __match_icase_char: {
-            if (__current_ == __last || __gstate.__machine_.__traits_.translate_nocase(*__current_) !=
-                                            __gstate.__machine()[__current_pos_++].__char_)
-              return false;
-            ++__current_;
+            if (__current == __last ||
+                __gstate.__machine_.__traits_.translate_nocase(*__current) != __code[__current_pos++].__char_)
+              return {false, __counter};
+            ++__current;
           } break;
 
           case __branch_alternative: {
-            auto __offset = __read_uleb(__gstate.__machine(), __current_pos_);
-            __gstate.__states_.push(*this);
-            __current_pos_ += __offset;
+            auto __offset = __read_uleb(__code, __current_pos);
+            __copy_to(__current, __gstate.__states_, __gstate);
+            __gstate.__states_.back().__current_pos_ = __current_pos + __offset;
             break;
           }
 
           case __relative_jump: {
-            __current_pos_ += __read_uleb(__gstate.__machine(), __current_pos_);
+            __current_pos += __read_uleb(__code, __current_pos);
             break;
           }
 
-          case __branch_n_to_m_matcher: {
-            auto __loop_index     = __read_uleb(__gstate.__machine(), __current_pos_);
-            auto __again_pos_base = __current_pos_;
-            auto __again_pos      = __again_pos_base - __read_uleb(__gstate.__machine(), __current_pos_);
-            if (__loop_values_[__loop_index] > 0) {
-              --__loop_values_[__loop_index];
-              __current_pos_ = __again_pos;
-              break;
-            }
-            if (__loop_starts_[__loop_index] != __current_ && __loop_values_[__loop_index + 1] > 0) {
-              --__loop_values_[__loop_index + 1];
-              __loop_starts_[__loop_index] = __current_;
-              __gstate.__states_.push(*this);
-              __current_pos_ = __again_pos;
-              break;
-            }
-            break;
-          }
+          case __branch_n_to_m_matcher:
+          case __branch_nongreedy_n_to_m_matcher: {
+            __current_pos = __exec_branch_n_to_m_matcher(
+                __gstate, __code, __current, __current_pos, __st != __branch_nongreedy_n_to_m_matcher);
+          } break;
 
           case __match_backref: {
-            sub_match<const _CharT*>& __match = __sub_matches_[__read_uleb(__gstate.__machine(), __current_pos_) - 1];
+            sub_match<const _CharT*>& __match = __sub_matches_[__read_uleb(__code, __current_pos) - 1];
             if (!__match.matched)
-              return false;
+              return {false, __counter};
 
             auto __len = __match.second - __match.first;
-            if (__last - __current_ < __len || !std::equal(__match.first, __match.second, __current_))
-              return false;
+            if (__last - __current < __len || !std::equal(__match.first, __match.second, __current))
+              return {false, __counter};
 
-            __current_ += __len;
+            __current += __len;
           } break;
 
           case __match_icase_backref: {
-            sub_match<const _CharT*>& __match = __sub_matches_[__read_uleb(__gstate.__machine(), __current_pos_) - 1];
+            sub_match<const _CharT*>& __match = __sub_matches_[__read_uleb(__code, __current_pos) - 1];
             if (!__match.matched)
-              return false;
+              return {false, __counter};
 
             auto __len = __match.second - __match.first;
-            if (__last - __current_ < __len)
-              return false;
+            if (__last - __current < __len)
+              return {false, __counter};
 
             for (ptrdiff_t __i = 0; __i != __len; ++__i) {
               if (__gstate.__machine_.__traits_.translate_nocase(__match.first[__i]) !=
-                  __gstate.__machine_.__traits_.translate_nocase(__current_[__i]))
-                return false;
+                  __gstate.__machine_.__traits_.translate_nocase(__current[__i]))
+                return {false, __counter};
             }
 
-            __current_ += __len;
+            __current += __len;
           } break;
 
           case __match_character_list:
           case __match_no_character_list: {
-            if (__current_ == __last)
-              return false;
-            static const auto __buffer_size =
-                std::max(sizeof(typename _Traits::char_class_type) / sizeof(_CharT), size_t(1));
-            _CharT __buffer[__buffer_size];
-            for (size_t __i = 0; __i != __buffer_size; ++__i)
-              __buffer[__i] = __gstate.__machine()[__current_pos_++].__char_;
-            typename _Traits::char_class_type __mask;
-            __builtin_memcpy(&__mask, __buffer, sizeof(typename _Traits::char_class_type));
-
-            auto __chars       = __read_uleb(__gstate.__machine(), __current_pos_);
-            auto __digraphs    = __read_uleb(__gstate.__machine(), __current_pos_) * 2;
-            auto __ranges      = __read_uleb(__gstate.__machine(), __current_pos_) * 4;
-            auto __equiv_count = __read_uleb(__gstate.__machine(), __current_pos_);
-            auto __equiv_size  = __read_uleb(__gstate.__machine(), __current_pos_);
-
-            bool __found = false;
-
-            for (size_t __i = 0; __i != __chars; ++__i) {
-              if (__gstate.__machine()[__current_pos_ + __i].__char_ == *__current_) {
-                __found = true;
-                break;
-              }
-            }
-
-            __current_pos_ += __chars;
-
-            if (__found) {
-              __current_pos_ += __digraphs + __ranges + __equiv_size;
-              ++__current_;
-              if (__st == __match_no_character_list)
-                return false;
-              break;
-            }
-
-            if (__current_ + 1 != __last) {
-              _CharT __vals[2] = {__current_[0], __current_[1]};
-
-              for (size_t __i = 0; __i != __digraphs; __i += 2) {
-                if (__gstate.__machine()[__current_pos_ + __i].__char_ == __vals[0] &&
-                    __gstate.__machine()[__current_pos_ + __i + 1].__char_ == __vals[1]) {
-                  __found = true;
-                  break;
-                }
-              }
-            }
-
-            __current_pos_ += __digraphs;
-
-            if (__found) {
-              __current_pos_ += __ranges + __equiv_size;
-              __current_ += 2;
-              if (__st == __match_no_character_list)
-                return false;
-              break;
-            }
-
-            auto __cmp = __gstate.__machine_.__traits_.transform(__current_, __current_ + 1);
-            for (size_t __i = 0; __i != __ranges; __i += 4) {
-              _CharT __range_info[4];
-              std::transform(__gstate.__machine_.__machine_.begin() + __current_pos_ + __i,
-                             __gstate.__machine_.__machine_.begin() + __current_pos_ + __i + 4,
-                             __range_info,
-                             [](__interpreter_info<_CharT> __val) { return __val.__char_; });
-              basic_string_view<_CharT> __min(__range_info, __range_info[1] == '\0' ? 1 : 2);
-              basic_string_view<_CharT> __max(__range_info + 2, __range_info[3] == '\0' ? 1 : 2);
-              if (__min <= __cmp && __cmp <= __max) {
-                __found = true;
-                __current_ += __cmp.size();
-                break;
-              }
-            }
-
-            __current_pos_ += __ranges;
-
-            if (__found) {
-              __current_pos_ += __equiv_size;
-              if (__st == __match_no_character_list)
-                return false;
-              break;
-            }
-
-            if (__gstate.__machine_.__traits_.isctype(*__current_, __mask)) {
-              ++__current_;
-              if (__st == __match_no_character_list)
-                return false;
-              break;
-            }
-
-            auto __after_pos   = __current_pos_ + __equiv_size;
-            auto __transformed = __gstate.__machine_.__traits_.transform_primary(__current_, __current_ + 1);
-            for (size_t __i = 0; __i != __equiv_count; ++__i) {
-              auto __size = __read_uleb(__gstate.__machine(), __current_pos_);
-              basic_string<_CharT> __str;
-              std::transform(__gstate.__machine().begin() + __current_pos_,
-                             __gstate.__machine().begin() + __current_pos_ + __size,
-                             std::back_inserter(__str),
-                             [](__interpreter_info<_CharT> __v) { return __v.__char_; });
-              __current_pos_ += __size;
-              if (__transformed == __str) {
-                __found = true;
-                break;
-              }
-            }
-
-            __current_pos_ = __after_pos;
-
-            if (__found) {
-              ++__current_;
-              if (__st == __match_no_character_list)
-                return false;
-              break;
-            }
-
-            if (__st == __match_no_character_list) {
-              ++__current_;
-              break;
+            if (__current == __last)
+              return {false, __counter};
+            if (auto [__success, __digraph, __new_pos] =
+                    __exec_match_character_list(__code, __last, __current, __gstate, __current_pos);
+                __success != (__st == __match_character_list))
+              return {false, __counter};
+            else {
+              __current_pos = __new_pos;
+              ++__current; // Swallow the matched character
+              if (__digraph)
+                ++__current; // Swallow the second character of a digraph
             }
-            return false;
-
           } break;
 
           case __marked_subexpression_begin: {
-            auto __match                  = __read_uleb(__gstate.__machine(), __current_pos_);
-            __sub_matches_[__match].first = __current_;
+            auto __match                  = __read_uleb(__code, __current_pos);
+            __sub_matches_[__match].first = __current;
           } break;
 
           case __marked_subexpression_end: {
-            auto __match                    = __read_uleb(__gstate.__machine(), __current_pos_);
-            __sub_matches_[__match].second  = __current_;
+            auto __match                    = __read_uleb(__code, __current_pos);
+            __sub_matches_[__match].second  = __current;
             __sub_matches_[__match].matched = true;
           } break;
 
+          case __match_word_boundary: {
+            if (!__is_word_boundary(__first, __last, __current, __gstate))
+              return {false, __counter};
+          } break;
+
+          case __match_no_word_boundary: {
+            if (__is_word_boundary(__first, __last, __current, __gstate))
+              return {false, __counter};
+          } break;
+
+          case __negative_lookahead:
+          case __positive_lookahead: {
+            if (auto __result =
+                    __exec_lookahead(__first, __last, __gstate, __code, __current_pos, (__st == __positive_lookahead));
+                __result.first)
+              __current_pos = __result.second;
+            else
+              return {false, __counter};
+          } break;
+
           default:
             std::__libcpp_unreachable();
           }
@@ -403,32 +579,38 @@ class __interpreter {
       if (__machine_.__find_longest_) {
         __local_execution_state __best_state;
         bool __found_match = false;
+        size_t __gcounter  = 0;
         while (!__states_.empty()) {
-          if (__counter_ / _LIBCPP_REGEX_COMPLEXITY_FACTOR >= __length)
+          if (__gcounter / _LIBCPP_REGEX_COMPLEXITY_FACTOR >= __length)
             std::__throw_regex_error<regex_constants::error_complexity>();
-          auto __state = std::move(__states_.top());
-          __states_.pop();
-          if (__state.__execute(__first, __last, *this)) {
+          auto __state = std::move(__states_.back());
+          __states_.pop_back();
+          auto [__success, __counter] = __state.__execute(__first, __last, *this);
+          __gcounter += __counter;
+          if (__success) {
             if (!__found_match || __best_state.__current_ < __state.__current_)
               __best_state = std::move(__state);
             if (__best_state.__current_ == __last) {
-              __states_.push(std::move(__best_state));
+              __states_.push_back(std::move(__best_state));
               return true;
             }
             __found_match = true;
           }
         }
-        __states_.push(std::move(__best_state));
+        __states_.push_back(std::move(__best_state));
         return __found_match;
       } else {
+        size_t __gcounter = 0;
         while (!__states_.empty()) {
-          if (__counter_ / _LIBCPP_REGEX_COMPLEXITY_FACTOR >= __length)
+          if (__gcounter / _LIBCPP_REGEX_COMPLEXITY_FACTOR >= __length)
             std::__throw_regex_error<regex_constants::error_complexity>();
-          auto __state = std::move(__states_.top());
-          __states_.pop();
-          if (__state.__execute(__first, __last, *this)) {
-            __states_.push(std::move(__state));
+          auto __state = std::move(__states_.back());
+          __states_.pop_back();
+          if (auto [__success, __counter] = __state.__execute(__first, __last, *this); __success) {
+            __states_.push_back(std::move(__state));
             return true;
+          } else {
+            __gcounter += __counter;
           }
         }
         return false;
@@ -471,11 +653,16 @@ class __interpreter {
   }
 
 public:
-  __interpreter(_Traits __traits, bool __find_longest) : __traits_(__traits), __find_longest_(__find_longest) {}
+  __interpreter(const _Traits& __traits, bool __find_longest) : __traits_(__traits), __find_longest_(__find_longest) {
+    __machine_.reserve(16);
+  }
 
   void __push_any_matcher() { push_back(__state::__match_any); }
+  void __push_any_except_newline_matcher() { push_back(__state::__match_any_except_newline); }
   void __push_end_state() { push_back(__state::__end_state); }
+  void __push_multiline_start_anchor() { push_back(__state::__multiline_start_anchor); }
   void __push_start_anchor() { push_back(__state::__start_anchor); }
+  void __push_multiline_end_anchor() { push_back(__state::__multiline_end_anchor); }
   void __push_end_anchor() { push_back(__state::__end_anchor); }
 
   void __push_char_matcher(_CharT __char,
@@ -499,21 +686,12 @@ class __interpreter {
     __write_uleb(*this, __num);
   }
 
-  void __push_n_matcher(size_t __expr_start, size_t __count) {
-    vector<__interpreter_info<_CharT> > __buffer;
-    __buffer.push_back(__state::__match_n_times);
-    __write_uleb(__buffer, __count);
-    __write_uleb(__buffer, __machine_.size() - __expr_start + 1);
-    insert(__expr_start, __buffer);
-    push_back(__state::__end_state);
-  }
-
-  void __push_n_to_m_matcher(size_t __expr_start, size_t __min, size_t __max) {
-    vector<__interpreter_info<_CharT> > __buffer;
+  void __push_n_to_m_matcher(size_t __expr_start, size_t __min, size_t __max, bool __greedy = true) {
+    vector<__interpreter_info<_CharT>> __buffer;
     __push_relative_jump(__buffer, size() - __expr_start);
     insert(__expr_start, __buffer);
     __expr_start += __buffer.size();
-    push_back(__state::__branch_n_to_m_matcher);
+    push_back(__greedy ? __state::__branch_n_to_m_matcher : __state::__branch_nongreedy_n_to_m_matcher);
     __write_uleb(__machine_, __initial_loop_values_.size());
     __write_uleb(__machine_, size() - __expr_start);
     __initial_loop_values_.push_back(__min);
@@ -544,6 +722,8 @@ class __interpreter {
     _CharT __buffer[std::max(sizeof(typename _Traits::char_class_type) / sizeof(_CharT), size_t(1))];
     __builtin_memcpy(__buffer, &__expr.__mask_, sizeof(__buffer));
     append_range(__buffer);
+    __builtin_memcpy(__buffer, &__expr.__neg_mask_, sizeof(__buffer));
+    append_range(__buffer);
 
     basic_string<_CharT> __equivalences_buffer;
     for (auto& __eq : __expr.__equivalences_)
@@ -551,33 +731,112 @@ class __interpreter {
     __write_uleb(*this, __expr.__chars_.size());
     __write_uleb(*this, __expr.__digraphs_.size() / 2);
     __write_uleb(*this, __expr.__ranges_.size() / 4);
+    __write_uleb(*this, __expr.__neg_chars_.size());
     __write_uleb(*this, __expr.__equivalences_.size());
     __write_uleb(*this, __equivalences_buffer.size());
     append_range(__expr.__chars_);
     append_range(__expr.__digraphs_);
     append_range(__expr.__ranges_);
+    append_range(__expr.__neg_chars_);
     append_range(__equivalences_buffer);
   }
 
+  void __push_word_boundary() { push_back(__state::__match_word_boundary); }
+  void __push_no_word_boundary() { push_back(__state::__match_no_word_boundary); }
+
+  struct __lookahead_info {
+    vector<size_t> __initial_loop_values_;
+    size_t __lookahead_start_;
+  };
+
+  __lookahead_info __start_lookahead() {
+    __lookahead_info __ret;
+    __ret.__initial_loop_values_ = std::move(__initial_loop_values_);
+    __ret.__lookahead_start_     = __machine_.size();
+    return __ret;
+  }
+
+  void __push_lookahead(bool __is_positive, __lookahead_info __info, size_t __marked_base, size_t __marked_count) {
+    __push_end_state();
+    vector<__interpreter_info<_CharT>> __buffer;
+    __buffer.push_back(__is_positive ? __state::__positive_lookahead : __state::__negative_lookahead);
+    __write_uleb(__buffer, __machine_.size() - __info.__lookahead_start_);
+    __write_uleb(__buffer, __marked_count);
+    __write_uleb(__buffer, __marked_base);
+    __write_uleb(__buffer, __initial_loop_values_.size());
+    for (size_t __val : __initial_loop_values_)
+      __write_uleb(__buffer, __val);
+    insert(__info.__lookahead_start_, __buffer);
+  }
+
   size_t size() const { return __machine_.size(); }
 
-  __global_execution_state __get_exec_state(
-      vector<sub_match<const _CharT*>>& __sub_matches,
-      const _CharT* __current,
-      bool __at_first,
-      regex_constants::match_flag_type __flags) const {
-    typename __global_execution_state::__local_execution_state __base_state;
-    __base_state.__sub_matches_ = __sub_matches;
-    __base_state.__current_     = __current;
-    __base_state.__loop_values_ = __initial_loop_values_;
-    __base_state.__loop_starts_.resize(__initial_loop_values_.size());
+  pair<bool, const _CharT*>
+  __execute(regex_constants::match_flag_type __flags,
+            const _CharT* __first,
+            const _CharT* __last,
+            vector<sub_match<const _CharT*>>& __sub_matches) const {
+    using __local_state = typename __global_execution_state::__local_execution_state;
+    __local_state __base_state;
+    __base_state.__sub_matches_ = std::move(__sub_matches);
+    __base_state.__current_     = __first;
+    if (!__initial_loop_values_.empty()) {
+      __base_state.__loop_values_ = std::make_unique_for_overwrite<size_t[]>(__initial_loop_values_.size());
+      std::copy(__initial_loop_values_.begin(), __initial_loop_values_.end(), __base_state.__loop_values_.get());
+      __base_state.__loop_starts_ = std::make_unique<const _CharT*[]>(__initial_loop_values_.size());
+    }
     __base_state.__current_pos_ = 0;
-    stack<typename __global_execution_state::__local_execution_state> __s;
-    __s.push(__base_state);
-    return __global_execution_state{__at_first, __s, *this, __flags};
+
+    __global_execution_state __gexec_state{{}, *this, __flags};
+    auto [__base_state_matched, __gcounter] = __base_state.__execute(__first, __last, __gexec_state);
+
+    size_t __length = __last - __first + 1;
+    if (__gexec_state.__machine_.__find_longest_) {
+      __local_state __best_state = __base_state_matched ? std::move(__base_state) : __local_state{};
+      bool __found_match         = __base_state_matched;
+      while (!__gexec_state.__states_.empty()) {
+        if (__gcounter / _LIBCPP_REGEX_COMPLEXITY_FACTOR >= __length)
+          std::__throw_regex_error<regex_constants::error_complexity>();
+        auto __state = std::move(__gexec_state.__states_.back());
+        __gexec_state.__states_.pop_back();
+        auto [__success, __counter] = __state.__execute(__first, __last, __gexec_state);
+        __gcounter += __counter;
+        if (__success) {
+          if (!__found_match || __best_state.__current_ < __state.__current_)
+            __best_state = std::move(__state);
+          if (__best_state.__current_ == __last) {
+            __sub_matches = std::move(__best_state.__sub_matches_);
+            return {true, __best_state.__current_};
+          }
+          __found_match = true;
+        }
+      }
+      if (!__found_match)
+        return {false, {}};
+      __sub_matches = std::move(__best_state.__sub_matches_);
+      return {true, __best_state.__current_};
+    } else {
+      if (__base_state_matched) {
+        __sub_matches = std::move(__base_state.__sub_matches_);
+        return {true, __base_state.__current_};
+      }
+      while (!__gexec_state.__states_.empty()) {
+        if (__gcounter / _LIBCPP_REGEX_COMPLEXITY_FACTOR >= __length)
+          std::__throw_regex_error<regex_constants::error_complexity>();
+        auto __state = std::move(__gexec_state.__states_.back());
+        __gexec_state.__states_.pop_back();
+        if (auto [__success, __counter] = __state.__execute(__first, __last, __gexec_state); __success) {
+          __sub_matches = std::move(__state.__sub_matches_);
+          return {true, __state.__current_};
+        } else {
+          __gcounter += __counter;
+        }
+      }
+      return {false, {}};
+    }
   }
 
-  _Traits __get_traits() { return __traits_; }
+  const _Traits& __get_traits() const { return __traits_; }
 };
 } // namespace __regex
 
diff --git a/libcxx/include/__regex/parser_common.h b/libcxx/include/__regex/parser_common.h
index 44b5ebd563f05..f7ea5418b0cc0 100644
--- a/libcxx/include/__regex/parser_common.h
+++ b/libcxx/include/__regex/parser_common.h
@@ -6,8 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef _LIBCPP___REGEX_ECMA_PARSER_H
-#define _LIBCPP___REGEX_ECMA_PARSER_H
+#ifndef _LIBCPP___REGEX_PARSER_COMMON_H
+#define _LIBCPP___REGEX_PARSER_COMMON_H
 
 #include <__algorithm/search.h>
 #include <__config>
@@ -68,6 +68,115 @@ _CharT __parse_awk_escape(_ForwardIterator& __first, _ForwardIterator __last) {
   return _CharT(__val);
 }
 
+template <class _CharT, class _Traits, class _ForwardIterator>
+_CharT __parse_character_escape(
+    __interpreter<_CharT, _Traits>& __machine, _ForwardIterator& __first, _ForwardIterator __last) {
+  auto __get_next_converted = [&](bool __advance = true) {
+    if (__first == __last)
+      std::__throw_regex_error<regex_constants::error_escape>();
+    auto __converted = __machine.__get_traits().value(*__first, 16);
+    if (__advance)
+      ++__first;
+    if (__converted == -1)
+      std::__throw_regex_error<regex_constants::error_escape>();
+    return __converted;
+  };
+
+  size_t __sum = 0;
+  switch (*__first) {
+  case 'f':
+    ++__first;
+    return '\f';
+  case 'n':
+    ++__first;
+    return '\n';
+  case 'r':
+    ++__first;
+    return '\r';
+  case 't':
+    ++__first;
+    return '\t';
+  case 'v':
+    ++__first;
+    return '\v';
+  case '0':
+    ++__first;
+    return '\0';
+
+  case 'c': {
+    auto __next = std::next(__first);
+    if (__next == __last || !((*__next >= 'A' && *__next <= 'Z') || (*__next >= 'a' && *__next <= 'z')))
+      std::__throw_regex_error<regex_constants::error_escape>();
+    __first = std::next(__next);
+    return _CharT(*__next & ~0x20);
+  }
+
+  case 'u': {
+    ++__first;
+    __sum = __get_next_converted();
+    __sum = __sum * 16 + __get_next_converted(false);
+  }
+    [[__fallthrough__]];
+  case 'x': {
+    ++__first;
+    __sum = __sum * 16 + __get_next_converted();
+    __sum = __sum * 16 + __get_next_converted();
+    return __sum;
+  }
+  default: {
+    if (__machine.__get_traits().isctype(*__first, ctype_base::alnum))
+      std::__throw_regex_error<regex_constants::error_escape>();
+    return *__first++;
+  }
+  }
+}
+
+template <class _CharT, class _Traits, class _ForwardIterator>
+void __parse_class_escape(
+    __interpreter<_CharT, _Traits>& __machine,
+    _ForwardIterator& __first,
+    _ForwardIterator __last,
+    basic_string<_CharT>& __start_range,
+    __bracket_expr<_CharT, _Traits>& __buffer) {
+  switch (*__first) {
+  case '\0':
+    ++__first;
+    __start_range = '\0';
+    return;
+  case 'b':
+    ++__first;
+    __start_range = '\b';
+    return;
+  case 'd':
+    ++__first;
+    __buffer.__mask_ |= ctype_base::digit;
+    return;
+  case 'D':
+    ++__first;
+    __buffer.__neg_mask_ |= ctype_base::digit;
+    return;
+  case 's':
+    ++__first;
+    __buffer.__mask_ |= ctype_base::space;
+    return;
+  case 'S':
+    ++__first;
+    __buffer.__neg_mask_ |= ctype_base::space;
+    return;
+  case 'w':
+    ++__first;
+    __buffer.__mask_ |= ctype_base::alnum;
+    __buffer.__chars_.push_back('_');
+    return;
+  case 'W':
+    ++__first;
+    __buffer.__neg_mask_ |= ctype_base::alnum;
+    __buffer.__neg_chars_.push_back('_');
+    return;
+  }
+  __start_range = __regex::__parse_character_escape(__machine, __first, __last);
+}
+
 // bracket expression parsing
 
 template <class _CharT, class _Traits, class _ForwardIterator>
@@ -190,7 +299,18 @@ bool __parse_expression_term(
              __grammar == regex_constants::awk && *__first == '\\') {
     if (++__first == __last)
       return false;
-    __start_range = __parse_awk_escape<_CharT>(__first, __last);
+    __start_range = __regex::__parse_awk_escape<_CharT>(__first, __last);
+  } else if (__grammar == regex_constants::ECMAScript && *__first == '\\') {
+    if (++__first == __last)
+      return false;
+    __regex::__parse_class_escape<_CharT>(__machine, __first, __last, __start_range, __buffer);
+    if (__start_range.empty()) {
+      if (__first == __last)
+        return false;
+      if (*__first == '-')
+        std::__throw_regex_error<regex_constants::error_range>();
+      return true;
+    }
   } else {
     __start_range = *__first;
     ++__first;
@@ -236,10 +356,20 @@ bool __parse_expression_term(
     if (++__first == __last)
       return false;
     __start_range = __parse_awk_escape<_CharT>(__first, __last);
+  } else if (__grammar == regex_constants::ECMAScript && *__first == '\\') {
+    if (++__first == __last)
+      return false;
+    __regex::__parse_class_escape(__machine, __first, __last, __end_range, __buffer);
+    if (__end_range.empty())
+      std::__throw_regex_error<regex_constants::error_range>();
   } else {
     __end_range = *__first;
     ++__first;
   }
+  if (__start_range.size() == 1 && __end_range.size() == 1) {
+    if (char_traits<_CharT>::lt(__end_range[0], __start_range[0]))
+      std::__throw_regex_error<regex_constants::error_range>();
+  }
   __buffer.__ranges_.push_back(__start_range[0]);
   __buffer.__ranges_.push_back(__start_range.size() == 2 ? __start_range[1] : '\0');
   __buffer.__ranges_.push_back(__end_range[0]);
@@ -329,6 +459,93 @@ __dup_count_result __parse_dup_count(_ForwardIterator& __first, _ForwardIterator
   return __dup_count_result(__num, true);
 }
 
+// duplication symbol parsing
+
+template <class _CharT, class _Traits, class _ForwardIterator>
+bool __parse_dupl_symbol(
+    __interpreter<_CharT, _Traits>& __machine,
+    _ForwardIterator& __first,
+    _ForwardIterator __last,
+    size_t __expr_start,
+    bool __has_nongreedy = false) {
+  if (__first == __last)
+    return false;
+
+  auto __check_greediness = [&]() {
+    if (!__has_nongreedy)
+      return true;
+    if (__first == __last || *__first != '?')
+      return true;
+    ++__first;
+    return false;
+  };
+
+  switch (*__first) {
+  case '*': {
+    ++__first;
+    __machine.__push_n_to_m_matcher(__expr_start, 0, numeric_limits<size_t>::max(), __check_greediness());
+  } break;
+
+  case '+': {
+    ++__first;
+    __machine.__push_n_to_m_matcher(__expr_start, 1, numeric_limits<size_t>::max(), __check_greediness());
+  } break;
+
+  case '?': {
+    ++__first;
+    __machine.__push_n_to_m_matcher(__expr_start, 0, 1, __check_greediness());
+  } break;
+
+  case '{': {
+    ++__first;
+    size_t __min;
+    if (auto __res = __regex::__parse_dup_count(__first, __last)) {
+      __min = __res.__num_;
+    } else {
+      std::__throw_regex_error<regex_constants::error_badbrace>();
+    }
+    if (__first == __last)
+      std::__throw_regex_error<regex_constants::error_brace>();
+
+    switch (*__first) {
+    case '}': {
+      ++__first;
+      __machine.__push_n_to_m_matcher(__expr_start, __min, __min);
+      return true;
+    } break;
+
+    case ',': {
+      ++__first;
+      if (__first == __last)
+        std::__throw_regex_error<regex_constants::error_badbrace>();
+      if (*__first == '}') {
+        ++__first;
+        __machine.__push_n_to_m_matcher(__expr_start, __min, numeric_limits<size_t>::max());
+        return true;
+      }
+
+      size_t __max;
+      if (auto __res = __regex::__parse_dup_count(__first, __last)) {
+        __max = __res.__num_;
+      } else {
+        std::__throw_regex_error<regex_constants::error_brace>();
+      }
+      if (__first == __last || *__first != '}')
+        std::__throw_regex_error<regex_constants::error_brace>();
+      ++__first;
+      if (__max < __min)
+        std::__throw_regex_error<regex_constants::error_badbrace>();
+      __machine.__push_n_to_m_matcher(__expr_start, __min, __max);
+      return true;
+    } break;
+    default:
+      std::__throw_regex_error<regex_constants::error_badbrace>();
+    }
+  } break;
+  }
+  return false;
+}
+
 } // namespace __regex
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__regex/regex_error.h b/libcxx/include/__regex/regex_error.h
index ee7811cd8edbd..4bf29d74c7282 100644
--- a/libcxx/include/__regex/regex_error.h
+++ b/libcxx/include/__regex/regex_error.h
@@ -98,7 +98,8 @@ enum match_flag_type {
   format_no_copy    = 1 << 9,
   format_first_only = 1 << 10,
   __no_update_pos   = 1 << 11,
-  __full_match      = 1 << 12
+  __full_match      = 1 << 12,
+  __at_first        = 1 << 13, // Only used behind an ABI firewall, so the value can be changed at any point.
 };
 
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR match_flag_type operator~(match_flag_type __x) {
diff --git a/libcxx/include/regex b/libcxx/include/regex
index 7f3449bd92500..654f02a5df4f4 100644
--- a/libcxx/include/regex
+++ b/libcxx/include/regex
@@ -824,6 +824,7 @@ typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;
 #    include <__memory/shared_ptr.h>
 #    include <__memory_resource/polymorphic_allocator.h>
 #    include <__regex/basic_parser.h>
+#    include <__regex/ecma_parser.h>
 #    include <__regex/extended_parser.h>
 #    include <__regex/regex_error.h>
 #    include <__type_traits/is_swappable.h>
@@ -1269,2287 +1270,370 @@ void __empty_state<_CharT>::__exec(__state& __s) const {
   __s.__node_ = this->first();
 }
 
-// __empty_non_own_state
-
-template <class _CharT>
-class __empty_non_own_state : public __has_one_state<_CharT> {
-  typedef __has_one_state<_CharT> base;
-
-public:
-  typedef std::__state<_CharT> __state;
-
-  _LIBCPP_HIDE_FROM_ABI explicit __empty_non_own_state(__node<_CharT>* __s) : base(__s) {}
-
-  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
-};
-
-template <class _CharT>
-void __empty_non_own_state<_CharT>::__exec(__state& __s) const {
-  __s.__do_   = __state::__accept_but_not_consume;
-  __s.__node_ = this->first();
-}
-
-// __repeat_one_loop
-
-template <class _CharT>
-class __repeat_one_loop : public __has_one_state<_CharT> {
-  typedef __has_one_state<_CharT> base;
-
-public:
-  typedef std::__state<_CharT> __state;
-
-  _LIBCPP_HIDE_FROM_ABI explicit __repeat_one_loop(__node<_CharT>* __s) : base(__s) {}
-
-  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
-};
-
-template <class _CharT>
-void __repeat_one_loop<_CharT>::__exec(__state& __s) const {
-  __s.__do_   = __state::__repeat;
-  __s.__node_ = this->first();
-}
-
-// __owns_two_states
-
-template <class _CharT>
-class __owns_two_states : public __owns_one_state<_CharT> {
-  typedef __owns_one_state<_CharT> base;
-
-  base* __second_;
+template <class _CharT, class _Traits>
+class __interpreter_state : public __empty_state<_CharT> {
+  __regex::__interpreter<_CharT, _Traits> __machine_;
 
 public:
-  _LIBCPP_HIDE_FROM_ABI explicit __owns_two_states(__node<_CharT>* __s1, base* __s2) : base(__s1), __second_(__s2) {}
-
-  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual ~__owns_two_states();
+  _LIBCPP_HIDE_FROM_ABI __interpreter_state(__regex::__interpreter<_CharT, _Traits> __machine, __node<_CharT>* __s)
+      : __empty_state<_CharT>(__s), __machine_(std::move(__machine)) {}
 
-  _LIBCPP_HIDE_FROM_ABI base* second() const { return __second_; }
-  _LIBCPP_HIDE_FROM_ABI base*& second() { return __second_; }
+  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __exec(__state<_CharT>& __state) const override {
+    auto __res = __machine_.__execute(
+        __state.__flags_ | (__state.__at_first_ ? regex_constants::__at_first : regex_constants::match_flag_type()),
+        __state.__first_,
+        __state.__last_,
+        __state.__sub_matches_);
+    __state.__do_      = __res.first ? std::__state<_CharT>::__end_state : std::__state<_CharT>::__reject;
+    __state.__current_ = __res.second;
+  }
 };
 
-template <class _CharT>
-__owns_two_states<_CharT>::~__owns_two_states() {
-  delete __second_;
-}
-
-// __loop
-
-template <class _CharT>
-class __loop : public __owns_two_states<_CharT> {
-  typedef __owns_two_states<_CharT> base;
+template <class _CharT, class _Traits = regex_traits<_CharT> >
+class basic_regex;
 
-  size_t __min_;
-  size_t __max_;
-  unsigned __loop_id_;
-  unsigned __mexp_begin_;
-  unsigned __mexp_end_;
-  bool __greedy_;
+typedef basic_regex<char> regex;
+#    if _LIBCPP_HAS_WIDE_CHARACTERS
+typedef basic_regex<wchar_t> wregex;
+#    endif
 
+template <class _CharT, class _Traits>
+class _LIBCPP_PREFERRED_NAME(regex) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wregex)) basic_regex {
 public:
-  typedef std::__state<_CharT> __state;
-
-  _LIBCPP_HIDE_FROM_ABI explicit __loop(
-      unsigned __loop_id,
-      __node<_CharT>* __s1,
-      __owns_one_state<_CharT>* __s2,
-      unsigned __mexp_begin,
-      unsigned __mexp_end,
-      bool __greedy = true,
-      size_t __min  = 0,
-      size_t __max  = numeric_limits<size_t>::max())
-      : base(__s1, __s2),
-        __min_(__min),
-        __max_(__max),
-        __loop_id_(__loop_id),
-        __mexp_begin_(__mexp_begin),
-        __mexp_end_(__mexp_end),
-        __greedy_(__greedy) {}
-
-  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state& __s) const;
-  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec_split(bool __second, __state& __s) const;
+  // types:
+  typedef _CharT value_type;
+  typedef _Traits traits_type;
+  typedef typename _Traits::string_type string_type;
+  typedef regex_constants::syntax_option_type flag_type;
+  typedef typename _Traits::locale_type locale_type;
 
 private:
-  _LIBCPP_HIDE_FROM_ABI void __init_repeat(__state& __s) const {
-    __s.__loop_data_[__loop_id_].second = __s.__current_;
-    for (size_t __i = __mexp_begin_ - 1; __i != __mexp_end_ - 1; ++__i) {
-      __s.__sub_matches_[__i].first   = __s.__last_;
-      __s.__sub_matches_[__i].second  = __s.__last_;
-      __s.__sub_matches_[__i].matched = false;
-    }
-  }
-};
-
-template <class _CharT>
-void __loop<_CharT>::__exec(__state& __s) const {
-  if (__s.__do_ == __state::__repeat) {
-    bool __do_repeat = ++__s.__loop_data_[__loop_id_].first < __max_;
-    bool __do_alt    = __s.__loop_data_[__loop_id_].first >= __min_;
-    if (__do_repeat && __do_alt && __s.__loop_data_[__loop_id_].second == __s.__current_)
-      __do_repeat = false;
-    if (__do_repeat && __do_alt)
-      __s.__do_ = __state::__split;
-    else if (__do_repeat) {
-      __s.__do_   = __state::__accept_but_not_consume;
-      __s.__node_ = this->first();
-      __init_repeat(__s);
-    } else {
-      __s.__do_   = __state::__accept_but_not_consume;
-      __s.__node_ = this->second();
-    }
-  } else {
-    __s.__loop_data_[__loop_id_].first = 0;
-    bool __do_repeat                   = 0 < __max_;
-    bool __do_alt                      = 0 >= __min_;
-    if (__do_repeat && __do_alt)
-      __s.__do_ = __state::__split;
-    else if (__do_repeat) {
-      __s.__do_   = __state::__accept_but_not_consume;
-      __s.__node_ = this->first();
-      __init_repeat(__s);
-    } else {
-      __s.__do_   = __state::__accept_but_not_consume;
-      __s.__node_ = this->second();
-    }
-  }
-}
-
-template <class _CharT>
-void __loop<_CharT>::__exec_split(bool __second, __state& __s) const {
-  __s.__do_ = __state::__accept_but_not_consume;
-  if (__greedy_ != __second) {
-    __s.__node_ = this->first();
-    __init_repeat(__s);
-  } else
-    __s.__node_ = this->second();
-}
-
-// __alternate
-
-template <class _CharT>
-class __alternate : public __owns_two_states<_CharT> {
-  typedef __owns_two_states<_CharT> base;
+  _Traits __traits_;
+  flag_type __flags_;
+  unsigned __marked_count_;
+  unsigned __loop_count_;
+  int __open_count_;
+  shared_ptr<__empty_state<_CharT> > __start_;
+  __owns_one_state<_CharT>* __end_;
 
-public:
   typedef std::__state<_CharT> __state;
-
-  _LIBCPP_HIDE_FROM_ABI explicit __alternate(__owns_one_state<_CharT>* __s1, __owns_one_state<_CharT>* __s2)
-      : base(__s1, __s2) {}
-
-  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state& __s) const;
-  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec_split(bool __second, __state& __s) const;
-};
-
-template <class _CharT>
-void __alternate<_CharT>::__exec(__state& __s) const {
-  __s.__do_ = __state::__split;
-}
-
-template <class _CharT>
-void __alternate<_CharT>::__exec_split(bool __second, __state& __s) const {
-  __s.__do_ = __state::__accept_but_not_consume;
-  if (__second)
-    __s.__node_ = this->second();
-  else
-    __s.__node_ = this->first();
-}
-
-// __begin_marked_subexpression
-
-template <class _CharT>
-class __begin_marked_subexpression : public __owns_one_state<_CharT> {
-  typedef __owns_one_state<_CharT> base;
-
-  unsigned __mexp_;
+  typedef std::__node<_CharT> __node;
 
 public:
-  typedef std::__state<_CharT> __state;
-
-  _LIBCPP_HIDE_FROM_ABI explicit __begin_marked_subexpression(unsigned __mexp, __node<_CharT>* __s)
-      : base(__s), __mexp_(__mexp) {}
-
-  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
-};
-
-template <class _CharT>
-void __begin_marked_subexpression<_CharT>::__exec(__state& __s) const {
-  __s.__do_                             = __state::__accept_but_not_consume;
-  __s.__sub_matches_[__mexp_ - 1].first = __s.__current_;
-  __s.__node_                           = this->first();
-}
-
-// __end_marked_subexpression
+  // constants:
+  static const regex_constants::syntax_option_type icase      = regex_constants::icase;
+  static const regex_constants::syntax_option_type nosubs     = regex_constants::nosubs;
+  static const regex_constants::syntax_option_type optimize   = regex_constants::optimize;
+  static const regex_constants::syntax_option_type collate    = regex_constants::collate;
+  static const regex_constants::syntax_option_type ECMAScript = regex_constants::ECMAScript;
+  static const regex_constants::syntax_option_type basic      = regex_constants::basic;
+  static const regex_constants::syntax_option_type extended   = regex_constants::extended;
+  static const regex_constants::syntax_option_type awk        = regex_constants::awk;
+  static const regex_constants::syntax_option_type grep       = regex_constants::grep;
+  static const regex_constants::syntax_option_type egrep      = regex_constants::egrep;
+  static const regex_constants::syntax_option_type multiline  = regex_constants::multiline;
 
-template <class _CharT>
-class __end_marked_subexpression : public __owns_one_state<_CharT> {
-  typedef __owns_one_state<_CharT> base;
+  // construct/copy/destroy:
+  _LIBCPP_HIDE_FROM_ABI basic_regex()
+      : __flags_(regex_constants::ECMAScript),
+        __marked_count_(0),
+        __loop_count_(0),
+        __open_count_(0),
+        __end_(nullptr) {}
+  _LIBCPP_HIDE_FROM_ABI explicit basic_regex(const value_type* __p, flag_type __f = regex_constants::ECMAScript)
+      : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(nullptr) {
+    __init(__p, __p + __traits_.length(__p));
+  }
 
-  unsigned __mexp_;
+  _LIBCPP_HIDE_FROM_ABI basic_regex(const value_type* __p, size_t __len, flag_type __f = regex_constants::ECMAScript)
+      : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(nullptr) {
+    __init(__p, __p + __len);
+  }
 
-public:
-  typedef std::__state<_CharT> __state;
+  //     basic_regex(const basic_regex&) = default;
+  //     basic_regex(basic_regex&&) = default;
+  template <class _ST, class _SA>
+  _LIBCPP_HIDE_FROM_ABI explicit basic_regex(const basic_string<value_type, _ST, _SA>& __p,
+                                             flag_type __f = regex_constants::ECMAScript)
+      : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(nullptr) {
+    __init(__p.begin(), __p.end());
+  }
 
-  _LIBCPP_HIDE_FROM_ABI explicit __end_marked_subexpression(unsigned __mexp, __node<_CharT>* __s)
-      : base(__s), __mexp_(__mexp) {}
+  template <class _ForwardIterator>
+  _LIBCPP_HIDE_FROM_ABI
+  basic_regex(_ForwardIterator __first, _ForwardIterator __last, flag_type __f = regex_constants::ECMAScript)
+      : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(nullptr) {
+    __init(__first, __last);
+  }
+#    ifndef _LIBCPP_CXX03_LANG
+  _LIBCPP_HIDE_FROM_ABI basic_regex(initializer_list<value_type> __il, flag_type __f = regex_constants::ECMAScript)
+      : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(nullptr) {
+    __init(__il.begin(), __il.end());
+  }
+#    endif // _LIBCPP_CXX03_LANG
 
-  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
-};
+  //    ~basic_regex() = default;
 
-template <class _CharT>
-void __end_marked_subexpression<_CharT>::__exec(__state& __s) const {
-  __s.__do_                               = __state::__accept_but_not_consume;
-  __s.__sub_matches_[__mexp_ - 1].second  = __s.__current_;
-  __s.__sub_matches_[__mexp_ - 1].matched = true;
-  __s.__node_                             = this->first();
-}
+  //     basic_regex& operator=(const basic_regex&) = default;
+  //     basic_regex& operator=(basic_regex&&) = default;
+  _LIBCPP_HIDE_FROM_ABI basic_regex& operator=(const value_type* __p) { return assign(__p); }
+#    ifndef _LIBCPP_CXX03_LANG
+  _LIBCPP_HIDE_FROM_ABI basic_regex& operator=(initializer_list<value_type> __il) { return assign(__il); }
+#    endif // _LIBCPP_CXX03_LANG
+  template <class _ST, class _SA>
+  _LIBCPP_HIDE_FROM_ABI basic_regex& operator=(const basic_string<value_type, _ST, _SA>& __p) {
+    return assign(__p);
+  }
 
-// __back_ref
+  // assign:
+  _LIBCPP_HIDE_FROM_ABI basic_regex& assign(const basic_regex& __that) { return *this = __that; }
+#    ifndef _LIBCPP_CXX03_LANG
+  _LIBCPP_HIDE_FROM_ABI basic_regex& assign(basic_regex&& __that) _NOEXCEPT { return *this = std::move(__that); }
+#    endif
+  _LIBCPP_HIDE_FROM_ABI basic_regex& assign(const value_type* __p, flag_type __f = regex_constants::ECMAScript) {
+    return assign(__p, __p + __traits_.length(__p), __f);
+  }
+  _LIBCPP_HIDE_FROM_ABI basic_regex&
+  assign(const value_type* __p, size_t __len, flag_type __f = regex_constants::ECMAScript) {
+    return assign(__p, __p + __len, __f);
+  }
+  template <class _ST, class _SA>
+  _LIBCPP_HIDE_FROM_ABI basic_regex&
+  assign(const basic_string<value_type, _ST, _SA>& __s, flag_type __f = regex_constants::ECMAScript) {
+    return assign(__s.begin(), __s.end(), __f);
+  }
 
-template <class _CharT>
-class __back_ref : public __owns_one_state<_CharT> {
-  typedef __owns_one_state<_CharT> base;
+  template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
+  _LIBCPP_HIDE_FROM_ABI basic_regex&
+  assign(_InputIterator __first, _InputIterator __last, flag_type __f = regex_constants::ECMAScript) {
+    basic_string<_CharT> __t(__first, __last);
+    return assign(__t.begin(), __t.end(), __f);
+  }
 
-  unsigned __mexp_;
+private:
+  _LIBCPP_HIDE_FROM_ABI void __member_init(flag_type __f) {
+    __flags_        = __f;
+    __marked_count_ = 0;
+    __loop_count_   = 0;
+    __open_count_   = 0;
+    __end_          = nullptr;
+  }
 
 public:
-  typedef std::__state<_CharT> __state;
-
-  _LIBCPP_HIDE_FROM_ABI explicit __back_ref(unsigned __mexp, __node<_CharT>* __s) : base(__s), __mexp_(__mexp) {}
-
-  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
-};
-
-template <class _CharT>
-void __back_ref<_CharT>::__exec(__state& __s) const {
-  if (__mexp_ > __s.__sub_matches_.size())
-    std::__throw_regex_error<regex_constants::error_backref>();
-  sub_match<const _CharT*>& __sm = __s.__sub_matches_[__mexp_ - 1];
-  if (__sm.matched) {
-    ptrdiff_t __len = __sm.second - __sm.first;
-    if (__s.__last_ - __s.__current_ >= __len && std::equal(__sm.first, __sm.second, __s.__current_)) {
-      __s.__do_ = __state::__accept_but_not_consume;
-      __s.__current_ += __len;
-      __s.__node_ = this->first();
-    } else {
-      __s.__do_   = __state::__reject;
-      __s.__node_ = nullptr;
-    }
-  } else {
-    __s.__do_   = __state::__reject;
-    __s.__node_ = nullptr;
+  template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>
+  _LIBCPP_HIDE_FROM_ABI basic_regex&
+  assign(_ForwardIterator __first, _ForwardIterator __last, flag_type __f = regex_constants::ECMAScript) {
+    return assign(basic_regex(__first, __last, __f));
   }
-}
 
-// __back_ref_icase
-
-template <class _CharT, class _Traits>
-class __back_ref_icase : public __owns_one_state<_CharT> {
-  typedef __owns_one_state<_CharT> base;
-
-  _Traits __traits_;
-  unsigned __mexp_;
+#    ifndef _LIBCPP_CXX03_LANG
 
-public:
-  typedef std::__state<_CharT> __state;
+  _LIBCPP_HIDE_FROM_ABI basic_regex&
+  assign(initializer_list<value_type> __il, flag_type __f = regex_constants::ECMAScript) {
+    return assign(__il.begin(), __il.end(), __f);
+  }
 
-  _LIBCPP_HIDE_FROM_ABI explicit __back_ref_icase(const _Traits& __traits, unsigned __mexp, __node<_CharT>* __s)
-      : base(__s), __traits_(__traits), __mexp_(__mexp) {}
+#    endif // _LIBCPP_CXX03_LANG
 
-  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
-};
+  // const operations:
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI unsigned mark_count() const { return __marked_count_; }
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI flag_type flags() const { return __flags_; }
 
-template <class _CharT, class _Traits>
-void __back_ref_icase<_CharT, _Traits>::__exec(__state& __s) const {
-  sub_match<const _CharT*>& __sm = __s.__sub_matches_[__mexp_ - 1];
-  if (__sm.matched) {
-    ptrdiff_t __len = __sm.second - __sm.first;
-    if (__s.__last_ - __s.__current_ >= __len) {
-      for (ptrdiff_t __i = 0; __i < __len; ++__i) {
-        if (__traits_.translate_nocase(__sm.first[__i]) != __traits_.translate_nocase(__s.__current_[__i]))
-          goto __not_equal;
-      }
-      __s.__do_ = __state::__accept_but_not_consume;
-      __s.__current_ += __len;
-      __s.__node_ = this->first();
-    } else {
-      __s.__do_   = __state::__reject;
-      __s.__node_ = nullptr;
-    }
-  } else {
-  __not_equal:
-    __s.__do_   = __state::__reject;
-    __s.__node_ = nullptr;
+  // locale:
+  _LIBCPP_HIDE_FROM_ABI locale_type imbue(locale_type __loc) {
+    __member_init(ECMAScript);
+    __start_.reset();
+    return __traits_.imbue(__loc);
   }
-}
-
-// __back_ref_collate
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI locale_type getloc() const { return __traits_.getloc(); }
 
-template <class _CharT, class _Traits>
-class __back_ref_collate : public __owns_one_state<_CharT> {
-  typedef __owns_one_state<_CharT> base;
-
-  _Traits __traits_;
-  unsigned __mexp_;
-
-public:
-  typedef std::__state<_CharT> __state;
-
-  _LIBCPP_HIDE_FROM_ABI explicit __back_ref_collate(const _Traits& __traits, unsigned __mexp, __node<_CharT>* __s)
-      : base(__s), __traits_(__traits), __mexp_(__mexp) {}
-
-  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
-};
-
-template <class _CharT, class _Traits>
-void __back_ref_collate<_CharT, _Traits>::__exec(__state& __s) const {
-  sub_match<const _CharT*>& __sm = __s.__sub_matches_[__mexp_ - 1];
-  if (__sm.matched) {
-    ptrdiff_t __len = __sm.second - __sm.first;
-    if (__s.__last_ - __s.__current_ >= __len) {
-      for (ptrdiff_t __i = 0; __i < __len; ++__i) {
-        if (__traits_.translate(__sm.first[__i]) != __traits_.translate(__s.__current_[__i]))
-          goto __not_equal;
-      }
-      __s.__do_ = __state::__accept_but_not_consume;
-      __s.__current_ += __len;
-      __s.__node_ = this->first();
-    } else {
-      __s.__do_   = __state::__reject;
-      __s.__node_ = nullptr;
-    }
-  } else {
-  __not_equal:
-    __s.__do_   = __state::__reject;
-    __s.__node_ = nullptr;
-  }
-}
-
-// __word_boundary
-
-template <class _CharT, class _Traits>
-class __word_boundary : public __owns_one_state<_CharT> {
-  typedef __owns_one_state<_CharT> base;
-
-  _Traits __traits_;
-  bool __invert_;
-
-public:
-  typedef std::__state<_CharT> __state;
-
-  _LIBCPP_HIDE_FROM_ABI explicit __word_boundary(const _Traits& __traits, bool __invert, __node<_CharT>* __s)
-      : base(__s), __traits_(__traits), __invert_(__invert) {}
-
-  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
-};
-
-template <class _CharT, class _Traits>
-void __word_boundary<_CharT, _Traits>::__exec(__state& __s) const {
-  bool __is_word_b = false;
-  if (__s.__first_ != __s.__last_) {
-    if (__s.__current_ == __s.__last_) {
-      if (!(__s.__flags_ & regex_constants::match_not_eow)) {
-        _CharT __c  = __s.__current_[-1];
-        __is_word_b = __c == '_' || __traits_.isctype(__c, ctype_base::alnum);
-      }
-    } else if (__s.__current_ == __s.__first_ && !(__s.__flags_ & regex_constants::match_prev_avail)) {
-      if (!(__s.__flags_ & regex_constants::match_not_bow)) {
-        _CharT __c  = *__s.__current_;
-        __is_word_b = __c == '_' || __traits_.isctype(__c, ctype_base::alnum);
-      }
-    } else {
-      _CharT __c1    = __s.__current_[-1];
-      _CharT __c2    = *__s.__current_;
-      bool __is_c1_b = __c1 == '_' || __traits_.isctype(__c1, ctype_base::alnum);
-      bool __is_c2_b = __c2 == '_' || __traits_.isctype(__c2, ctype_base::alnum);
-      __is_word_b    = __is_c1_b != __is_c2_b;
-    }
-  }
-  if (__is_word_b != __invert_) {
-    __s.__do_   = __state::__accept_but_not_consume;
-    __s.__node_ = this->first();
-  } else {
-    __s.__do_   = __state::__reject;
-    __s.__node_ = nullptr;
-  }
-}
-
-template <class _CharT, class _Traits>
-class __interpreter_state : public __owns_one_state<_CharT> {
-  __regex::__interpreter<_CharT, _Traits> __machine_;
-
-public:
-  _LIBCPP_HIDE_FROM_ABI __interpreter_state(__regex::__interpreter<_CharT, _Traits> __machine, __node<_CharT>* __s)
-      : __owns_one_state<_CharT>(__s), __machine_(std::move(__machine)) {}
-
-  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __exec(__state<_CharT>& __state) const override {
-    auto __exec_state =
-        __machine_.__get_exec_state(__state.__sub_matches_, __state.__current_, __state.__at_first_, __state.__flags_);
-    if (!__exec_state.__execute(__state.__first_, __state.__last_)) {
-      __state.__do_ = std::__state<_CharT>::__reject;
-      __state.__node_ = nullptr;
-      return;
-    }
-    __state.__do_          = std::__state<_CharT>::__end_state;
-    auto& __matched_state  = __exec_state.__states_.top();
-    __state.__current_     = __matched_state.__current_;
-    __state.__sub_matches_ = __matched_state.__sub_matches_;
-  }
-};
-
-// __l_anchor
-
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool __is_eol(_CharT __c) {
-  return __c == '\r' || __c == '\n';
-}
-
-template <class _CharT>
-class __l_anchor_multiline : public __owns_one_state<_CharT> {
-  typedef __owns_one_state<_CharT> base;
-
-  bool __multiline_;
-
-public:
-  typedef std::__state<_CharT> __state;
-
-  _LIBCPP_HIDE_FROM_ABI __l_anchor_multiline(bool __multiline, __node<_CharT>* __s)
-      : base(__s), __multiline_(__multiline) {}
-
-  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
-};
-
-template <class _CharT>
-void __l_anchor_multiline<_CharT>::__exec(__state& __s) const {
-  if (__s.__at_first_ && __s.__current_ == __s.__first_ && !(__s.__flags_ & regex_constants::match_not_bol)) {
-    __s.__do_   = __state::__accept_but_not_consume;
-    __s.__node_ = this->first();
-  } else if (__multiline_ && !__s.__at_first_ && std::__is_eol(*std::prev(__s.__current_))) {
-    __s.__do_   = __state::__accept_but_not_consume;
-    __s.__node_ = this->first();
-  } else {
-    __s.__do_   = __state::__reject;
-    __s.__node_ = nullptr;
-  }
-}
-
-// __r_anchor
-
-template <class _CharT>
-class __r_anchor_multiline : public __owns_one_state<_CharT> {
-  typedef __owns_one_state<_CharT> base;
-
-  bool __multiline_;
-
-public:
-  typedef std::__state<_CharT> __state;
-
-  _LIBCPP_HIDE_FROM_ABI __r_anchor_multiline(bool __multiline, __node<_CharT>* __s)
-      : base(__s), __multiline_(__multiline) {}
-
-  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
-};
-
-template <class _CharT>
-void __r_anchor_multiline<_CharT>::__exec(__state& __s) const {
-  if (__s.__current_ == __s.__last_ && !(__s.__flags_ & regex_constants::match_not_eol)) {
-    __s.__do_   = __state::__accept_but_not_consume;
-    __s.__node_ = this->first();
-  } else if (__multiline_ && std::__is_eol(*__s.__current_)) {
-    __s.__do_   = __state::__accept_but_not_consume;
-    __s.__node_ = this->first();
-  } else {
-    __s.__do_   = __state::__reject;
-    __s.__node_ = nullptr;
-  }
-}
-
-// __match_any
-
-template <class _CharT>
-class __match_any : public __owns_one_state<_CharT> {
-  typedef __owns_one_state<_CharT> base;
-
-public:
-  typedef std::__state<_CharT> __state;
-
-  _LIBCPP_HIDE_FROM_ABI __match_any(__node<_CharT>* __s) : base(__s) {}
-
-  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
-};
-
-template <class _CharT>
-void __match_any<_CharT>::__exec(__state& __s) const {
-  if (__s.__current_ != __s.__last_ && *__s.__current_ != 0) {
-    __s.__do_ = __state::__accept_and_consume;
-    ++__s.__current_;
-    __s.__node_ = this->first();
-  } else {
-    __s.__do_   = __state::__reject;
-    __s.__node_ = nullptr;
-  }
-}
-
-// __match_any_but_newline
-
-template <class _CharT>
-class __match_any_but_newline : public __owns_one_state<_CharT> {
-  typedef __owns_one_state<_CharT> base;
-
-public:
-  typedef std::__state<_CharT> __state;
-
-  _LIBCPP_HIDE_FROM_ABI __match_any_but_newline(__node<_CharT>* __s) : base(__s) {}
-
-  void __exec(__state&) const override;
-};
-
-template <>
-_LIBCPP_EXPORTED_FROM_ABI void __match_any_but_newline<char>::__exec(__state&) const;
-#    if _LIBCPP_HAS_WIDE_CHARACTERS
-template <>
-_LIBCPP_EXPORTED_FROM_ABI void __match_any_but_newline<wchar_t>::__exec(__state&) const;
-#    endif
-
-// __match_char
-
-template <class _CharT>
-class __match_char : public __owns_one_state<_CharT> {
-  typedef __owns_one_state<_CharT> base;
-
-  _CharT __c_;
-
-public:
-  typedef std::__state<_CharT> __state;
-
-  _LIBCPP_HIDE_FROM_ABI __match_char(_CharT __c, __node<_CharT>* __s) : base(__s), __c_(__c) {}
-
-  __match_char(const __match_char&)            = delete;
-  __match_char& operator=(const __match_char&) = delete;
-
-  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
-};
-
-template <class _CharT>
-void __match_char<_CharT>::__exec(__state& __s) const {
-  if (__s.__current_ != __s.__last_ && *__s.__current_ == __c_) {
-    __s.__do_ = __state::__accept_and_consume;
-    ++__s.__current_;
-    __s.__node_ = this->first();
-  } else {
-    __s.__do_   = __state::__reject;
-    __s.__node_ = nullptr;
-  }
-}
-
-// __match_char_icase
-
-template <class _CharT, class _Traits>
-class __match_char_icase : public __owns_one_state<_CharT> {
-  typedef __owns_one_state<_CharT> base;
-
-  _Traits __traits_;
-  _CharT __c_;
-
-public:
-  typedef std::__state<_CharT> __state;
-
-  _LIBCPP_HIDE_FROM_ABI __match_char_icase(const _Traits& __traits, _CharT __c, __node<_CharT>* __s)
-      : base(__s), __traits_(__traits), __c_(__traits.translate_nocase(__c)) {}
-
-  __match_char_icase(const __match_char_icase&)            = delete;
-  __match_char_icase& operator=(const __match_char_icase&) = delete;
-
-  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
-};
-
-template <class _CharT, class _Traits>
-void __match_char_icase<_CharT, _Traits>::__exec(__state& __s) const {
-  if (__s.__current_ != __s.__last_ && __traits_.translate_nocase(*__s.__current_) == __c_) {
-    __s.__do_ = __state::__accept_and_consume;
-    ++__s.__current_;
-    __s.__node_ = this->first();
-  } else {
-    __s.__do_   = __state::__reject;
-    __s.__node_ = nullptr;
-  }
-}
-
-// __match_char_collate
-
-template <class _CharT, class _Traits>
-class __match_char_collate : public __owns_one_state<_CharT> {
-  typedef __owns_one_state<_CharT> base;
-
-  _Traits __traits_;
-  _CharT __c_;
-
-public:
-  typedef std::__state<_CharT> __state;
-
-  _LIBCPP_HIDE_FROM_ABI __match_char_collate(const _Traits& __traits, _CharT __c, __node<_CharT>* __s)
-      : base(__s), __traits_(__traits), __c_(__traits.translate(__c)) {}
-
-  __match_char_collate(const __match_char_collate&)            = delete;
-  __match_char_collate& operator=(const __match_char_collate&) = delete;
-
-  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
-};
-
-template <class _CharT, class _Traits>
-void __match_char_collate<_CharT, _Traits>::__exec(__state& __s) const {
-  if (__s.__current_ != __s.__last_ && __traits_.translate(*__s.__current_) == __c_) {
-    __s.__do_ = __state::__accept_and_consume;
-    ++__s.__current_;
-    __s.__node_ = this->first();
-  } else {
-    __s.__do_   = __state::__reject;
-    __s.__node_ = nullptr;
-  }
-}
-
-// __bracket_expression
-
-template <class _CharT, class _Traits>
-class __bracket_expression : public __owns_one_state<_CharT> {
-  typedef __owns_one_state<_CharT> base;
-  typedef typename _Traits::string_type string_type;
-
-  _Traits __traits_;
-  vector<_CharT> __chars_;
-  vector<_CharT> __neg_chars_;
-  vector<pair<string_type, string_type> > __ranges_;
-  vector<pair<_CharT, _CharT> > __digraphs_;
-  vector<string_type> __equivalences_;
-  typename regex_traits<_CharT>::char_class_type __mask_;
-  typename regex_traits<_CharT>::char_class_type __neg_mask_;
-  bool __negate_;
-  bool __icase_;
-  bool __collate_;
-  bool __might_have_digraph_;
-
-public:
-  typedef std::__state<_CharT> __state;
-
-  _LIBCPP_HIDE_FROM_ABI
-  __bracket_expression(const _Traits& __traits, __node<_CharT>* __s, bool __negate, bool __icase, bool __collate)
-      : base(__s),
-        __traits_(__traits),
-        __mask_(),
-        __neg_mask_(),
-        __negate_(__negate),
-        __icase_(__icase),
-        __collate_(__collate),
-        __might_have_digraph_(__traits_.getloc().name() != "C") {}
-
-  __bracket_expression(const __bracket_expression&)            = delete;
-  __bracket_expression& operator=(const __bracket_expression&) = delete;
-
-  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
-
-  _LIBCPP_HIDE_FROM_ABI bool __negated() const { return __negate_; }
-
-  _LIBCPP_HIDE_FROM_ABI void __add_char(_CharT __c) {
-    if (__icase_)
-      __chars_.push_back(__traits_.translate_nocase(__c));
-    else if (__collate_)
-      __chars_.push_back(__traits_.translate(__c));
-    else
-      __chars_.push_back(__c);
-  }
-  _LIBCPP_HIDE_FROM_ABI void __add_neg_char(_CharT __c) {
-    if (__icase_)
-      __neg_chars_.push_back(__traits_.translate_nocase(__c));
-    else if (__collate_)
-      __neg_chars_.push_back(__traits_.translate(__c));
-    else
-      __neg_chars_.push_back(__c);
-  }
-  _LIBCPP_HIDE_FROM_ABI void __add_range(string_type __b, string_type __e) {
-    if (__collate_) {
-      if (__icase_) {
-        for (size_t __i = 0; __i < __b.size(); ++__i)
-          __b[__i] = __traits_.translate_nocase(__b[__i]);
-        for (size_t __i = 0; __i < __e.size(); ++__i)
-          __e[__i] = __traits_.translate_nocase(__e[__i]);
-      } else {
-        for (size_t __i = 0; __i < __b.size(); ++__i)
-          __b[__i] = __traits_.translate(__b[__i]);
-        for (size_t __i = 0; __i < __e.size(); ++__i)
-          __e[__i] = __traits_.translate(__e[__i]);
-      }
-      __ranges_.push_back(
-          std::make_pair(__traits_.transform(__b.begin(), __b.end()), __traits_.transform(__e.begin(), __e.end())));
-    } else {
-      if (__b.size() != 1 || __e.size() != 1 || char_traits<typename string_type::value_type>::lt(__e[0], __b[0]))
-        std::__throw_regex_error<regex_constants::error_range>();
-      if (__icase_) {
-        __b[0] = __traits_.translate_nocase(__b[0]);
-        __e[0] = __traits_.translate_nocase(__e[0]);
-      }
-      __ranges_.push_back(std::make_pair(std::move(__b), std::move(__e)));
-    }
-  }
-  _LIBCPP_HIDE_FROM_ABI void __add_digraph(_CharT __c1, _CharT __c2) {
-    if (__icase_)
-      __digraphs_.push_back(std::make_pair(__traits_.translate_nocase(__c1), __traits_.translate_nocase(__c2)));
-    else if (__collate_)
-      __digraphs_.push_back(std::make_pair(__traits_.translate(__c1), __traits_.translate(__c2)));
-    else
-      __digraphs_.push_back(std::make_pair(__c1, __c2));
-  }
-  _LIBCPP_HIDE_FROM_ABI void __add_equivalence(const string_type& __s) { __equivalences_.push_back(__s); }
-  _LIBCPP_HIDE_FROM_ABI void __add_class(typename regex_traits<_CharT>::char_class_type __mask) { __mask_ |= __mask; }
-  _LIBCPP_HIDE_FROM_ABI void __add_neg_class(typename regex_traits<_CharT>::char_class_type __mask) {
-    __neg_mask_ |= __mask;
-  }
-};
-
-template <class _CharT, class _Traits>
-void __bracket_expression<_CharT, _Traits>::__exec(__state& __s) const {
-  bool __found        = false;
-  unsigned __consumed = 0;
-  if (__s.__current_ != __s.__last_) {
-    ++__consumed;
-    if (__might_have_digraph_) {
-      const _CharT* __next = std::next(__s.__current_);
-      if (__next != __s.__last_) {
-        pair<_CharT, _CharT> __ch2(*__s.__current_, *__next);
-        if (__icase_) {
-          __ch2.first  = __traits_.translate_nocase(__ch2.first);
-          __ch2.second = __traits_.translate_nocase(__ch2.second);
-        } else if (__collate_) {
-          __ch2.first  = __traits_.translate(__ch2.first);
-          __ch2.second = __traits_.translate(__ch2.second);
-        }
-        if (!__traits_.lookup_collatename(std::addressof(__ch2.first), std::addressof(__ch2.first) + 2).empty()) {
-          // __ch2 is a digraph in this locale
-          ++__consumed;
-          for (size_t __i = 0; __i < __digraphs_.size(); ++__i) {
-            if (__ch2 == __digraphs_[__i]) {
-              __found = true;
-              goto __exit;
-            }
-          }
-          if (__collate_ && !__ranges_.empty()) {
-            string_type __s2 = __traits_.transform(std::addressof(__ch2.first), std::addressof(__ch2.first) + 2);
-            for (size_t __i = 0; __i < __ranges_.size(); ++__i) {
-              if (__ranges_[__i].first <= __s2 && __s2 <= __ranges_[__i].second) {
-                __found = true;
-                goto __exit;
-              }
-            }
-          }
-          if (!__equivalences_.empty()) {
-            string_type __s2 =
-                __traits_.transform_primary(std::addressof(__ch2.first), std::addressof(__ch2.first) + 2);
-            for (size_t __i = 0; __i < __equivalences_.size(); ++__i) {
-              if (__s2 == __equivalences_[__i]) {
-                __found = true;
-                goto __exit;
-              }
-            }
-          }
-          if (__traits_.isctype(__ch2.first, __mask_) && __traits_.isctype(__ch2.second, __mask_)) {
-            __found = true;
-            goto __exit;
-          }
-          if (!__traits_.isctype(__ch2.first, __neg_mask_) && !__traits_.isctype(__ch2.second, __neg_mask_)) {
-            __found = true;
-            goto __exit;
-          }
-          goto __exit;
-        }
-      }
-    }
-    // test *__s.__current_ as not a digraph
-    _CharT __ch = *__s.__current_;
-    if (__icase_)
-      __ch = __traits_.translate_nocase(__ch);
-    else if (__collate_)
-      __ch = __traits_.translate(__ch);
-    for (size_t __i = 0; __i < __chars_.size(); ++__i) {
-      if (__ch == __chars_[__i]) {
-        __found = true;
-        goto __exit;
-      }
-    }
-    // When there's at least one of __neg_chars_ and __neg_mask_, the set
-    // of "__found" chars is
-    //   union(complement(union(__neg_chars_, __neg_mask_)),
-    //         other cases...)
-    //
-    // It doesn't make sense to check this when there are no __neg_chars_
-    // and no __neg_mask_.
-    if (!(__neg_mask_ == 0 && __neg_chars_.empty())) {
-      const bool __in_neg_mask  = __traits_.isctype(__ch, __neg_mask_);
-      const bool __in_neg_chars = std::find(__neg_chars_.begin(), __neg_chars_.end(), __ch) != __neg_chars_.end();
-      if (!(__in_neg_mask || __in_neg_chars)) {
-        __found = true;
-        goto __exit;
-      }
-    }
-    if (!__ranges_.empty()) {
-      string_type __s2 =
-          __collate_ ? __traits_.transform(std::addressof(__ch), std::addressof(__ch) + 1) : string_type(1, __ch);
-      for (size_t __i = 0; __i < __ranges_.size(); ++__i) {
-        if (__ranges_[__i].first <= __s2 && __s2 <= __ranges_[__i].second) {
-          __found = true;
-          goto __exit;
-        }
-      }
-    }
-    if (!__equivalences_.empty()) {
-      string_type __s2 = __traits_.transform_primary(std::addressof(__ch), std::addressof(__ch) + 1);
-      for (size_t __i = 0; __i < __equivalences_.size(); ++__i) {
-        if (__s2 == __equivalences_[__i]) {
-          __found = true;
-          goto __exit;
-        }
-      }
-    }
-    if (__traits_.isctype(__ch, __mask_)) {
-      __found = true;
-      goto __exit;
-    }
-  } else
-    __found = __negate_; // force reject
-__exit:
-  if (__found != __negate_) {
-    __s.__do_ = __state::__accept_and_consume;
-    __s.__current_ += __consumed;
-    __s.__node_ = this->first();
-  } else {
-    __s.__do_   = __state::__reject;
-    __s.__node_ = nullptr;
-  }
-}
-
-template <class _CharT, class _Traits>
-class __lookahead;
-
-template <class _CharT, class _Traits = regex_traits<_CharT> >
-class basic_regex;
-
-typedef basic_regex<char> regex;
-#    if _LIBCPP_HAS_WIDE_CHARACTERS
-typedef basic_regex<wchar_t> wregex;
-#    endif
-
-template <class _CharT, class _Traits>
-class _LIBCPP_PREFERRED_NAME(regex) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wregex)) basic_regex {
-public:
-  // types:
-  typedef _CharT value_type;
-  typedef _Traits traits_type;
-  typedef typename _Traits::string_type string_type;
-  typedef regex_constants::syntax_option_type flag_type;
-  typedef typename _Traits::locale_type locale_type;
-
-private:
-  _Traits __traits_;
-  flag_type __flags_;
-  unsigned __marked_count_;
-  unsigned __loop_count_;
-  int __open_count_;
-  shared_ptr<__empty_state<_CharT> > __start_;
-  __owns_one_state<_CharT>* __end_;
-
-  typedef std::__state<_CharT> __state;
-  typedef std::__node<_CharT> __node;
-
-public:
-  // constants:
-  static const regex_constants::syntax_option_type icase      = regex_constants::icase;
-  static const regex_constants::syntax_option_type nosubs     = regex_constants::nosubs;
-  static const regex_constants::syntax_option_type optimize   = regex_constants::optimize;
-  static const regex_constants::syntax_option_type collate    = regex_constants::collate;
-  static const regex_constants::syntax_option_type ECMAScript = regex_constants::ECMAScript;
-  static const regex_constants::syntax_option_type basic      = regex_constants::basic;
-  static const regex_constants::syntax_option_type extended   = regex_constants::extended;
-  static const regex_constants::syntax_option_type awk        = regex_constants::awk;
-  static const regex_constants::syntax_option_type grep       = regex_constants::grep;
-  static const regex_constants::syntax_option_type egrep      = regex_constants::egrep;
-  static const regex_constants::syntax_option_type multiline  = regex_constants::multiline;
-
-  // construct/copy/destroy:
-  _LIBCPP_HIDE_FROM_ABI basic_regex()
-      : __flags_(regex_constants::ECMAScript),
-        __marked_count_(0),
-        __loop_count_(0),
-        __open_count_(0),
-        __end_(nullptr) {}
-  _LIBCPP_HIDE_FROM_ABI explicit basic_regex(const value_type* __p, flag_type __f = regex_constants::ECMAScript)
-      : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(nullptr) {
-    __init(__p, __p + __traits_.length(__p));
-  }
-
-  _LIBCPP_HIDE_FROM_ABI basic_regex(const value_type* __p, size_t __len, flag_type __f = regex_constants::ECMAScript)
-      : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(nullptr) {
-    __init(__p, __p + __len);
-  }
-
-  //     basic_regex(const basic_regex&) = default;
-  //     basic_regex(basic_regex&&) = default;
-  template <class _ST, class _SA>
-  _LIBCPP_HIDE_FROM_ABI explicit basic_regex(const basic_string<value_type, _ST, _SA>& __p,
-                                             flag_type __f = regex_constants::ECMAScript)
-      : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(nullptr) {
-    __init(__p.begin(), __p.end());
-  }
-
-  template <class _ForwardIterator>
-  _LIBCPP_HIDE_FROM_ABI
-  basic_regex(_ForwardIterator __first, _ForwardIterator __last, flag_type __f = regex_constants::ECMAScript)
-      : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(nullptr) {
-    __init(__first, __last);
-  }
-#    ifndef _LIBCPP_CXX03_LANG
-  _LIBCPP_HIDE_FROM_ABI basic_regex(initializer_list<value_type> __il, flag_type __f = regex_constants::ECMAScript)
-      : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(nullptr) {
-    __init(__il.begin(), __il.end());
-  }
-#    endif // _LIBCPP_CXX03_LANG
-
-  //    ~basic_regex() = default;
-
-  //     basic_regex& operator=(const basic_regex&) = default;
-  //     basic_regex& operator=(basic_regex&&) = default;
-  _LIBCPP_HIDE_FROM_ABI basic_regex& operator=(const value_type* __p) { return assign(__p); }
-#    ifndef _LIBCPP_CXX03_LANG
-  _LIBCPP_HIDE_FROM_ABI basic_regex& operator=(initializer_list<value_type> __il) { return assign(__il); }
-#    endif // _LIBCPP_CXX03_LANG
-  template <class _ST, class _SA>
-  _LIBCPP_HIDE_FROM_ABI basic_regex& operator=(const basic_string<value_type, _ST, _SA>& __p) {
-    return assign(__p);
-  }
-
-  // assign:
-  _LIBCPP_HIDE_FROM_ABI basic_regex& assign(const basic_regex& __that) { return *this = __that; }
-#    ifndef _LIBCPP_CXX03_LANG
-  _LIBCPP_HIDE_FROM_ABI basic_regex& assign(basic_regex&& __that) _NOEXCEPT { return *this = std::move(__that); }
-#    endif
-  _LIBCPP_HIDE_FROM_ABI basic_regex& assign(const value_type* __p, flag_type __f = regex_constants::ECMAScript) {
-    return assign(__p, __p + __traits_.length(__p), __f);
-  }
-  _LIBCPP_HIDE_FROM_ABI basic_regex&
-  assign(const value_type* __p, size_t __len, flag_type __f = regex_constants::ECMAScript) {
-    return assign(__p, __p + __len, __f);
-  }
-  template <class _ST, class _SA>
-  _LIBCPP_HIDE_FROM_ABI basic_regex&
-  assign(const basic_string<value_type, _ST, _SA>& __s, flag_type __f = regex_constants::ECMAScript) {
-    return assign(__s.begin(), __s.end(), __f);
-  }
-
-  template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
-  _LIBCPP_HIDE_FROM_ABI basic_regex&
-  assign(_InputIterator __first, _InputIterator __last, flag_type __f = regex_constants::ECMAScript) {
-    basic_string<_CharT> __t(__first, __last);
-    return assign(__t.begin(), __t.end(), __f);
-  }
-
-private:
-  _LIBCPP_HIDE_FROM_ABI void __member_init(flag_type __f) {
-    __flags_        = __f;
-    __marked_count_ = 0;
-    __loop_count_   = 0;
-    __open_count_   = 0;
-    __end_          = nullptr;
-  }
-
-public:
-  template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>
-  _LIBCPP_HIDE_FROM_ABI basic_regex&
-  assign(_ForwardIterator __first, _ForwardIterator __last, flag_type __f = regex_constants::ECMAScript) {
-    return assign(basic_regex(__first, __last, __f));
-  }
-
-#    ifndef _LIBCPP_CXX03_LANG
-
-  _LIBCPP_HIDE_FROM_ABI basic_regex&
-  assign(initializer_list<value_type> __il, flag_type __f = regex_constants::ECMAScript) {
-    return assign(__il.begin(), __il.end(), __f);
-  }
-
-#    endif // _LIBCPP_CXX03_LANG
-
-  // const operations:
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI unsigned mark_count() const { return __marked_count_; }
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI flag_type flags() const { return __flags_; }
-
-  // locale:
-  _LIBCPP_HIDE_FROM_ABI locale_type imbue(locale_type __loc) {
-    __member_init(ECMAScript);
-    __start_.reset();
-    return __traits_.imbue(__loc);
-  }
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI locale_type getloc() const { return __traits_.getloc(); }
-
-  // swap:
-  void swap(basic_regex& __r);
-
-private:
-  _LIBCPP_HIDE_FROM_ABI unsigned __loop_count() const { return __loop_count_; }
-
-  _LIBCPP_HIDE_FROM_ABI bool __use_multiline() const {
-    return __get_grammar(__flags_) == ECMAScript && (__flags_ & multiline);
-  }
-
-  template <class _ForwardIterator>
-  void __init(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_ERE_dupl_symbol(
-      _ForwardIterator __first,
-      _ForwardIterator __last,
-      __owns_one_state<_CharT>* __s,
-      unsigned __mexp_begin,
-      unsigned __mexp_end);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_bracket_expression(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
-  _ForwardIterator
-  __parse_follow_list(_ForwardIterator __first, _ForwardIterator __last, __bracket_expression<_CharT, _Traits>* __ml);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_expression_term(
-      _ForwardIterator __first, _ForwardIterator __last, __bracket_expression<_CharT, _Traits>* __ml);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_equivalence_class(
-      _ForwardIterator __first, _ForwardIterator __last, __bracket_expression<_CharT, _Traits>* __ml);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_character_class(
-      _ForwardIterator __first, _ForwardIterator __last, __bracket_expression<_CharT, _Traits>* __ml);
-  template <class _ForwardIterator>
-  _ForwardIterator
-  __parse_collating_symbol(_ForwardIterator __first, _ForwardIterator __last, basic_string<_CharT>& __col_sym);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_DUP_COUNT(_ForwardIterator __first, _ForwardIterator __last, int& __c);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_ecma_exp(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_alternative(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_term(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_assertion(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_atom(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_atom_escape(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_decimal_escape(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_character_class_escape(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
-  _ForwardIterator
-  __parse_character_escape(_ForwardIterator __first, _ForwardIterator __last, basic_string<_CharT>* __str = nullptr);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_pattern_character(_ForwardIterator __first, _ForwardIterator __last);
-  template <class _ForwardIterator>
-  _ForwardIterator __parse_class_escape(
-      _ForwardIterator __first,
-      _ForwardIterator __last,
-      basic_string<_CharT>& __str,
-      __bracket_expression<_CharT, _Traits>* __ml);
-  template <class _ForwardIterator>
-  _ForwardIterator
-  __parse_awk_escape(_ForwardIterator __first, _ForwardIterator __last, basic_string<_CharT>* __str = nullptr);
-
-  bool __test_back_ref(_CharT);
-
-  _LIBCPP_HIDE_FROM_ABI void __push_l_anchor();
-  void __push_r_anchor();
-  void __push_match_any();
-  void __push_match_any_but_newline();
-  _LIBCPP_HIDE_FROM_ABI void __push_greedy_inf_repeat(
-      size_t __min, __owns_one_state<_CharT>* __s, unsigned __mexp_begin = 0, unsigned __mexp_end = 0) {
-    __push_loop(__min, numeric_limits<size_t>::max(), __s, __mexp_begin, __mexp_end);
-  }
-  _LIBCPP_HIDE_FROM_ABI void __push_nongreedy_inf_repeat(
-      size_t __min, __owns_one_state<_CharT>* __s, unsigned __mexp_begin = 0, unsigned __mexp_end = 0) {
-    __push_loop(__min, numeric_limits<size_t>::max(), __s, __mexp_begin, __mexp_end, false);
-  }
-  void __push_loop(size_t __min,
-                   size_t __max,
-                   __owns_one_state<_CharT>* __s,
-                   size_t __mexp_begin = 0,
-                   size_t __mexp_end   = 0,
-                   bool __greedy       = true);
-  __bracket_expression<_CharT, _Traits>* __start_matching_list(bool __negate);
-  void __push_char(value_type __c);
-  void __push_back_ref(int __i);
-  void __push_alternation(__owns_one_state<_CharT>* __sa, __owns_one_state<_CharT>* __sb);
-  void __push_begin_marked_subexpression();
-  void __push_end_marked_subexpression(unsigned);
-  void __push_empty();
-  void __push_word_boundary(bool);
-  void __push_lookahead(const basic_regex&, bool, unsigned);
-
-  template <class _Allocator>
-  bool __search(const _CharT* __first,
-                const _CharT* __last,
-                match_results<const _CharT*, _Allocator>& __m,
-                regex_constants::match_flag_type __flags) const;
-
-  template <class _Allocator>
-  bool __match_at_start(
-      vector<__state>& __states,
-      const _CharT* __first,
-      const _CharT* __last,
-      match_results<const _CharT*, _Allocator>& __m,
-      regex_constants::match_flag_type __flags,
-      bool) const;
-  template <class _Allocator>
-  bool __match_at_start_ecma(
-      vector<__state>& __states,
-      const _CharT* __first,
-      const _CharT* __last,
-      match_results<const _CharT*, _Allocator>& __m,
-      regex_constants::match_flag_type __flags,
-      bool) const;
-  template <class _Allocator>
-  bool __match_at_start_posix_nosubs(
-      const _CharT* __first,
-      const _CharT* __last,
-      match_results<const _CharT*, _Allocator>& __m,
-      regex_constants::match_flag_type __flags,
-      bool) const;
-  template <class _Allocator>
-  bool __match_at_start_posix_subs(
-      vector<__state>& __states,
-      const _CharT* __first,
-      const _CharT* __last,
-      match_results<const _CharT*, _Allocator>& __m,
-      regex_constants::match_flag_type __flags,
-      bool) const;
-
-  template <class _Bp, class _Ap, class _Cp, class _Tp>
-  friend bool
-  regex_search(_Bp, _Bp, match_results<_Bp, _Ap>&, const basic_regex<_Cp, _Tp>&, regex_constants::match_flag_type);
-
-  template <class _Ap, class _Cp, class _Tp>
-  friend bool
-  regex_search(const _Cp*,
-               const _Cp*,
-               match_results<const _Cp*, _Ap>&,
-               const basic_regex<_Cp, _Tp>&,
-               regex_constants::match_flag_type);
-
-  template <class _Bp, class _Cp, class _Tp>
-  friend bool regex_search(_Bp, _Bp, const basic_regex<_Cp, _Tp>&, regex_constants::match_flag_type);
-
-  template <class _Cp, class _Tp>
-  friend bool regex_search(const _Cp*, const _Cp*, const basic_regex<_Cp, _Tp>&, regex_constants::match_flag_type);
-
-  template <class _Cp, class _Ap, class _Tp>
-  friend bool regex_search(
-      const _Cp*, match_results<const _Cp*, _Ap>&, const basic_regex<_Cp, _Tp>&, regex_constants::match_flag_type);
-
-  template <class _ST, class _SA, class _Cp, class _Tp>
-  friend bool regex_search(const basic_string<_Cp, _ST, _SA>& __s,
-                           const basic_regex<_Cp, _Tp>& __e,
-                           regex_constants::match_flag_type __flags);
-
-  template <class _ST, class _SA, class _Ap, class _Cp, class _Tp>
-  friend bool regex_search(const basic_string<_Cp, _ST, _SA>& __s,
-                           match_results<typename basic_string<_Cp, _ST, _SA>::const_iterator, _Ap>&,
-                           const basic_regex<_Cp, _Tp>& __e,
-                           regex_constants::match_flag_type __flags);
-
-  template <class _Iter, class _Ap, class _Cp, class _Tp>
-  friend bool
-  regex_search(__wrap_iter<_Iter> __first,
-               __wrap_iter<_Iter> __last,
-               match_results<__wrap_iter<_Iter>, _Ap>& __m,
-               const basic_regex<_Cp, _Tp>& __e,
-               regex_constants::match_flag_type __flags);
-
-  template <class, class>
-  friend class __lookahead;
-};
-
-#    if _LIBCPP_STD_VER >= 17
-template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>
-basic_regex(_ForwardIterator, _ForwardIterator, regex_constants::syntax_option_type = regex_constants::ECMAScript)
-    -> basic_regex<typename iterator_traits<_ForwardIterator>::value_type>;
-#    endif
-
-template <class _CharT, class _Traits>
-const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::icase;
-template <class _CharT, class _Traits>
-const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::nosubs;
-template <class _CharT, class _Traits>
-const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::optimize;
-template <class _CharT, class _Traits>
-const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::collate;
-template <class _CharT, class _Traits>
-const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::ECMAScript;
-template <class _CharT, class _Traits>
-const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::basic;
-template <class _CharT, class _Traits>
-const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::extended;
-template <class _CharT, class _Traits>
-const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::awk;
-template <class _CharT, class _Traits>
-const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::grep;
-template <class _CharT, class _Traits>
-const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::egrep;
-
-template <class _CharT, class _Traits>
-void basic_regex<_CharT, _Traits>::swap(basic_regex& __r) {
-  using std::swap;
-  swap(__traits_, __r.__traits_);
-  swap(__flags_, __r.__flags_);
-  swap(__marked_count_, __r.__marked_count_);
-  swap(__loop_count_, __r.__loop_count_);
-  swap(__open_count_, __r.__open_count_);
-  swap(__start_, __r.__start_);
-  swap(__end_, __r.__end_);
-}
-
-template <class _CharT, class _Traits>
-inline _LIBCPP_HIDE_FROM_ABI void swap(basic_regex<_CharT, _Traits>& __x, basic_regex<_CharT, _Traits>& __y) {
-  return __x.swap(__y);
-}
-
-// __lookahead
-
-template <class _CharT, class _Traits>
-class __lookahead : public __owns_one_state<_CharT> {
-  typedef __owns_one_state<_CharT> base;
-
-  basic_regex<_CharT, _Traits> __exp_;
-  unsigned __mexp_;
-  bool __invert_;
-
-public:
-  typedef std::__state<_CharT> __state;
-
-  _LIBCPP_HIDE_FROM_ABI
-  __lookahead(const basic_regex<_CharT, _Traits>& __exp, bool __invert, __node<_CharT>* __s, unsigned __mexp)
-      : base(__s), __exp_(__exp), __mexp_(__mexp), __invert_(__invert) {}
-
-  __lookahead(const __lookahead&)            = delete;
-  __lookahead& operator=(const __lookahead&) = delete;
-
-  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const;
-};
-
-template <class _CharT, class _Traits>
-void __lookahead<_CharT, _Traits>::__exec(__state& __s) const {
-  match_results<const _CharT*> __m;
-  __m.__init(1 + __exp_.mark_count(), __s.__current_, __s.__last_);
-  vector<__state> __states_buffer;
-  bool __matched = __exp_.__match_at_start_ecma(
-      __states_buffer,
-      __s.__current_,
-      __s.__last_,
-      __m,
-      (__s.__flags_ | regex_constants::match_continuous) & ~regex_constants::__full_match,
-      __s.__at_first_ && __s.__current_ == __s.__first_);
-  if (__matched != __invert_) {
-    __s.__do_   = __state::__accept_but_not_consume;
-    __s.__node_ = this->first();
-    for (unsigned __i = 1; __i < __m.size(); ++__i) {
-      __s.__sub_matches_[__mexp_ + __i - 1] = __m.__matches_[__i];
-    }
-  } else {
-    __s.__do_   = __state::__reject;
-    __s.__node_ = nullptr;
-  }
-}
-
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-void basic_regex<_CharT, _Traits>::__init(_ForwardIterator __first, _ForwardIterator __last) {
-  if (__get_grammar(__flags_) == 0)
-    __flags_ |= regex_constants::ECMAScript;
-  _ForwardIterator __temp = __parse(__first, __last);
-  if (__temp != __last)
-    std::__throw_regex_error<regex_constants::__re_err_parse>();
-}
-
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator basic_regex<_CharT, _Traits>::__parse(_ForwardIterator __first, _ForwardIterator __last) {
-  {
-    unique_ptr<__node> __h(new __end_state<_CharT>);
-    __start_.reset(new __empty_state<_CharT>(__h.get()));
-    __h.release();
-    __end_ = __start_.get();
-  }
-  switch (__get_grammar(__flags_)) {
-  case ECMAScript:
-    __first = __parse_ecma_exp(__first, __last);
-    break;
-  case basic:
-  case grep: {
-    __regex::__basic::__parser<_CharT, _Traits, _ForwardIterator> __parser(__first, __last, __traits_, flags());
-    if (__get_grammar(__flags_) == basic)
-      __parser.__parse_basic();
-    else
-      __parser.__parse_grep();
-    __end_->first() = new __interpreter_state<_CharT, _Traits>(__parser.__extract_interpreter(), __end_->first());
-    __end_          = static_cast<__owns_one_state<_CharT>*>(__end_->first());
-    __marked_count_ = __parser.mark_count();
-    return __last;
-  }
-  case awk:
-  case extended:
-  case egrep: {
-    __regex::__extended::__parser<_CharT, _Traits, _ForwardIterator> __parser(__first, __last, __traits_, flags());
-    if (auto __grammar = __get_grammar(__flags_); __grammar == extended || __grammar == awk)
-      __parser.__parse_extended();
-    else
-      __parser.__parse_egrep();
-    __end_->first() = new __interpreter_state<_CharT, _Traits>(__parser.__extract_interpreter(), __end_->first());
-    __end_          = static_cast<__owns_one_state<_CharT>*>(__end_->first());
-    __marked_count_ = __parser.mark_count();
-    return __last;
-  }
-  default:
-    std::__throw_regex_error<regex_constants::__re_err_grammar>();
-  }
-  return __first;
-}
-
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator basic_regex<_CharT, _Traits>::__parse_ERE_dupl_symbol(
-    _ForwardIterator __first,
-    _ForwardIterator __last,
-    __owns_one_state<_CharT>* __s,
-    unsigned __mexp_begin,
-    unsigned __mexp_end) {
-  if (__first != __last) {
-    unsigned __grammar = __get_grammar(__flags_);
-    switch (*__first) {
-    case '*':
-      ++__first;
-      if (__grammar == ECMAScript && __first != __last && *__first == '?') {
-        ++__first;
-        __push_nongreedy_inf_repeat(0, __s, __mexp_begin, __mexp_end);
-      } else
-        __push_greedy_inf_repeat(0, __s, __mexp_begin, __mexp_end);
-      break;
-    case '+':
-      ++__first;
-      if (__grammar == ECMAScript && __first != __last && *__first == '?') {
-        ++__first;
-        __push_nongreedy_inf_repeat(1, __s, __mexp_begin, __mexp_end);
-      } else
-        __push_greedy_inf_repeat(1, __s, __mexp_begin, __mexp_end);
-      break;
-    case '?':
-      ++__first;
-      if (__grammar == ECMAScript && __first != __last && *__first == '?') {
-        ++__first;
-        __push_loop(0, 1, __s, __mexp_begin, __mexp_end, false);
-      } else
-        __push_loop(0, 1, __s, __mexp_begin, __mexp_end);
-      break;
-    case '{': {
-      int __min;
-      _ForwardIterator __temp = __parse_DUP_COUNT(++__first, __last, __min);
-      if (__temp == __first)
-        std::__throw_regex_error<regex_constants::error_badbrace>();
-      __first = __temp;
-      if (__first == __last)
-        std::__throw_regex_error<regex_constants::error_brace>();
-      switch (*__first) {
-      case '}':
-        ++__first;
-        if (__grammar == ECMAScript && __first != __last && *__first == '?') {
-          ++__first;
-          __push_loop(__min, __min, __s, __mexp_begin, __mexp_end, false);
-        } else
-          __push_loop(__min, __min, __s, __mexp_begin, __mexp_end);
-        break;
-      case ',':
-        ++__first;
-        if (__first == __last)
-          std::__throw_regex_error<regex_constants::error_badbrace>();
-        if (*__first == '}') {
-          ++__first;
-          if (__grammar == ECMAScript && __first != __last && *__first == '?') {
-            ++__first;
-            __push_nongreedy_inf_repeat(__min, __s, __mexp_begin, __mexp_end);
-          } else
-            __push_greedy_inf_repeat(__min, __s, __mexp_begin, __mexp_end);
-        } else {
-          int __max = -1;
-          __temp    = __parse_DUP_COUNT(__first, __last, __max);
-          if (__temp == __first)
-            std::__throw_regex_error<regex_constants::error_brace>();
-          __first = __temp;
-          if (__first == __last || *__first != '}')
-            std::__throw_regex_error<regex_constants::error_brace>();
-          ++__first;
-          if (__max < __min)
-            std::__throw_regex_error<regex_constants::error_badbrace>();
-          if (__grammar == ECMAScript && __first != __last && *__first == '?') {
-            ++__first;
-            __push_loop(__min, __max, __s, __mexp_begin, __mexp_end, false);
-          } else
-            __push_loop(__min, __max, __s, __mexp_begin, __mexp_end);
-        }
-        break;
-      default:
-        std::__throw_regex_error<regex_constants::error_badbrace>();
-      }
-    } break;
-    }
-  }
-  return __first;
-}
-
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator
-basic_regex<_CharT, _Traits>::__parse_bracket_expression(_ForwardIterator __first, _ForwardIterator __last) {
-  if (__first != __last && *__first == '[') {
-    ++__first;
-    if (__first == __last)
-      std::__throw_regex_error<regex_constants::error_brack>();
-    bool __negate = false;
-    if (*__first == '^') {
-      ++__first;
-      __negate = true;
-    }
-    __bracket_expression<_CharT, _Traits>* __ml = __start_matching_list(__negate);
-    // __ml owned by *this
-    if (__first == __last)
-      std::__throw_regex_error<regex_constants::error_brack>();
-    if (__get_grammar(__flags_) != ECMAScript && *__first == ']') {
-      __ml->__add_char(']');
-      ++__first;
-    }
-    __first = __parse_follow_list(__first, __last, __ml);
-    if (__first == __last)
-      std::__throw_regex_error<regex_constants::error_brack>();
-    if (*__first == '-') {
-      __ml->__add_char('-');
-      ++__first;
-    }
-    if (__first == __last || *__first != ']')
-      std::__throw_regex_error<regex_constants::error_brack>();
-    ++__first;
-  }
-  return __first;
-}
-
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator basic_regex<_CharT, _Traits>::__parse_follow_list(
-    _ForwardIterator __first, _ForwardIterator __last, __bracket_expression<_CharT, _Traits>* __ml) {
-  if (__first != __last) {
-    while (true) {
-      _ForwardIterator __temp = __parse_expression_term(__first, __last, __ml);
-      if (__temp == __first)
-        break;
-      __first = __temp;
-    }
-  }
-  return __first;
-}
-
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator basic_regex<_CharT, _Traits>::__parse_expression_term(
-    _ForwardIterator __first, _ForwardIterator __last, __bracket_expression<_CharT, _Traits>* __ml) {
-  if (__first != __last && *__first != ']') {
-    _ForwardIterator __temp = std::next(__first);
-    basic_string<_CharT> __start_range;
-    if (__temp != __last && *__first == '[') {
-      if (*__temp == '=')
-        return __parse_equivalence_class(++__temp, __last, __ml);
-      else if (*__temp == ':')
-        return __parse_character_class(++__temp, __last, __ml);
-      else if (*__temp == '.')
-        __first = __parse_collating_symbol(++__temp, __last, __start_range);
-    }
-    unsigned __grammar = __get_grammar(__flags_);
-    if (__start_range.empty()) {
-      if ((__grammar == ECMAScript || __grammar == awk) && *__first == '\\') {
-        if (__grammar == ECMAScript)
-          __first = __parse_class_escape(++__first, __last, __start_range, __ml);
-        else
-          __first = __parse_awk_escape(++__first, __last, std::addressof(__start_range));
-      } else {
-        __start_range = *__first;
-        ++__first;
-      }
-    }
-    if (__first != __last && *__first != ']') {
-      __temp = std::next(__first);
-      if (__temp != __last && *__first == '-' && *__temp != ']') {
-        // parse a range
-        basic_string<_CharT> __end_range;
-        __first = __temp;
-        ++__temp;
-        if (__temp != __last && *__first == '[' && *__temp == '.')
-          __first = __parse_collating_symbol(++__temp, __last, __end_range);
-        else {
-          if ((__grammar == ECMAScript || __grammar == awk) && *__first == '\\') {
-            if (__grammar == ECMAScript)
-              __first = __parse_class_escape(++__first, __last, __end_range, __ml);
-            else
-              __first = __parse_awk_escape(++__first, __last, std::addressof(__end_range));
-          } else {
-            __end_range = *__first;
-            ++__first;
-          }
-        }
-        __ml->__add_range(std::move(__start_range), std::move(__end_range));
-      } else if (!__start_range.empty()) {
-        if (__start_range.size() == 1)
-          __ml->__add_char(__start_range[0]);
-        else
-          __ml->__add_digraph(__start_range[0], __start_range[1]);
-      }
-    } else if (!__start_range.empty()) {
-      if (__start_range.size() == 1)
-        __ml->__add_char(__start_range[0]);
-      else
-        __ml->__add_digraph(__start_range[0], __start_range[1]);
-    }
-  }
-  return __first;
-}
-
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator basic_regex<_CharT, _Traits>::__parse_class_escape(
-    _ForwardIterator __first,
-    _ForwardIterator __last,
-    basic_string<_CharT>& __str,
-    __bracket_expression<_CharT, _Traits>* __ml) {
-  if (__first == __last)
-    std::__throw_regex_error<regex_constants::error_escape>();
-  switch (*__first) {
-  case 0:
-    __str = *__first;
-    return ++__first;
-  case 'b':
-    __str = _CharT(8);
-    return ++__first;
-  case 'd':
-    __ml->__add_class(ctype_base::digit);
-    return ++__first;
-  case 'D':
-    __ml->__add_neg_class(ctype_base::digit);
-    return ++__first;
-  case 's':
-    __ml->__add_class(ctype_base::space);
-    return ++__first;
-  case 'S':
-    __ml->__add_neg_class(ctype_base::space);
-    return ++__first;
-  case 'w':
-    __ml->__add_class(ctype_base::alnum);
-    __ml->__add_char('_');
-    return ++__first;
-  case 'W':
-    __ml->__add_neg_class(ctype_base::alnum);
-    __ml->__add_neg_char('_');
-    return ++__first;
-  }
-  __first = __parse_character_escape(__first, __last, std::addressof(__str));
-  return __first;
-}
-
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator basic_regex<_CharT, _Traits>::__parse_awk_escape(
-    _ForwardIterator __first, _ForwardIterator __last, basic_string<_CharT>* __str) {
-  if (__first == __last)
-    std::__throw_regex_error<regex_constants::error_escape>();
-  switch (*__first) {
-  case '\\':
-  case '"':
-  case '/':
-    if (__str)
-      *__str = *__first;
-    else
-      __push_char(*__first);
-    return ++__first;
-  case 'a':
-    if (__str)
-      *__str = _CharT(7);
-    else
-      __push_char(_CharT(7));
-    return ++__first;
-  case 'b':
-    if (__str)
-      *__str = _CharT(8);
-    else
-      __push_char(_CharT(8));
-    return ++__first;
-  case 'f':
-    if (__str)
-      *__str = _CharT(0xC);
-    else
-      __push_char(_CharT(0xC));
-    return ++__first;
-  case 'n':
-    if (__str)
-      *__str = _CharT(0xA);
-    else
-      __push_char(_CharT(0xA));
-    return ++__first;
-  case 'r':
-    if (__str)
-      *__str = _CharT(0xD);
-    else
-      __push_char(_CharT(0xD));
-    return ++__first;
-  case 't':
-    if (__str)
-      *__str = _CharT(0x9);
-    else
-      __push_char(_CharT(0x9));
-    return ++__first;
-  case 'v':
-    if (__str)
-      *__str = _CharT(0xB);
-    else
-      __push_char(_CharT(0xB));
-    return ++__first;
-  }
-  if ('0' <= *__first && *__first <= '7') {
-    unsigned __val = *__first - '0';
-    if (++__first != __last && ('0' <= *__first && *__first <= '7')) {
-      __val = 8 * __val + *__first - '0';
-      if (++__first != __last && ('0' <= *__first && *__first <= '7'))
-        __val = 8 * __val + *__first++ - '0';
-    }
-    if (__str)
-      *__str = _CharT(__val);
-    else
-      __push_char(_CharT(__val));
-  } else
-    std::__throw_regex_error<regex_constants::error_escape>();
-  return __first;
-}
-
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator basic_regex<_CharT, _Traits>::__parse_equivalence_class(
-    _ForwardIterator __first, _ForwardIterator __last, __bracket_expression<_CharT, _Traits>* __ml) {
-  // Found [=
-  //   This means =] must exist
-  value_type __equal_close[2] = {'=', ']'};
-  _ForwardIterator __temp     = std::search(__first, __last, __equal_close, __equal_close + 2);
-  if (__temp == __last)
-    std::__throw_regex_error<regex_constants::error_brack>();
-  // [__first, __temp) contains all text in [= ... =]
-  string_type __collate_name = __traits_.lookup_collatename(__first, __temp);
-  if (__collate_name.empty())
-    std::__throw_regex_error<regex_constants::error_collate>();
-  string_type __equiv_name = __traits_.transform_primary(__collate_name.begin(), __collate_name.end());
-  if (!__equiv_name.empty())
-    __ml->__add_equivalence(__equiv_name);
-  else {
-    switch (__collate_name.size()) {
-    case 1:
-      __ml->__add_char(__collate_name[0]);
-      break;
-    case 2:
-      __ml->__add_digraph(__collate_name[0], __collate_name[1]);
-      break;
-    default:
-      std::__throw_regex_error<regex_constants::error_collate>();
-    }
-  }
-  __first = std::next(__temp, 2);
-  return __first;
-}
-
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator basic_regex<_CharT, _Traits>::__parse_character_class(
-    _ForwardIterator __first, _ForwardIterator __last, __bracket_expression<_CharT, _Traits>* __ml) {
-  // Found [:
-  //   This means :] must exist
-  value_type __colon_close[2] = {':', ']'};
-  _ForwardIterator __temp     = std::search(__first, __last, __colon_close, __colon_close + 2);
-  if (__temp == __last)
-    std::__throw_regex_error<regex_constants::error_brack>();
-  // [__first, __temp) contains all text in [: ... :]
-  typedef typename _Traits::char_class_type char_class_type;
-  char_class_type __class_type = __traits_.lookup_classname(__first, __temp, __flags_ & icase);
-  if (__class_type == 0)
-    std::__throw_regex_error<regex_constants::error_ctype>();
-  __ml->__add_class(__class_type);
-  __first = std::next(__temp, 2);
-  return __first;
-}
-
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator basic_regex<_CharT, _Traits>::__parse_collating_symbol(
-    _ForwardIterator __first, _ForwardIterator __last, basic_string<_CharT>& __col_sym) {
-  // Found [.
-  //   This means .] must exist
-  value_type __dot_close[2] = {'.', ']'};
-  _ForwardIterator __temp   = std::search(__first, __last, __dot_close, __dot_close + 2);
-  if (__temp == __last)
-    std::__throw_regex_error<regex_constants::error_brack>();
-  // [__first, __temp) contains all text in [. ... .]
-  __col_sym = __traits_.lookup_collatename(__first, __temp);
-  switch (__col_sym.size()) {
-  case 1:
-  case 2:
-    break;
-  default:
-    std::__throw_regex_error<regex_constants::error_collate>();
-  }
-  __first = std::next(__temp, 2);
-  return __first;
-}
-
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator
-basic_regex<_CharT, _Traits>::__parse_DUP_COUNT(_ForwardIterator __first, _ForwardIterator __last, int& __c) {
-  if (__first != __last) {
-    int __val = __traits_.value(*__first, 10);
-    if (__val != -1) {
-      __c = __val;
-      for (++__first; __first != __last && (__val = __traits_.value(*__first, 10)) != -1; ++__first) {
-        if (__c >= numeric_limits<int>::max() / 10)
-          std::__throw_regex_error<regex_constants::error_badbrace>();
-        __c *= 10;
-        __c += __val;
-      }
-    }
-  }
-  return __first;
-}
+  // swap:
+  void swap(basic_regex& __r);
 
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator basic_regex<_CharT, _Traits>::__parse_ecma_exp(_ForwardIterator __first, _ForwardIterator __last) {
-  __owns_one_state<_CharT>* __sa = __end_;
-  _ForwardIterator __temp        = __parse_alternative(__first, __last);
-  if (__temp == __first)
-    __push_empty();
-  __first = __temp;
-  while (__first != __last && *__first == '|') {
-    __owns_one_state<_CharT>* __sb = __end_;
-    __temp                         = __parse_alternative(++__first, __last);
-    if (__temp == __first)
-      __push_empty();
-    __push_alternation(__sa, __sb);
-    __first = __temp;
-  }
-  return __first;
-}
+private:
+  _LIBCPP_HIDE_FROM_ABI unsigned __loop_count() const { return __loop_count_; }
 
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator basic_regex<_CharT, _Traits>::__parse_alternative(_ForwardIterator __first, _ForwardIterator __last) {
-  while (true) {
-    _ForwardIterator __temp = __parse_term(__first, __last);
-    if (__temp == __first)
-      break;
-    __first = __temp;
-  }
-  return __first;
-}
+  template <class _ForwardIterator>
+  void __init(_ForwardIterator __first, _ForwardIterator __last);
+  template <class _ForwardIterator>
+  _ForwardIterator __parse(_ForwardIterator __first, _ForwardIterator __last);
 
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator basic_regex<_CharT, _Traits>::__parse_term(_ForwardIterator __first, _ForwardIterator __last) {
-  _ForwardIterator __temp = __parse_assertion(__first, __last);
-  if (__temp == __first) {
-    __owns_one_state<_CharT>* __e = __end_;
-    unsigned __mexp_begin         = __marked_count_;
-    __temp                        = __parse_atom(__first, __last);
-    if (__temp != __first)
-      __first = __parse_ERE_dupl_symbol(__temp, __last, __e, __mexp_begin + 1, __marked_count_ + 1);
-  } else
-    __first = __temp;
-  return __first;
-}
+  template <class _Allocator>
+  bool __search(const _CharT* __first,
+                const _CharT* __last,
+                match_results<const _CharT*, _Allocator>& __m,
+                regex_constants::match_flag_type __flags) const;
 
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator basic_regex<_CharT, _Traits>::__parse_assertion(_ForwardIterator __first, _ForwardIterator __last) {
-  if (__first != __last) {
-    switch (*__first) {
-    case '^':
-      __push_l_anchor();
-      ++__first;
-      break;
-    case '$':
-      __push_r_anchor();
-      ++__first;
-      break;
-    case '\\': {
-      _ForwardIterator __temp = std::next(__first);
-      if (__temp != __last) {
-        if (*__temp == 'b') {
-          __push_word_boundary(false);
-          __first = ++__temp;
-        } else if (*__temp == 'B') {
-          __push_word_boundary(true);
-          __first = ++__temp;
-        }
-      }
-    } break;
-    case '(': {
-      _ForwardIterator __temp = std::next(__first);
-      if (__temp != __last && *__temp == '?') {
-        if (++__temp != __last) {
-          switch (*__temp) {
-          case '=': {
-            basic_regex __exp;
-            __exp.__flags_  = __flags_;
-            __temp          = __exp.__parse(++__temp, __last);
-            unsigned __mexp = __exp.__marked_count_;
-            __push_lookahead(std::move(__exp), false, __marked_count_);
-            __marked_count_ += __mexp;
-            if (__temp == __last || *__temp != ')')
-              std::__throw_regex_error<regex_constants::error_paren>();
-            __first = ++__temp;
-          } break;
-          case '!': {
-            basic_regex __exp;
-            __exp.__flags_  = __flags_;
-            __temp          = __exp.__parse(++__temp, __last);
-            unsigned __mexp = __exp.__marked_count_;
-            __push_lookahead(std::move(__exp), true, __marked_count_);
-            __marked_count_ += __mexp;
-            if (__temp == __last || *__temp != ')')
-              std::__throw_regex_error<regex_constants::error_paren>();
-            __first = ++__temp;
-          } break;
-          }
-        }
-      }
-    } break;
-    }
-  }
-  return __first;
-}
+  template <class _Allocator>
+  bool __match_at_start(
+      vector<__state>& __states,
+      const _CharT* __first,
+      const _CharT* __last,
+      match_results<const _CharT*, _Allocator>& __m,
+      regex_constants::match_flag_type __flags,
+      bool,
+      __interpreter_state<_CharT, _Traits>*) const;
+  template <class _Allocator>
+  bool __match_at_start_ecma(
+      vector<__state>& __states,
+      const _CharT* __first,
+      const _CharT* __last,
+      match_results<const _CharT*, _Allocator>& __m,
+      regex_constants::match_flag_type __flags,
+      bool) const;
+  template <class _Allocator>
+  bool __match_at_start_posix_nosubs(
+      const _CharT* __first,
+      const _CharT* __last,
+      match_results<const _CharT*, _Allocator>& __m,
+      regex_constants::match_flag_type __flags,
+      bool) const;
+  template <class _Allocator>
+  bool __match_at_start_posix_subs(
+      vector<__state>& __states,
+      const _CharT* __first,
+      const _CharT* __last,
+      match_results<const _CharT*, _Allocator>& __m,
+      regex_constants::match_flag_type __flags,
+      bool) const;
 
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator basic_regex<_CharT, _Traits>::__parse_atom(_ForwardIterator __first, _ForwardIterator __last) {
-  if (__first != __last) {
-    switch (*__first) {
-    case '.':
-      __push_match_any_but_newline();
-      ++__first;
-      break;
-    case '\\':
-      __first = __parse_atom_escape(__first, __last);
-      break;
-    case '[':
-      __first = __parse_bracket_expression(__first, __last);
-      break;
-    case '(': {
-      ++__first;
-      if (__first == __last)
-        std::__throw_regex_error<regex_constants::error_paren>();
-      _ForwardIterator __temp = std::next(__first);
-      if (__temp != __last && *__first == '?' && *__temp == ':') {
-        ++__open_count_;
-        __first = __parse_ecma_exp(++__temp, __last);
-        if (__first == __last || *__first != ')')
-          std::__throw_regex_error<regex_constants::error_paren>();
-        --__open_count_;
-        ++__first;
-      } else {
-        __push_begin_marked_subexpression();
-        unsigned __temp_count = __marked_count_;
-        ++__open_count_;
-        __first = __parse_ecma_exp(__first, __last);
-        if (__first == __last || *__first != ')')
-          std::__throw_regex_error<regex_constants::error_paren>();
-        __push_end_marked_subexpression(__temp_count);
-        --__open_count_;
-        ++__first;
-      }
-    } break;
-    case '*':
-    case '+':
-    case '?':
-    case '{':
-      std::__throw_regex_error<regex_constants::error_badrepeat>();
-      break;
-    default:
-      __first = __parse_pattern_character(__first, __last);
-      break;
-    }
-  }
-  return __first;
-}
+  template <class _Bp, class _Ap, class _Cp, class _Tp>
+  friend bool
+  regex_search(_Bp, _Bp, match_results<_Bp, _Ap>&, const basic_regex<_Cp, _Tp>&, regex_constants::match_flag_type);
 
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator basic_regex<_CharT, _Traits>::__parse_atom_escape(_ForwardIterator __first, _ForwardIterator __last) {
-  if (__first != __last && *__first == '\\') {
-    _ForwardIterator __t1 = std::next(__first);
-    if (__t1 == __last)
-      std::__throw_regex_error<regex_constants::error_escape>();
-
-    _ForwardIterator __t2 = __parse_decimal_escape(__t1, __last);
-    if (__t2 != __t1)
-      __first = __t2;
-    else {
-      __t2 = __parse_character_class_escape(__t1, __last);
-      if (__t2 != __t1)
-        __first = __t2;
-      else {
-        __t2 = __parse_character_escape(__t1, __last);
-        if (__t2 != __t1)
-          __first = __t2;
-      }
-    }
-  }
-  return __first;
-}
+  template <class _Ap, class _Cp, class _Tp>
+  friend bool
+  regex_search(const _Cp*,
+               const _Cp*,
+               match_results<const _Cp*, _Ap>&,
+               const basic_regex<_Cp, _Tp>&,
+               regex_constants::match_flag_type);
 
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator
-basic_regex<_CharT, _Traits>::__parse_decimal_escape(_ForwardIterator __first, _ForwardIterator __last) {
-  if (__first != __last) {
-    if (*__first == '0') {
-      __push_char(_CharT());
-      ++__first;
-    } else if ('1' <= *__first && *__first <= '9') {
-      unsigned __v = *__first - '0';
-      for (++__first; __first != __last && '0' <= *__first && *__first <= '9'; ++__first) {
-        if (__v >= numeric_limits<unsigned>::max() / 10)
-          std::__throw_regex_error<regex_constants::error_backref>();
-        __v = 10 * __v + *__first - '0';
-      }
-      if (__v == 0 || __v > mark_count())
-        std::__throw_regex_error<regex_constants::error_backref>();
-      __push_back_ref(__v);
-    }
-  }
-  return __first;
-}
+  template <class _Bp, class _Cp, class _Tp>
+  friend bool regex_search(_Bp, _Bp, const basic_regex<_Cp, _Tp>&, regex_constants::match_flag_type);
 
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator
-basic_regex<_CharT, _Traits>::__parse_character_class_escape(_ForwardIterator __first, _ForwardIterator __last) {
-  if (__first != __last) {
-    __bracket_expression<_CharT, _Traits>* __ml;
-    switch (*__first) {
-    case 'd':
-      __ml = __start_matching_list(false);
-      __ml->__add_class(ctype_base::digit);
-      ++__first;
-      break;
-    case 'D':
-      __ml = __start_matching_list(true);
-      __ml->__add_class(ctype_base::digit);
-      ++__first;
-      break;
-    case 's':
-      __ml = __start_matching_list(false);
-      __ml->__add_class(ctype_base::space);
-      ++__first;
-      break;
-    case 'S':
-      __ml = __start_matching_list(true);
-      __ml->__add_class(ctype_base::space);
-      ++__first;
-      break;
-    case 'w':
-      __ml = __start_matching_list(false);
-      __ml->__add_class(ctype_base::alnum);
-      __ml->__add_char('_');
-      ++__first;
-      break;
-    case 'W':
-      __ml = __start_matching_list(true);
-      __ml->__add_class(ctype_base::alnum);
-      __ml->__add_char('_');
-      ++__first;
-      break;
-    }
-  }
-  return __first;
-}
+  template <class _Cp, class _Tp>
+  friend bool regex_search(const _Cp*, const _Cp*, const basic_regex<_Cp, _Tp>&, regex_constants::match_flag_type);
 
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator basic_regex<_CharT, _Traits>::__parse_character_escape(
-    _ForwardIterator __first, _ForwardIterator __last, basic_string<_CharT>* __str) {
-  if (__first != __last) {
-    _ForwardIterator __t;
-    unsigned __sum = 0;
-    int __hd;
-    switch (*__first) {
-    case 'f':
-      if (__str)
-        *__str = _CharT(0xC);
-      else
-        __push_char(_CharT(0xC));
-      ++__first;
-      break;
-    case 'n':
-      if (__str)
-        *__str = _CharT(0xA);
-      else
-        __push_char(_CharT(0xA));
-      ++__first;
-      break;
-    case 'r':
-      if (__str)
-        *__str = _CharT(0xD);
-      else
-        __push_char(_CharT(0xD));
-      ++__first;
-      break;
-    case 't':
-      if (__str)
-        *__str = _CharT(0x9);
-      else
-        __push_char(_CharT(0x9));
-      ++__first;
-      break;
-    case 'v':
-      if (__str)
-        *__str = _CharT(0xB);
-      else
-        __push_char(_CharT(0xB));
-      ++__first;
-      break;
-    case 'c':
-      if ((__t = std::next(__first)) != __last) {
-        if (('A' <= *__t && *__t <= 'Z') || ('a' <= *__t && *__t <= 'z')) {
-          if (__str)
-            *__str = _CharT(*__t % 32);
-          else
-            __push_char(_CharT(*__t % 32));
-          __first = ++__t;
-        } else
-          std::__throw_regex_error<regex_constants::error_escape>();
-      } else
-        std::__throw_regex_error<regex_constants::error_escape>();
-      break;
-    case 'u':
-      ++__first;
-      if (__first == __last)
-        std::__throw_regex_error<regex_constants::error_escape>();
-      __hd = __traits_.value(*__first, 16);
-      if (__hd == -1)
-        std::__throw_regex_error<regex_constants::error_escape>();
-      __sum = 16 * __sum + static_cast<unsigned>(__hd);
-      ++__first;
-      if (__first == __last)
-        std::__throw_regex_error<regex_constants::error_escape>();
-      __hd = __traits_.value(*__first, 16);
-      if (__hd == -1)
-        std::__throw_regex_error<regex_constants::error_escape>();
-      __sum = 16 * __sum + static_cast<unsigned>(__hd);
-      [[__fallthrough__]];
-    case 'x':
-      ++__first;
-      if (__first == __last)
-        std::__throw_regex_error<regex_constants::error_escape>();
-      __hd = __traits_.value(*__first, 16);
-      if (__hd == -1)
-        std::__throw_regex_error<regex_constants::error_escape>();
-      __sum = 16 * __sum + static_cast<unsigned>(__hd);
-      ++__first;
-      if (__first == __last)
-        std::__throw_regex_error<regex_constants::error_escape>();
-      __hd = __traits_.value(*__first, 16);
-      if (__hd == -1)
-        std::__throw_regex_error<regex_constants::error_escape>();
-      __sum = 16 * __sum + static_cast<unsigned>(__hd);
-      if (__str)
-        *__str = _CharT(__sum);
-      else
-        __push_char(_CharT(__sum));
-      ++__first;
-      break;
-    case '0':
-      if (__str)
-        *__str = _CharT(0);
-      else
-        __push_char(_CharT(0));
-      ++__first;
-      break;
-    default:
-      if (!__traits_.isctype(*__first, ctype_base::alnum)) {
-        if (__str)
-          *__str = *__first;
-        else
-          __push_char(*__first);
-        ++__first;
-      } else
-        std::__throw_regex_error<regex_constants::error_escape>();
-      break;
-    }
-  }
-  return __first;
-}
+  template <class _Cp, class _Ap, class _Tp>
+  friend bool regex_search(
+      const _Cp*, match_results<const _Cp*, _Ap>&, const basic_regex<_Cp, _Tp>&, regex_constants::match_flag_type);
 
-template <class _CharT, class _Traits>
-template <class _ForwardIterator>
-_ForwardIterator
-basic_regex<_CharT, _Traits>::__parse_pattern_character(_ForwardIterator __first, _ForwardIterator __last) {
-  if (__first != __last) {
-    switch (*__first) {
-    case '^':
-    case '$':
-    case '\\':
-    case '.':
-    case '*':
-    case '+':
-    case '?':
-    case '(':
-    case ')':
-    case '[':
-    case ']':
-    case '{':
-    case '}':
-    case '|':
-      break;
-    default:
-      __push_char(*__first);
-      ++__first;
-      break;
-    }
-  }
-  return __first;
-}
+  template <class _ST, class _SA, class _Cp, class _Tp>
+  friend bool regex_search(const basic_string<_Cp, _ST, _SA>& __s,
+                           const basic_regex<_Cp, _Tp>& __e,
+                           regex_constants::match_flag_type __flags);
 
-template <class _CharT, class _Traits>
-bool basic_regex<_CharT, _Traits>::__test_back_ref(_CharT __c) {
-  unsigned __val = __traits_.value(__c, 10);
-  if (__val >= 1 && __val <= 9) {
-    if (__val > mark_count())
-      std::__throw_regex_error<regex_constants::error_backref>();
-    __push_back_ref(__val);
-    return true;
-  }
+  template <class _ST, class _SA, class _Ap, class _Cp, class _Tp>
+  friend bool regex_search(const basic_string<_Cp, _ST, _SA>& __s,
+                           match_results<typename basic_string<_Cp, _ST, _SA>::const_iterator, _Ap>&,
+                           const basic_regex<_Cp, _Tp>& __e,
+                           regex_constants::match_flag_type __flags);
 
-  return false;
-}
+  template <class _Iter, class _Ap, class _Cp, class _Tp>
+  friend bool
+  regex_search(__wrap_iter<_Iter> __first,
+               __wrap_iter<_Iter> __last,
+               match_results<__wrap_iter<_Iter>, _Ap>& __m,
+               const basic_regex<_Cp, _Tp>& __e,
+               regex_constants::match_flag_type __flags);
+};
 
-template <class _CharT, class _Traits>
-void basic_regex<_CharT, _Traits>::__push_loop(
-    size_t __min, size_t __max, __owns_one_state<_CharT>* __s, size_t __mexp_begin, size_t __mexp_end, bool __greedy) {
-  unique_ptr<__empty_state<_CharT> > __e1(new __empty_state<_CharT>(__end_->first()));
-  __end_->first() = nullptr;
-  unique_ptr<__loop<_CharT> > __e2(
-      new __loop<_CharT>(__loop_count_, __s->first(), __e1.get(), __mexp_begin, __mexp_end, __greedy, __min, __max));
-  __s->first() = nullptr;
-  __e1.release();
-  __end_->first() = new __repeat_one_loop<_CharT>(__e2.get());
-  __end_          = __e2->second();
-  __s->first()    = __e2.release();
-  ++__loop_count_;
-}
+#    if _LIBCPP_STD_VER >= 17
+template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>
+basic_regex(_ForwardIterator, _ForwardIterator, regex_constants::syntax_option_type = regex_constants::ECMAScript)
+    -> basic_regex<typename iterator_traits<_ForwardIterator>::value_type>;
+#    endif
 
 template <class _CharT, class _Traits>
-void basic_regex<_CharT, _Traits>::__push_char(value_type __c) {
-  if (flags() & icase)
-    __end_->first() = new __match_char_icase<_CharT, _Traits>(__traits_, __c, __end_->first());
-  else if (flags() & collate)
-    __end_->first() = new __match_char_collate<_CharT, _Traits>(__traits_, __c, __end_->first());
-  else
-    __end_->first() = new __match_char<_CharT>(__c, __end_->first());
-  __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
-}
-
+const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::icase;
 template <class _CharT, class _Traits>
-void basic_regex<_CharT, _Traits>::__push_begin_marked_subexpression() {
-  if (!(__flags_ & nosubs)) {
-    __end_->first() = new __begin_marked_subexpression<_CharT>(++__marked_count_, __end_->first());
-    __end_          = static_cast<__owns_one_state<_CharT>*>(__end_->first());
-  }
-}
-
+const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::nosubs;
 template <class _CharT, class _Traits>
-void basic_regex<_CharT, _Traits>::__push_end_marked_subexpression(unsigned __sub) {
-  if (!(__flags_ & nosubs)) {
-    __end_->first() = new __end_marked_subexpression<_CharT>(__sub, __end_->first());
-    __end_          = static_cast<__owns_one_state<_CharT>*>(__end_->first());
-  }
-}
-
+const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::optimize;
 template <class _CharT, class _Traits>
-void basic_regex<_CharT, _Traits>::__push_l_anchor() {
-  __end_->first() = new __l_anchor_multiline<_CharT>(__use_multiline(), __end_->first());
-  __end_          = static_cast<__owns_one_state<_CharT>*>(__end_->first());
-}
-
+const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::collate;
 template <class _CharT, class _Traits>
-void basic_regex<_CharT, _Traits>::__push_r_anchor() {
-  __end_->first() = new __r_anchor_multiline<_CharT>(__use_multiline(), __end_->first());
-  __end_          = static_cast<__owns_one_state<_CharT>*>(__end_->first());
-}
-
+const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::ECMAScript;
 template <class _CharT, class _Traits>
-void basic_regex<_CharT, _Traits>::__push_match_any() {
-  __end_->first() = new __match_any<_CharT>(__end_->first());
-  __end_          = static_cast<__owns_one_state<_CharT>*>(__end_->first());
-}
-
+const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::basic;
 template <class _CharT, class _Traits>
-void basic_regex<_CharT, _Traits>::__push_match_any_but_newline() {
-  __end_->first() = new __match_any_but_newline<_CharT>(__end_->first());
-  __end_          = static_cast<__owns_one_state<_CharT>*>(__end_->first());
-}
-
+const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::extended;
 template <class _CharT, class _Traits>
-void basic_regex<_CharT, _Traits>::__push_empty() {
-  __end_->first() = new __empty_state<_CharT>(__end_->first());
-  __end_          = static_cast<__owns_one_state<_CharT>*>(__end_->first());
-}
-
+const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::awk;
 template <class _CharT, class _Traits>
-void basic_regex<_CharT, _Traits>::__push_word_boundary(bool __invert) {
-  __end_->first() = new __word_boundary<_CharT, _Traits>(__traits_, __invert, __end_->first());
-  __end_          = static_cast<__owns_one_state<_CharT>*>(__end_->first());
-}
+const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::grep;
+template <class _CharT, class _Traits>
+const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::egrep;
 
 template <class _CharT, class _Traits>
-void basic_regex<_CharT, _Traits>::__push_back_ref(int __i) {
-  if (flags() & icase)
-    __end_->first() = new __back_ref_icase<_CharT, _Traits>(__traits_, __i, __end_->first());
-  else if (flags() & collate)
-    __end_->first() = new __back_ref_collate<_CharT, _Traits>(__traits_, __i, __end_->first());
-  else
-    __end_->first() = new __back_ref<_CharT>(__i, __end_->first());
-  __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
+void basic_regex<_CharT, _Traits>::swap(basic_regex& __r) {
+  using std::swap;
+  swap(__traits_, __r.__traits_);
+  swap(__flags_, __r.__flags_);
+  swap(__marked_count_, __r.__marked_count_);
+  swap(__loop_count_, __r.__loop_count_);
+  swap(__open_count_, __r.__open_count_);
+  swap(__start_, __r.__start_);
+  swap(__end_, __r.__end_);
 }
 
 template <class _CharT, class _Traits>
-void basic_regex<_CharT, _Traits>::__push_alternation(__owns_one_state<_CharT>* __sa, __owns_one_state<_CharT>* __ea) {
-  __sa->first() = new __alternate<_CharT>(
-      static_cast<__owns_one_state<_CharT>*>(__sa->first()), static_cast<__owns_one_state<_CharT>*>(__ea->first()));
-  __ea->first()   = nullptr;
-  __ea->first()   = new __empty_state<_CharT>(__end_->first());
-  __end_->first() = nullptr;
-  __end_->first() = new __empty_non_own_state<_CharT>(__ea->first());
-  __end_          = static_cast<__owns_one_state<_CharT>*>(__ea->first());
+inline _LIBCPP_HIDE_FROM_ABI void swap(basic_regex<_CharT, _Traits>& __x, basic_regex<_CharT, _Traits>& __y) {
+  return __x.swap(__y);
 }
 
 template <class _CharT, class _Traits>
-__bracket_expression<_CharT, _Traits>* basic_regex<_CharT, _Traits>::__start_matching_list(bool __negate) {
-  __bracket_expression<_CharT, _Traits>* __r = new __bracket_expression<_CharT, _Traits>(
-      __traits_, __end_->first(), __negate, __flags_ & icase, __flags_ & collate);
-  __end_->first() = __r;
-  __end_          = __r;
-  return __r;
+template <class _ForwardIterator>
+void basic_regex<_CharT, _Traits>::__init(_ForwardIterator __first, _ForwardIterator __last) {
+  if (__get_grammar(__flags_) == 0)
+    __flags_ |= regex_constants::ECMAScript;
+  _ForwardIterator __temp = __parse(__first, __last);
+  if (__temp != __last)
+    std::__throw_regex_error<regex_constants::__re_err_parse>();
 }
 
 template <class _CharT, class _Traits>
-void basic_regex<_CharT, _Traits>::__push_lookahead(const basic_regex& __exp, bool __invert, unsigned __mexp) {
-  __end_->first() = new __lookahead<_CharT, _Traits>(__exp, __invert, __end_->first(), __mexp);
-  __end_          = static_cast<__owns_one_state<_CharT>*>(__end_->first());
+template <class _ForwardIterator>
+_ForwardIterator basic_regex<_CharT, _Traits>::__parse(_ForwardIterator __first, _ForwardIterator __last) {
+  switch (__get_grammar(__flags_)) {
+  case ECMAScript: {
+    __regex::__ecma::__parser<_CharT, _Traits, _ForwardIterator> __parser(__first, __last, __traits_, flags());
+    __parser.__parse_ecma();
+    __start_.reset(new __interpreter_state<_CharT, _Traits>(__parser.__extract_interpreter(), nullptr));
+    __end_          = __start_.get();
+    __marked_count_ = __parser.mark_count();
+    return __last;
+  }
+  case basic:
+  case grep: {
+    __regex::__basic::__parser<_CharT, _Traits, _ForwardIterator> __parser(__first, __last, __traits_, flags());
+    if (__get_grammar(__flags_) == basic)
+      __parser.__parse_basic();
+    else
+      __parser.__parse_grep();
+    __start_.reset(new __interpreter_state<_CharT, _Traits>(__parser.__extract_interpreter(), nullptr));
+    __end_          = __start_.get();
+    __marked_count_ = __parser.mark_count();
+    return __last;
+  }
+  case awk:
+  case extended:
+  case egrep: {
+    __regex::__extended::__parser<_CharT, _Traits, _ForwardIterator> __parser(__first, __last, __traits_, flags());
+    if (auto __grammar = __get_grammar(__flags_); __grammar == extended || __grammar == awk)
+      __parser.__parse_extended();
+    else
+      __parser.__parse_egrep();
+    __start_.reset(new __interpreter_state<_CharT, _Traits>(__parser.__extract_interpreter(), nullptr));
+    __end_          = __start_.get();
+    __marked_count_ = __parser.mark_count();
+    return __last;
+  }
+  default:
+    std::__throw_regex_error<regex_constants::__re_err_grammar>();
+  }
+  return __first;
 }
 
 // sub_match
@@ -4072,9 +2156,6 @@ private:
   template <class _Bp, class _Ap>
   friend bool operator==(const match_results<_Bp, _Ap>&, const match_results<_Bp, _Ap>&);
 
-  template <class, class>
-  friend class __lookahead;
-
   template <class, class, class>
   friend class regex_iterator;
 };
@@ -4463,7 +2544,31 @@ bool basic_regex<_CharT, _Traits>::__match_at_start(
     const _CharT* __last,
     match_results<const _CharT*, _Allocator>& __m,
     regex_constants::match_flag_type __flags,
-    bool __at_first) const {
+    bool __at_first,
+    __interpreter_state<_CharT, _Traits>* __interp) const {
+  if (__interp) {
+    sub_match<const _CharT*> __unmatched;
+    __unmatched.first   = __last;
+    __unmatched.second  = __last;
+    __unmatched.matched = false;
+
+    std::__state<_CharT> __s;
+    __s.__first_   = __first;
+    __s.__last_    = __last;
+    __s.__current_ = __first;
+    __s.__sub_matches_.resize(mark_count(), __unmatched);
+    __s.__flags_    = __flags;
+    __s.__at_first_ = __at_first;
+    __interp->__exec(__s);
+    if (__s.__do_ != __state::__end_state)
+      return false;
+    __m.__matches_[0].first   = __first;
+    __m.__matches_[0].second  = std::next(__first, __s.__current_ - __first);
+    __m.__matches_[0].matched = true;
+    for (unsigned __i = 0; __i < __s.__sub_matches_.size(); ++__i)
+      __m.__matches_[__i + 1] = __s.__sub_matches_[__i];
+    return true;
+  }
   if (__get_grammar(__flags_) == ECMAScript)
     return __match_at_start_ecma(__states, __first, __last, __m, __flags, __at_first);
   if (mark_count() == 0)
@@ -4481,9 +2586,12 @@ bool basic_regex<_CharT, _Traits>::__search(
   if (__flags & regex_constants::match_prev_avail)
     __flags &= ~(regex_constants::match_not_bol | regex_constants::match_not_bow);
 
+  auto* __interp = dynamic_cast<__interpreter_state<_CharT, _Traits>*>(__start_.get());
+
   vector<__state> __states_buffer;
   __m.__init(1 + mark_count(), __first, __last, __flags & regex_constants::__no_update_pos);
-  if (__match_at_start(__states_buffer, __first, __last, __m, __flags, !(__flags & regex_constants::__no_update_pos))) {
+  if (__match_at_start(
+          __states_buffer, __first, __last, __m, __flags, !(__flags & regex_constants::__no_update_pos), __interp)) {
     __m.__prefix_.second  = __m[0].first;
     __m.__prefix_.matched = __m.__prefix_.first != __m.__prefix_.second;
     __m.__suffix_.first   = __m[0].second;
@@ -4494,7 +2602,7 @@ bool basic_regex<_CharT, _Traits>::__search(
     __flags |= regex_constants::match_prev_avail;
     for (++__first; __first != __last; ++__first) {
       __m.__matches_.assign(__m.size(), __m.__unmatched_);
-      if (__match_at_start(__states_buffer, __first, __last, __m, __flags, false)) {
+      if (__match_at_start(__states_buffer, __first, __last, __m, __flags, false, __interp)) {
         __m.__prefix_.second  = __m[0].first;
         __m.__prefix_.matched = __m.__prefix_.first != __m.__prefix_.second;
         __m.__suffix_.first   = __m[0].second;
@@ -4504,7 +2612,7 @@ bool basic_regex<_CharT, _Traits>::__search(
       __m.__matches_.assign(__m.size(), __m.__unmatched_);
     }
     __m.__matches_.assign(__m.size(), __m.__unmatched_);
-    if (__match_at_start(__states_buffer, __first, __last, __m, __flags, false)) {
+    if (__match_at_start(__states_buffer, __first, __last, __m, __flags, false, __interp)) {
       __m.__prefix_.second  = __m[0].first;
       __m.__prefix_.matched = __m.__prefix_.first != __m.__prefix_.second;
       __m.__suffix_.first   = __m[0].second;
diff --git a/libcxx/src/regex.cpp b/libcxx/src/regex.cpp
index 9d7d1699ae266..1e5bc9cdb83db 100644
--- a/libcxx/src/regex.cpp
+++ b/libcxx/src/regex.cpp
@@ -353,8 +353,16 @@ regex_traits<char>::char_class_type __get_classname(const char* s, bool __icase)
   return r;
 }
 
+template <class _CharT>
+class __match_any_but_newline : public __owns_one_state<_CharT> {
+public:
+  typedef std::__state<_CharT> __state;
+
+  void __exec(__state&) const override;
+};
+
 template <>
-void __match_any_but_newline<char>::__exec(__state& __s) const {
+_LIBCPP_EXPORTED_FROM_ABI void __match_any_but_newline<char>::__exec(__state& __s) const {
   if (__s.__current_ != __s.__last_) {
     switch (*__s.__current_) {
     case '\r':
@@ -374,8 +382,9 @@ void __match_any_but_newline<char>::__exec(__state& __s) const {
   }
 }
 
+#if _LIBCPP_HAS_WIDE_CHARACTERS
 template <>
-void __match_any_but_newline<wchar_t>::__exec(__state& __s) const {
+_LIBCPP_EXPORTED_FROM_ABI void __match_any_but_newline<wchar_t>::__exec(__state& __s) const {
   if (__s.__current_ != __s.__last_) {
     switch (*__s.__current_) {
     case '\r':
@@ -396,6 +405,7 @@ void __match_any_but_newline<wchar_t>::__exec(__state& __s) const {
     __s.__node_ = nullptr;
   }
 }
+#endif
 
 _LIBCPP_END_EXPLICIT_ABI_ANNOTATIONS
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/test/std/re/re.alg/re.alg.search/basic.pass.cpp b/libcxx/test/std/re/re.alg/re.alg.search/basic.pass.cpp
index 80918d2b2958a..4006b47896509 100644
--- a/libcxx/test/std/re/re.alg/re.alg.search/basic.pass.cpp
+++ b/libcxx/test/std/re/re.alg/re.alg.search/basic.pass.cpp
@@ -37,7 +37,7 @@ int main(int, char**)
     }
     {
         std::cmatch m;
-        assert(!std::regex_search("a", m, std::regex("[a-[.hyphen.]]", std::regex_constants::basic)));
+        assert(!std::regex_search("a", m, std::regex("[[.hyphen.]-0]", std::regex_constants::basic)));
         assert(m.size() == 0);
         assert(m.empty());
     }

>From 2c699ee91d993faa547e1993f15f51d180468871 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Sat, 28 Mar 2026 04:59:31 +0100
Subject: [PATCH 05/21] [libc++] Add a more efficient interface to call the new
 regex implementation

---
 libcxx/include/__regex/interpreter.h | 79 +++++++++++++++++++++++++---
 libcxx/include/regex                 | 79 ++++++++++++++++------------
 2 files changed, 115 insertions(+), 43 deletions(-)

diff --git a/libcxx/include/__regex/interpreter.h b/libcxx/include/__regex/interpreter.h
index fc7aefa7db8a4..864b645c56d3e 100644
--- a/libcxx/include/__regex/interpreter.h
+++ b/libcxx/include/__regex/interpreter.h
@@ -125,6 +125,27 @@ struct __bracket_expr {
   typename _Traits::char_class_type __neg_mask_ = 0;
 };
 
+// This is essentially an optional<vector<sub_match<const _CharT*>>>, just back-ported to C++03
+// FIXME: This isn't exactly the optimal representation
+template <class _CharT>
+struct __search_result {
+  union {
+    struct {
+      const _CharT* __match_first_;
+      const _CharT* __match_last_;
+      vector<sub_match<const _CharT*>> __sub_matches_;
+    };
+  };
+  bool __matched_;
+
+  __search_result() : __matched_(false) {}
+  __search_result(const _CharT* __first, const _CharT* __last, vector<sub_match<const _CharT*>> __sub_matches)
+      : __match_first_(__first), __match_last_(__last), __sub_matches_(std::move(__sub_matches)), __matched_(true) {}
+  __search_result(const __search_result&)            = delete;
+  __search_result& operator=(const __search_result&) = delete;
+  ~__search_result() {}
+};
+
 template <class _CharT, class _Traits>
 class __interpreter {
   vector<__interpreter_info<_CharT> > __machine_;
@@ -777,15 +798,19 @@ class __interpreter {
             const _CharT* __last,
             vector<sub_match<const _CharT*>>& __sub_matches) const {
     using __local_state = typename __global_execution_state::__local_execution_state;
-    __local_state __base_state;
-    __base_state.__sub_matches_ = std::move(__sub_matches);
-    __base_state.__current_     = __first;
-    if (!__initial_loop_values_.empty()) {
-      __base_state.__loop_values_ = std::make_unique_for_overwrite<size_t[]>(__initial_loop_values_.size());
+
+    __local_state __base_state{
+        .__current_     = __first,
+        .__sub_matches_ = std::move(__sub_matches),
+        .__current_pos_ = 0,
+        .__loop_values_ = __initial_loop_values_.empty()
+                            ? nullptr
+                            : std::make_unique_for_overwrite<size_t[]>(__initial_loop_values_.size()),
+        .__loop_starts_ =
+            __initial_loop_values_.empty() ? nullptr : std::make_unique<const _CharT*[]>(__initial_loop_values_.size()),
+    };
+    if (!__initial_loop_values_.empty())
       std::copy(__initial_loop_values_.begin(), __initial_loop_values_.end(), __base_state.__loop_values_.get());
-      __base_state.__loop_starts_ = std::make_unique<const _CharT*[]>(__initial_loop_values_.size());
-    }
-    __base_state.__current_pos_ = 0;
 
     __global_execution_state __gexec_state{{}, *this, __flags};
     auto [__base_state_matched, __gcounter] = __base_state.__execute(__first, __last, __gexec_state);
@@ -836,6 +861,44 @@ class __interpreter {
     }
   }
 
+  __search_result<_CharT> __execute_search(
+      const _CharT* __first, const _CharT* __last, regex_constants::match_flag_type __flags, size_t __marked_count) {
+    sub_match<const _CharT*> __unmatched;
+    __unmatched.first   = __last;
+    __unmatched.second  = __last;
+    __unmatched.matched = false;
+
+    vector<sub_match<const _CharT*>> __sub_matches(__marked_count, __unmatched);
+    if (auto [__success, __last_val] = __execute(
+            __flags | ((__flags & regex_constants::__no_update_pos) ? regex_constants::match_flag_type()
+                                                                    : regex_constants::__at_first),
+            __first,
+            __last,
+            __sub_matches);
+        __success) {
+      return {__first, __last_val, std::move(__sub_matches)};
+    }
+
+    if (__first == __last || (__flags & regex_constants::match_continuous))
+      return {};
+
+    __flags |= regex_constants::match_prev_avail;
+
+    for (++__first; __first != __last; ++__first) {
+      __sub_matches.assign(__marked_count, __unmatched);
+      if (auto [__success, __last_val] = __execute(__flags, __first, __last, __sub_matches); __success) {
+        return {__first, __last_val, std::move(__sub_matches)};
+      }
+    }
+
+    __sub_matches.assign(__marked_count, __unmatched);
+    if (auto [__success, __last_val] = __execute(__flags, __first, __last, __sub_matches); __success) {
+      return {__first, __last_val, std::move(__sub_matches)};
+    }
+
+    return {};
+  }
+
   const _Traits& __get_traits() const { return __traits_; }
 };
 } // namespace __regex
diff --git a/libcxx/include/regex b/libcxx/include/regex
index 654f02a5df4f4..c0011c954cc26 100644
--- a/libcxx/include/regex
+++ b/libcxx/include/regex
@@ -1270,13 +1270,22 @@ void __empty_state<_CharT>::__exec(__state& __s) const {
   __s.__node_ = this->first();
 }
 
+template <class _CharT>
+class __regex_search_state : public __empty_state<_CharT> {
+public:
+  explicit __regex_search_state(__node<_CharT>* __s) : __empty_state<_CharT>(__s) {}
+
+  virtual __regex::__search_result<_CharT> __exec_regex_search(
+      const _CharT* __first, const _CharT* __last, regex_constants::match_flag_type, size_t __marked_count) = 0;
+};
+
 template <class _CharT, class _Traits>
-class __interpreter_state : public __empty_state<_CharT> {
+class __interpreter_state : public __regex_search_state<_CharT> {
   __regex::__interpreter<_CharT, _Traits> __machine_;
 
 public:
   _LIBCPP_HIDE_FROM_ABI __interpreter_state(__regex::__interpreter<_CharT, _Traits> __machine, __node<_CharT>* __s)
-      : __empty_state<_CharT>(__s), __machine_(std::move(__machine)) {}
+      : __regex_search_state<_CharT>(__s), __machine_(std::move(__machine)) {}
 
   _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __exec(__state<_CharT>& __state) const override {
     auto __res = __machine_.__execute(
@@ -1287,6 +1296,14 @@ public:
     __state.__do_      = __res.first ? std::__state<_CharT>::__end_state : std::__state<_CharT>::__reject;
     __state.__current_ = __res.second;
   }
+
+  __regex::__search_result<_CharT> __exec_regex_search(
+      const _CharT* __first,
+      const _CharT* __last,
+      regex_constants::match_flag_type __flags,
+      size_t __marked_count) override {
+    return __machine_.__execute_search(__first, __last, __flags, __marked_count);
+  }
 };
 
 template <class _CharT, class _Traits = regex_traits<_CharT> >
@@ -1471,8 +1488,7 @@ private:
       const _CharT* __last,
       match_results<const _CharT*, _Allocator>& __m,
       regex_constants::match_flag_type __flags,
-      bool,
-      __interpreter_state<_CharT, _Traits>*) const;
+      bool) const;
   template <class _Allocator>
   bool __match_at_start_ecma(
       vector<__state>& __states,
@@ -2544,31 +2560,7 @@ bool basic_regex<_CharT, _Traits>::__match_at_start(
     const _CharT* __last,
     match_results<const _CharT*, _Allocator>& __m,
     regex_constants::match_flag_type __flags,
-    bool __at_first,
-    __interpreter_state<_CharT, _Traits>* __interp) const {
-  if (__interp) {
-    sub_match<const _CharT*> __unmatched;
-    __unmatched.first   = __last;
-    __unmatched.second  = __last;
-    __unmatched.matched = false;
-
-    std::__state<_CharT> __s;
-    __s.__first_   = __first;
-    __s.__last_    = __last;
-    __s.__current_ = __first;
-    __s.__sub_matches_.resize(mark_count(), __unmatched);
-    __s.__flags_    = __flags;
-    __s.__at_first_ = __at_first;
-    __interp->__exec(__s);
-    if (__s.__do_ != __state::__end_state)
-      return false;
-    __m.__matches_[0].first   = __first;
-    __m.__matches_[0].second  = std::next(__first, __s.__current_ - __first);
-    __m.__matches_[0].matched = true;
-    for (unsigned __i = 0; __i < __s.__sub_matches_.size(); ++__i)
-      __m.__matches_[__i + 1] = __s.__sub_matches_[__i];
-    return true;
-  }
+    bool __at_first) const {
   if (__get_grammar(__flags_) == ECMAScript)
     return __match_at_start_ecma(__states, __first, __last, __m, __flags, __at_first);
   if (mark_count() == 0)
@@ -2586,12 +2578,29 @@ bool basic_regex<_CharT, _Traits>::__search(
   if (__flags & regex_constants::match_prev_avail)
     __flags &= ~(regex_constants::match_not_bol | regex_constants::match_not_bow);
 
-  auto* __interp = dynamic_cast<__interpreter_state<_CharT, _Traits>*>(__start_.get());
+  __m.__init(1 + mark_count(), __first, __last, __flags & regex_constants::__no_update_pos);
+
+  if (auto* __interp = dynamic_cast<__regex_search_state<_CharT>*>(__start_.get())) {
+    auto __res = __interp->__exec_regex_search(__first, __last, __flags, mark_count());
+    if (!__res.__matched_) {
+      __m.__matches_.clear();
+      return false;
+    }
+    vector<sub_match<const _CharT*>> __sub_matches(std::move(__res.__sub_matches_));
+    std::__destroy_at(&__res.__sub_matches_);
+    __m.__matches_[0].first   = __res.__match_first_;
+    __m.__matches_[0].second  = __res.__match_last_;
+    __m.__matches_[0].matched = true;
+    std::copy(__sub_matches.begin(), __sub_matches.end(), __m.__matches_.begin() + 1);
+    __m.__prefix_.second  = __m[0].first;
+    __m.__prefix_.matched = __m.__prefix_.first != __m.__prefix_.second;
+    __m.__suffix_.first   = __m[0].second;
+    __m.__suffix_.matched = __m.__suffix_.first != __m.__suffix_.second;
+    return true;
+  }
 
   vector<__state> __states_buffer;
-  __m.__init(1 + mark_count(), __first, __last, __flags & regex_constants::__no_update_pos);
-  if (__match_at_start(
-          __states_buffer, __first, __last, __m, __flags, !(__flags & regex_constants::__no_update_pos), __interp)) {
+  if (__match_at_start(__states_buffer, __first, __last, __m, __flags, !(__flags & regex_constants::__no_update_pos))) {
     __m.__prefix_.second  = __m[0].first;
     __m.__prefix_.matched = __m.__prefix_.first != __m.__prefix_.second;
     __m.__suffix_.first   = __m[0].second;
@@ -2602,7 +2611,7 @@ bool basic_regex<_CharT, _Traits>::__search(
     __flags |= regex_constants::match_prev_avail;
     for (++__first; __first != __last; ++__first) {
       __m.__matches_.assign(__m.size(), __m.__unmatched_);
-      if (__match_at_start(__states_buffer, __first, __last, __m, __flags, false, __interp)) {
+      if (__match_at_start(__states_buffer, __first, __last, __m, __flags, false)) {
         __m.__prefix_.second  = __m[0].first;
         __m.__prefix_.matched = __m.__prefix_.first != __m.__prefix_.second;
         __m.__suffix_.first   = __m[0].second;
@@ -2612,7 +2621,7 @@ bool basic_regex<_CharT, _Traits>::__search(
       __m.__matches_.assign(__m.size(), __m.__unmatched_);
     }
     __m.__matches_.assign(__m.size(), __m.__unmatched_);
-    if (__match_at_start(__states_buffer, __first, __last, __m, __flags, false, __interp)) {
+    if (__match_at_start(__states_buffer, __first, __last, __m, __flags, false)) {
       __m.__prefix_.second  = __m[0].first;
       __m.__prefix_.matched = __m.__prefix_.first != __m.__prefix_.second;
       __m.__suffix_.first   = __m[0].second;

>From 087d4afa4666dd2500f455863b98d9146e47c47d Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Sun, 29 Mar 2026 03:27:31 +0200
Subject: [PATCH 06/21] [libc++] Move the execution states out of __interpreter

---
 libcxx/include/__regex/interpreter.h | 852 ++++++++++++++-------------
 1 file changed, 429 insertions(+), 423 deletions(-)

diff --git a/libcxx/include/__regex/interpreter.h b/libcxx/include/__regex/interpreter.h
index 864b645c56d3e..5a52d5bb26eeb 100644
--- a/libcxx/include/__regex/interpreter.h
+++ b/libcxx/include/__regex/interpreter.h
@@ -147,11 +147,17 @@ struct __search_result {
 };
 
 template <class _CharT, class _Traits>
-class __interpreter {
-  vector<__interpreter_info<_CharT> > __machine_;
-  vector<size_t> __initial_loop_values_;
-  _Traits __traits_;
-  bool __find_longest_;
+struct __global_execution_state;
+
+template <class _CharT, class _Traits>
+struct __local_execution_state {
+  using __global_state = __global_execution_state<_CharT, _Traits>;
+
+  const _CharT* __current_;
+  vector<sub_match<const _CharT*> > __sub_matches_;
+  size_t __current_pos_;
+  unique_ptr<size_t[]> __loop_values_;
+  unique_ptr<const _CharT*[]> __loop_starts_;
 
   static pair<size_t, size_t>
   __read_uleb_impl(_LIBCPP_NOESCAPE const __interpreter_info<_CharT>* __machine, size_t __current_pos) {
@@ -177,467 +183,467 @@ class __interpreter {
     return __val;
   }
 
-  struct __global_execution_state {
-    struct __local_execution_state;
-
-    vector<__local_execution_state> __states_;
-    const __interpreter& __machine_;
-    regex_constants::match_flag_type __flags_;
-
-    struct __local_execution_state {
-      const _CharT* __current_;
-      vector<sub_match<const _CharT*> > __sub_matches_;
-      size_t __current_pos_;
-      unique_ptr<size_t[]> __loop_values_;
-      unique_ptr<const _CharT*[]> __loop_starts_;
-
-      void __copy_to(const _CharT* const __current,
-                     vector<__local_execution_state>& __vec,
-                     __global_execution_state& __gstate) {
-        auto __loop_value_count = __gstate.__machine_.__initial_loop_values_.size();
-        auto __loop_values_copy = std::make_unique_for_overwrite<size_t[]>(__loop_value_count);
-        std::copy_n(__loop_values_.get(), __loop_value_count, __loop_values_copy.get());
-        auto __loop_starts_copy = std::make_unique_for_overwrite<const _CharT*[]>(__loop_value_count);
-        std::copy_n(__loop_starts_.get(), __loop_value_count, __loop_starts_copy.get());
-        __vec.emplace_back(
-            __current, __sub_matches_, __current_pos_, std::move(__loop_values_copy), std::move(__loop_starts_copy));
-      }
+  void __copy_to(const _CharT* const __current, vector<__local_execution_state>& __vec, __global_state& __gstate) {
+    auto __loop_value_count = __gstate.__machine_.__initial_loop_values_.size();
+    auto __loop_values_copy = std::make_unique_for_overwrite<size_t[]>(__loop_value_count);
+    std::copy_n(__loop_values_.get(), __loop_value_count, __loop_values_copy.get());
+    auto __loop_starts_copy = std::make_unique_for_overwrite<const _CharT*[]>(__loop_value_count);
+    std::copy_n(__loop_starts_.get(), __loop_value_count, __loop_starts_copy.get());
+    __vec.emplace_back(
+        __current, __sub_matches_, __current_pos_, std::move(__loop_values_copy), std::move(__loop_starts_copy));
+  }
 
-      static bool __is_word_boundary(const _CharT* __first,
-                                     const _CharT* __last,
-                                     const _CharT* const __current,
-                                     __global_execution_state& __gstate) {
-        auto __is_word_char = [&](char __c) {
-          return __c == '_' || __gstate.__machine_.__traits_.isctype(__c, ctype_base::alnum);
-        };
+  static bool __is_word_boundary(
+      const _CharT* __first, const _CharT* __last, const _CharT* const __current, __global_state& __gstate) {
+    auto __is_word_char = [&](char __c) {
+      return __c == '_' || __gstate.__machine_.__traits_.isctype(__c, ctype_base::alnum);
+    };
 
-        if (__first == __last)
-          return false;
+    if (__first == __last)
+      return false;
 
-        if (__current == __last) {
-          return !(__gstate.__flags_ & regex_constants::match_not_eow) && __is_word_char(__current[-1]);
-        }
+    if (__current == __last) {
+      return !(__gstate.__flags_ & regex_constants::match_not_eow) && __is_word_char(__current[-1]);
+    }
 
-        if (__current == __first && !(__gstate.__flags_ & regex_constants::match_prev_avail)) {
-          return !(__gstate.__flags_ & regex_constants::match_not_bow) && __is_word_char(__current[0]);
-        }
+    if (__current == __first && !(__gstate.__flags_ & regex_constants::match_prev_avail)) {
+      return !(__gstate.__flags_ & regex_constants::match_not_bow) && __is_word_char(__current[0]);
+    }
+
+    return __is_word_char(__current[-1]) != __is_word_char(__current[0]);
+  }
+
+  struct __charlist_result {
+    bool __matched;
+    bool __matched_digraph;
+    size_t __new_pos;
+  };
 
-        return __is_word_char(__current[-1]) != __is_word_char(__current[0]);
+  static __charlist_result __exec_match_character_list(
+      const __interpreter_info<_CharT>* const __code,
+      const _CharT* const __last,
+      const _CharT* const __current,
+      const __global_state& __gstate,
+      size_t __current_pos) {
+    static constexpr auto __buffer_size =
+        std::max(sizeof(typename _Traits::char_class_type) / sizeof(_CharT), size_t(1));
+    _CharT __buffer[__buffer_size];
+    for (size_t __i = 0; __i != __buffer_size; ++__i)
+      __buffer[__i] = __code[__current_pos++].__char_;
+    typename _Traits::char_class_type __mask;
+    __builtin_memcpy(&__mask, __buffer, sizeof(typename _Traits::char_class_type));
+
+    for (size_t __i = 0; __i != __buffer_size; ++__i)
+      __buffer[__i] = __code[__current_pos++].__char_;
+    typename _Traits::char_class_type __neg_mask;
+    __builtin_memcpy(&__neg_mask, __buffer, sizeof(typename _Traits::char_class_type));
+
+    auto __chars       = __read_uleb(__code, __current_pos);
+    auto __digraphs    = __read_uleb(__code, __current_pos) * 2;
+    auto __ranges      = __read_uleb(__code, __current_pos) * 4;
+    auto __neg_chars   = __read_uleb(__code, __current_pos);
+    auto __equiv_count = __read_uleb(__code, __current_pos);
+    auto __equiv_size  = __read_uleb(__code, __current_pos);
+
+    bool __found = false;
+
+    for (size_t __i = 0; __i != __chars; ++__i) {
+      if (__code[__current_pos + __i].__char_ == *__current) {
+        __found = true;
+        break;
       }
+    }
 
-      struct __charlist_result {
-        bool __matched;
-        bool __matched_digraph;
-        size_t __new_pos;
-      };
-
-      static __charlist_result __exec_match_character_list(
-          const __interpreter_info<_CharT>* const __code,
-          const _CharT* const __last,
-          const _CharT* const __current,
-          const __global_execution_state& __gstate,
-          size_t __current_pos) {
-        static constexpr auto __buffer_size =
-            std::max(sizeof(typename _Traits::char_class_type) / sizeof(_CharT), size_t(1));
-        _CharT __buffer[__buffer_size];
-        for (size_t __i = 0; __i != __buffer_size; ++__i)
-          __buffer[__i] = __code[__current_pos++].__char_;
-        typename _Traits::char_class_type __mask;
-        __builtin_memcpy(&__mask, __buffer, sizeof(typename _Traits::char_class_type));
-
-        for (size_t __i = 0; __i != __buffer_size; ++__i)
-          __buffer[__i] = __code[__current_pos++].__char_;
-        typename _Traits::char_class_type __neg_mask;
-        __builtin_memcpy(&__neg_mask, __buffer, sizeof(typename _Traits::char_class_type));
-
-        auto __chars       = __read_uleb(__code, __current_pos);
-        auto __digraphs    = __read_uleb(__code, __current_pos) * 2;
-        auto __ranges      = __read_uleb(__code, __current_pos) * 4;
-        auto __neg_chars   = __read_uleb(__code, __current_pos);
-        auto __equiv_count = __read_uleb(__code, __current_pos);
-        auto __equiv_size  = __read_uleb(__code, __current_pos);
-
-        bool __found = false;
-
-        for (size_t __i = 0; __i != __chars; ++__i) {
-          if (__code[__current_pos + __i].__char_ == *__current) {
-            __found = true;
-            break;
-          }
-        }
+    __current_pos += __chars;
 
-        __current_pos += __chars;
+    if (__found) {
+      __current_pos += __digraphs + __ranges + __neg_chars + __equiv_size;
+      return {true, false, __current_pos};
+    }
+
+    if (__current + 1 != __last) {
+      _CharT __vals[2] = {__current[0], __current[1]};
 
-        if (__found) {
-          __current_pos += __digraphs + __ranges + __neg_chars + __equiv_size;
-          return {true, false, __current_pos};
+      for (size_t __i = 0; __i != __digraphs; __i += 2) {
+        if (__code[__current_pos + __i].__char_ == __vals[0] && __code[__current_pos + __i + 1].__char_ == __vals[1]) {
+          __found = true;
+          break;
         }
+      }
+    }
 
-        if (__current + 1 != __last) {
-          _CharT __vals[2] = {__current[0], __current[1]};
+    __current_pos += __digraphs;
 
-          for (size_t __i = 0; __i != __digraphs; __i += 2) {
-            if (__code[__current_pos + __i].__char_ == __vals[0] &&
-                __code[__current_pos + __i + 1].__char_ == __vals[1]) {
-              __found = true;
-              break;
-            }
-          }
-        }
+    if (__found) {
+      __current_pos += __ranges + __neg_chars + __equiv_size;
+      return {true, true, __current_pos};
+    }
 
-        __current_pos += __digraphs;
+    auto __cmp = __gstate.__machine_.__traits_.transform(__current, __current + 1);
+    for (size_t __i = 0; __i != __ranges; __i += 4) {
+      _CharT __range_info[4];
+      std::transform(__gstate.__machine_.__machine_.begin() + __current_pos + __i,
+                     __gstate.__machine_.__machine_.begin() + __current_pos + __i + 4,
+                     __range_info,
+                     [](__interpreter_info<_CharT> __val) { return __val.__char_; });
+      basic_string_view<_CharT> __min(__range_info, __range_info[1] == '\0' ? 1 : 2);
+      basic_string_view<_CharT> __max(__range_info + 2, __range_info[3] == '\0' ? 1 : 2);
+      if (__min <= __cmp && __cmp <= __max) {
+        __found = true;
+        break;
+      }
+    }
 
-        if (__found) {
-          __current_pos += __ranges + __neg_chars + __equiv_size;
-          return {true, true, __current_pos};
-        }
+    __current_pos += __ranges;
 
-        auto __cmp = __gstate.__machine_.__traits_.transform(__current, __current + 1);
-        for (size_t __i = 0; __i != __ranges; __i += 4) {
-          _CharT __range_info[4];
-          std::transform(__gstate.__machine_.__machine_.begin() + __current_pos + __i,
-                         __gstate.__machine_.__machine_.begin() + __current_pos + __i + 4,
-                         __range_info,
-                         [](__interpreter_info<_CharT> __val) { return __val.__char_; });
-          basic_string_view<_CharT> __min(__range_info, __range_info[1] == '\0' ? 1 : 2);
-          basic_string_view<_CharT> __max(__range_info + 2, __range_info[3] == '\0' ? 1 : 2);
-          if (__min <= __cmp && __cmp <= __max) {
-            __found = true;
-            break;
-          }
-        }
+    if (__found) {
+      __current_pos += __neg_chars + __equiv_size;
+      return {true, false, __current_pos};
+    }
 
-        __current_pos += __ranges;
+    if (__gstate.__machine_.__traits_.isctype(*__current, __mask)) {
+      return {true, false, __current_pos};
+    }
 
-        if (__found) {
-          __current_pos += __neg_chars + __equiv_size;
-          return {true, false, __current_pos};
-        }
+    bool __none_match = true;
+    for (size_t __i = 0; __i != __neg_chars; ++__i) {
+      if (__code[__current_pos + __i].__char_ == *__current) {
+        __none_match = false;
+        break;
+      }
+    }
 
-        if (__gstate.__machine_.__traits_.isctype(*__current, __mask)) {
-          return {true, false, __current_pos};
-        }
+    __current_pos += __neg_chars;
 
-        bool __none_match = true;
-        for (size_t __i = 0; __i != __neg_chars; ++__i) {
-          if (__code[__current_pos + __i].__char_ == *__current) {
-            __none_match = false;
-            break;
-          }
-        }
+    if (__none_match && __neg_mask != 0 && !__gstate.__machine_.__traits_.isctype(*__current, __neg_mask)) {
+      return {true, false, __current_pos};
+    }
 
-        __current_pos += __neg_chars;
+    if (__found) {
+      __current_pos += __equiv_size;
+      return {true, false, __current_pos};
+    }
 
-        if (__none_match && __neg_mask != 0 && !__gstate.__machine_.__traits_.isctype(*__current, __neg_mask)) {
-          return {true, false, __current_pos};
-        }
+    auto __after_pos   = __current_pos + __equiv_size;
+    auto __transformed = __gstate.__machine_.__traits_.transform_primary(__current, __current + 1);
+    for (size_t __i = 0; __i != __equiv_count; ++__i) {
+      auto __size = __read_uleb(__code, __current_pos);
+      basic_string<_CharT> __str;
+      std::transform(__code + __current_pos,
+                     __code + __current_pos + __size,
+                     std::back_inserter(__str),
+                     [](__interpreter_info<_CharT> __v) { return __v.__char_; });
+      __current_pos += __size;
+      if (__transformed == __str) {
+        __found = true;
+        break;
+      }
+    }
 
-        if (__found) {
-          __current_pos += __equiv_size;
-          return {true, false, __current_pos};
-        }
+    __current_pos = __after_pos;
 
-        auto __after_pos   = __current_pos + __equiv_size;
-        auto __transformed = __gstate.__machine_.__traits_.transform_primary(__current, __current + 1);
-        for (size_t __i = 0; __i != __equiv_count; ++__i) {
-          auto __size = __read_uleb(__code, __current_pos);
-          basic_string<_CharT> __str;
-          std::transform(__code + __current_pos,
-                         __code + __current_pos + __size,
-                         std::back_inserter(__str),
-                         [](__interpreter_info<_CharT> __v) { return __v.__char_; });
-          __current_pos += __size;
-          if (__transformed == __str) {
-            __found = true;
-            break;
-          }
-        }
+    return {__found, false, __current_pos};
+  }
 
-        __current_pos = __after_pos;
+  pair<bool, size_t> __exec_lookahead(
+      const _CharT* const __first,
+      const _CharT* const __last,
+      const __global_state& __gstate,
+      const __interpreter_info<_CharT>* const __code,
+      size_t __current_pos,
+      bool __is_positive) {
+    auto __jump_offset    = __read_uleb(__code, __current_pos);
+    auto __submatch_count = __read_uleb(__code, __current_pos);
+    auto __submatch_base  = __read_uleb(__code, __current_pos);
+    auto __loop_count     = __read_uleb(__code, __current_pos);
+
+    unique_ptr<size_t[]> __initial_loop_values = std::make_unique_for_overwrite<size_t[]>(__loop_count);
+
+    for (size_t __i = 0; __i != __loop_count; ++__i)
+      __initial_loop_values[__i] = __read_uleb(__code, __current_pos);
+
+    __global_state __gexec_state{{}, __gstate.__machine_, __gstate.__flags_};
+    __gexec_state.__flags_ &= ~regex_constants::__full_match;
+    auto& __s = __gexec_state.__states_.emplace_back();
+    if (__loop_count > 0)
+      __s.__sub_matches_.resize(__submatch_count);
+    __s.__current_     = __current_;
+    __s.__loop_values_ = std::move(__initial_loop_values);
+    __s.__loop_starts_ = std::make_unique<const _CharT*[]>(__loop_count);
+    __s.__current_pos_ = __current_pos;
+    if (__gexec_state.__execute(__first, __last) != __is_positive)
+      return {false, __current_pos};
+    if (__is_positive) {
+      auto& __matched_state = __gexec_state.__states_.back();
+      std::copy(__matched_state.__sub_matches_.begin(),
+                __matched_state.__sub_matches_.end(),
+                __sub_matches_.begin() + __submatch_base);
+    }
+    __current_pos += __jump_offset;
+    return {true, __current_pos};
+  }
+
+  size_t __exec_branch_n_to_m_matcher(
+      __global_state& __gstate,
+      const __interpreter_info<_CharT>* const __code,
+      const _CharT* const __current,
+      size_t __current_pos,
+      bool __is_greedy) {
+    auto __loop_index     = __read_uleb(__code, __current_pos);
+    auto __again_pos_base = __current_pos;
+    auto __again_pos      = __again_pos_base - __read_uleb(__code, __current_pos);
+    if (__loop_values_[__loop_index] > 0) {
+      --__loop_values_[__loop_index];
+      __current_pos = __again_pos;
+      return __current_pos;
+    }
+    if (__loop_starts_[__loop_index] != __current && __loop_values_[__loop_index + 1] > 0) {
+      --__loop_values_[__loop_index + 1];
+      __loop_starts_[__loop_index] = __current;
+      __copy_to(__current, __gstate.__states_, __gstate);
+      if (!__is_greedy) {
+        __gstate.__states_.back().__current_pos_ = __again_pos;
+      } else {
+        __gstate.__states_.back().__current_pos_ = __current_pos;
+        __current_pos                            = __again_pos;
+      }
+      return __current_pos;
+    }
+    return __current_pos;
+  }
 
-        return {__found, false, __current_pos};
+  pair<bool, size_t> __execute(const _CharT* __first, const _CharT* __last, __global_state& __gstate) {
+    const __interpreter_info<_CharT>* const __code = __gstate.__machine().data();
+    auto __current_pos                             = __current_pos_;
+    auto __counter                                 = 0;
+    auto __current                                 = __current_;
+    auto __commit_current                          = std::__make_scope_guard([&] { __current_ = __current; });
+    while (true) {
+      ++__counter;
+      auto __st = __code[__current_pos++].__state_;
+      switch (__st) {
+        using enum __state;
+
+      case __multiline_start_anchor:
+        if (!(__gstate.__flags_ & regex_constants::__at_first) && (__current[-1] == '\n' || __current[-1] == '\r'))
+          break;
+        [[__fallthrough__]];
+      case __start_anchor: {
+        if (__gstate.__flags_ & regex_constants::match_not_bol || !(__gstate.__flags_ & regex_constants::__at_first) ||
+            __first != __current)
+          return {false, __counter};
+      } break;
+
+      case __multiline_end_anchor:
+        if (__current[0] == '\r' || __current[0] == '\n')
+          break;
+        [[__fallthrough__]];
+      case __end_anchor: {
+        if (__gstate.__flags_ & regex_constants::match_not_eol || __current != __last)
+          return {false, __counter};
+      } break;
+
+      case __end_state: {
+        return {(!(__gstate.__flags_ & regex_constants::match_not_null) || __current != __first) &&
+                    (!(__gstate.__flags_ & regex_constants::match_flag_type::__full_match) || __current == __last),
+                __counter};
       }
 
-      pair<bool, size_t> __exec_lookahead(
-          const _CharT* const __first,
-          const _CharT* const __last,
-          const __global_execution_state& __gstate,
-          const __interpreter_info<_CharT>* const __code,
-          size_t __current_pos,
-          bool __is_positive) {
-        auto __jump_offset    = __read_uleb(__code, __current_pos);
-        auto __submatch_count = __read_uleb(__code, __current_pos);
-        auto __submatch_base  = __read_uleb(__code, __current_pos);
-        auto __loop_count     = __read_uleb(__code, __current_pos);
-
-        unique_ptr<size_t[]> __initial_loop_values = std::make_unique_for_overwrite<size_t[]>(__loop_count);
-
-        for (size_t __i = 0; __i != __loop_count; ++__i)
-          __initial_loop_values[__i] = __read_uleb(__code, __current_pos);
-
-        __global_execution_state __gexec_state{{}, __gstate.__machine_, __gstate.__flags_};
-        __gexec_state.__flags_ &= ~regex_constants::__full_match;
-        auto& __s = __gexec_state.__states_.emplace_back();
-        if (__loop_count > 0)
-          __s.__sub_matches_.resize(__submatch_count);
-        __s.__current_     = __current_;
-        __s.__loop_values_ = std::move(__initial_loop_values);
-        __s.__loop_starts_ = std::make_unique<const _CharT*[]>(__loop_count);
-        __s.__current_pos_ = __current_pos;
-        if (__gexec_state.__execute(__first, __last) != __is_positive)
-          return {false, __current_pos};
-        if (__is_positive) {
-          auto& __matched_state = __gexec_state.__states_.back();
-          std::copy(__matched_state.__sub_matches_.begin(),
-                    __matched_state.__sub_matches_.end(),
-                    __sub_matches_.begin() + __submatch_base);
+      case __match_any: {
+        if (__current == __last)
+          return {false, __counter};
+        ++__current;
+      } break;
+
+      case __match_any_except_newline: {
+        if (__current == __last || *__current == '\r' || *__current == '\n')
+          return {false, __counter};
+        if constexpr (__is_same(_CharT, wchar_t)) {
+          if (*__current == 0x2028 || *__current == 0x2029)
+            return {false, __counter};
         }
-        __current_pos += __jump_offset;
-        return {true, __current_pos};
+        ++__current;
+      } break;
+
+      case __match_char: {
+        if (__current == __last || *__current != __code[__current_pos++].__char_)
+          return {false, __counter};
+        ++__current;
+      } break;
+
+      case __match_icase_char: {
+        if (__current == __last ||
+            __gstate.__machine_.__traits_.translate_nocase(*__current) != __code[__current_pos++].__char_)
+          return {false, __counter};
+        ++__current;
+      } break;
+
+      case __branch_alternative: {
+        auto __offset = __read_uleb(__code, __current_pos);
+        __copy_to(__current, __gstate.__states_, __gstate);
+        __gstate.__states_.back().__current_pos_ = __current_pos + __offset;
+        break;
+      }
+
+      case __relative_jump: {
+        __current_pos += __read_uleb(__code, __current_pos);
+        break;
       }
 
-      size_t __exec_branch_n_to_m_matcher(
-          __global_execution_state& __gstate,
-          const __interpreter_info<_CharT>* const __code,
-          const _CharT* const __current,
-          size_t __current_pos,
-          bool __is_greedy) {
-        auto __loop_index     = __read_uleb(__code, __current_pos);
-        auto __again_pos_base = __current_pos;
-        auto __again_pos      = __again_pos_base - __read_uleb(__code, __current_pos);
-        if (__loop_values_[__loop_index] > 0) {
-          --__loop_values_[__loop_index];
-          __current_pos = __again_pos;
-          return __current_pos;
+      case __branch_n_to_m_matcher:
+      case __branch_nongreedy_n_to_m_matcher: {
+        __current_pos = __exec_branch_n_to_m_matcher(
+            __gstate, __code, __current, __current_pos, __st != __branch_nongreedy_n_to_m_matcher);
+      } break;
+
+      case __match_backref: {
+        sub_match<const _CharT*>& __match = __sub_matches_[__read_uleb(__code, __current_pos) - 1];
+        if (!__match.matched)
+          return {false, __counter};
+
+        auto __len = __match.second - __match.first;
+        if (__last - __current < __len || !std::equal(__match.first, __match.second, __current))
+          return {false, __counter};
+
+        __current += __len;
+      } break;
+
+      case __match_icase_backref: {
+        sub_match<const _CharT*>& __match = __sub_matches_[__read_uleb(__code, __current_pos) - 1];
+        if (!__match.matched)
+          return {false, __counter};
+
+        auto __len = __match.second - __match.first;
+        if (__last - __current < __len)
+          return {false, __counter};
+
+        for (ptrdiff_t __i = 0; __i != __len; ++__i) {
+          if (__gstate.__machine_.__traits_.translate_nocase(__match.first[__i]) !=
+              __gstate.__machine_.__traits_.translate_nocase(__current[__i]))
+            return {false, __counter};
         }
-        if (__loop_starts_[__loop_index] != __current && __loop_values_[__loop_index + 1] > 0) {
-          --__loop_values_[__loop_index + 1];
-          __loop_starts_[__loop_index] = __current;
-          __copy_to(__current, __gstate.__states_, __gstate);
-          if (!__is_greedy) {
-            __gstate.__states_.back().__current_pos_ = __again_pos;
-          } else {
-            __gstate.__states_.back().__current_pos_ = __current_pos;
-            __current_pos                            = __again_pos;
-          }
-          return __current_pos;
+
+        __current += __len;
+      } break;
+
+      case __match_character_list:
+      case __match_no_character_list: {
+        if (__current == __last)
+          return {false, __counter};
+        if (auto [__success, __digraph, __new_pos] =
+                __exec_match_character_list(__code, __last, __current, __gstate, __current_pos);
+            __success != (__st == __match_character_list))
+          return {false, __counter};
+        else {
+          __current_pos = __new_pos;
+          ++__current; // Swallow the matched character
+          if (__digraph)
+            ++__current; // Swallow the second character of a digraph
         }
-        return __current_pos;
+      } break;
+
+      case __marked_subexpression_begin: {
+        auto __match                  = __read_uleb(__code, __current_pos);
+        __sub_matches_[__match].first = __current;
+      } break;
+
+      case __marked_subexpression_end: {
+        auto __match                    = __read_uleb(__code, __current_pos);
+        __sub_matches_[__match].second  = __current;
+        __sub_matches_[__match].matched = true;
+      } break;
+
+      case __match_word_boundary: {
+        if (!__is_word_boundary(__first, __last, __current, __gstate))
+          return {false, __counter};
+      } break;
+
+      case __match_no_word_boundary: {
+        if (__is_word_boundary(__first, __last, __current, __gstate))
+          return {false, __counter};
+      } break;
+
+      case __negative_lookahead:
+      case __positive_lookahead: {
+        if (auto __result =
+                __exec_lookahead(__first, __last, __gstate, __code, __current_pos, (__st == __positive_lookahead));
+            __result.first)
+          __current_pos = __result.second;
+        else
+          return {false, __counter};
+      } break;
+
+      default:
+        std::__libcpp_unreachable();
       }
+    }
+  }
+};
 
-      pair<bool, size_t> __execute(const _CharT* __first, const _CharT* __last, __global_execution_state& __gstate) {
-        const __interpreter_info<_CharT>* const __code = __gstate.__machine().data();
-        auto __current_pos                             = __current_pos_;
-        auto __counter                                 = 0;
-        auto __current                                 = __current_;
-        auto __commit_current                          = std::__make_scope_guard([&] { __current_ = __current; });
-        while (true) {
-          ++__counter;
-          auto __st = __code[__current_pos++].__state_;
-          switch (__st) {
-            using enum __state;
-
-          case __multiline_start_anchor:
-            if (!(__gstate.__flags_ & regex_constants::__at_first) && (__current[-1] == '\n' || __current[-1] == '\r'))
-              break;
-            [[__fallthrough__]];
-          case __start_anchor: {
-            if (__gstate.__flags_ & regex_constants::match_not_bol ||
-                !(__gstate.__flags_ & regex_constants::__at_first) || __first != __current)
-              return {false, __counter};
-          } break;
-
-          case __multiline_end_anchor:
-            if (__current[0] == '\r' || __current[0] == '\n')
-              break;
-            [[__fallthrough__]];
-          case __end_anchor: {
-            if (__gstate.__flags_ & regex_constants::match_not_eol || __current != __last)
-              return {false, __counter};
-          } break;
-
-          case __end_state: {
-            return {(!(__gstate.__flags_ & regex_constants::match_not_null) || __current != __first) &&
-                        (!(__gstate.__flags_ & regex_constants::match_flag_type::__full_match) || __current == __last),
-                    __counter};
-          }
+template <class _CharT, class _Traits>
+class __interpreter;
 
-          case __match_any: {
-            if (__current == __last)
-              return {false, __counter};
-            ++__current;
-          } break;
-
-          case __match_any_except_newline: {
-            if (__current == __last || *__current == '\r' || *__current == '\n')
-              return {false, __counter};
-            if constexpr (__is_same(_CharT, wchar_t)) {
-              if (*__current == 0x2028 || *__current == 0x2029)
-                return {false, __counter};
-            }
-            ++__current;
-          } break;
-
-          case __match_char: {
-            if (__current == __last || *__current != __code[__current_pos++].__char_)
-              return {false, __counter};
-            ++__current;
-          } break;
-
-          case __match_icase_char: {
-            if (__current == __last ||
-                __gstate.__machine_.__traits_.translate_nocase(*__current) != __code[__current_pos++].__char_)
-              return {false, __counter};
-            ++__current;
-          } break;
-
-          case __branch_alternative: {
-            auto __offset = __read_uleb(__code, __current_pos);
-            __copy_to(__current, __gstate.__states_, __gstate);
-            __gstate.__states_.back().__current_pos_ = __current_pos + __offset;
-            break;
-          }
+template <class _CharT, class _Traits>
+struct __global_execution_state {
+  vector<__local_execution_state<_CharT, _Traits>> __states_;
+  const __interpreter<_CharT, _Traits>& __machine_;
+  regex_constants::match_flag_type __flags_;
 
-          case __relative_jump: {
-            __current_pos += __read_uleb(__code, __current_pos);
-            break;
-          }
+  const vector<__interpreter_info<_CharT>>& __machine() { return __machine_.__machine_; }
 
-          case __branch_n_to_m_matcher:
-          case __branch_nongreedy_n_to_m_matcher: {
-            __current_pos = __exec_branch_n_to_m_matcher(
-                __gstate, __code, __current, __current_pos, __st != __branch_nongreedy_n_to_m_matcher);
-          } break;
-
-          case __match_backref: {
-            sub_match<const _CharT*>& __match = __sub_matches_[__read_uleb(__code, __current_pos) - 1];
-            if (!__match.matched)
-              return {false, __counter};
-
-            auto __len = __match.second - __match.first;
-            if (__last - __current < __len || !std::equal(__match.first, __match.second, __current))
-              return {false, __counter};
-
-            __current += __len;
-          } break;
-
-          case __match_icase_backref: {
-            sub_match<const _CharT*>& __match = __sub_matches_[__read_uleb(__code, __current_pos) - 1];
-            if (!__match.matched)
-              return {false, __counter};
-
-            auto __len = __match.second - __match.first;
-            if (__last - __current < __len)
-              return {false, __counter};
-
-            for (ptrdiff_t __i = 0; __i != __len; ++__i) {
-              if (__gstate.__machine_.__traits_.translate_nocase(__match.first[__i]) !=
-                  __gstate.__machine_.__traits_.translate_nocase(__current[__i]))
-                return {false, __counter};
-            }
-
-            __current += __len;
-          } break;
-
-          case __match_character_list:
-          case __match_no_character_list: {
-            if (__current == __last)
-              return {false, __counter};
-            if (auto [__success, __digraph, __new_pos] =
-                    __exec_match_character_list(__code, __last, __current, __gstate, __current_pos);
-                __success != (__st == __match_character_list))
-              return {false, __counter};
-            else {
-              __current_pos = __new_pos;
-              ++__current; // Swallow the matched character
-              if (__digraph)
-                ++__current; // Swallow the second character of a digraph
-            }
-          } break;
-
-          case __marked_subexpression_begin: {
-            auto __match                  = __read_uleb(__code, __current_pos);
-            __sub_matches_[__match].first = __current;
-          } break;
-
-          case __marked_subexpression_end: {
-            auto __match                    = __read_uleb(__code, __current_pos);
-            __sub_matches_[__match].second  = __current;
-            __sub_matches_[__match].matched = true;
-          } break;
-
-          case __match_word_boundary: {
-            if (!__is_word_boundary(__first, __last, __current, __gstate))
-              return {false, __counter};
-          } break;
-
-          case __match_no_word_boundary: {
-            if (__is_word_boundary(__first, __last, __current, __gstate))
-              return {false, __counter};
-          } break;
-
-          case __negative_lookahead:
-          case __positive_lookahead: {
-            if (auto __result =
-                    __exec_lookahead(__first, __last, __gstate, __code, __current_pos, (__st == __positive_lookahead));
-                __result.first)
-              __current_pos = __result.second;
-            else
-              return {false, __counter};
-          } break;
-
-          default:
-            std::__libcpp_unreachable();
+  bool __execute(const _CharT* __first, const _CharT* __last) {
+    size_t __length = __last - __first + 1;
+    if (__machine_.__find_longest_) {
+      __local_execution_state<_CharT, _Traits> __best_state;
+      bool __found_match = false;
+      size_t __gcounter  = 0;
+      while (!__states_.empty()) {
+        if (__gcounter / _LIBCPP_REGEX_COMPLEXITY_FACTOR >= __length)
+          std::__throw_regex_error<regex_constants::error_complexity>();
+        auto __state = std::move(__states_.back());
+        __states_.pop_back();
+        auto [__success, __counter] = __state.__execute(__first, __last, *this);
+        __gcounter += __counter;
+        if (__success) {
+          if (!__found_match || __best_state.__current_ < __state.__current_)
+            __best_state = std::move(__state);
+          if (__best_state.__current_ == __last) {
+            __states_.push_back(std::move(__best_state));
+            return true;
           }
+          __found_match = true;
         }
       }
-    };
-
-    const vector<__interpreter_info<_CharT>>& __machine() { return __machine_.__machine_; }
-
-    bool __execute(const _CharT* __first, const _CharT* __last) {
-      size_t __length = __last - __first + 1;
-      if (__machine_.__find_longest_) {
-        __local_execution_state __best_state;
-        bool __found_match = false;
-        size_t __gcounter  = 0;
-        while (!__states_.empty()) {
-          if (__gcounter / _LIBCPP_REGEX_COMPLEXITY_FACTOR >= __length)
-            std::__throw_regex_error<regex_constants::error_complexity>();
-          auto __state = std::move(__states_.back());
-          __states_.pop_back();
-          auto [__success, __counter] = __state.__execute(__first, __last, *this);
+      __states_.push_back(std::move(__best_state));
+      return __found_match;
+    } else {
+      size_t __gcounter = 0;
+      while (!__states_.empty()) {
+        if (__gcounter / _LIBCPP_REGEX_COMPLEXITY_FACTOR >= __length)
+          std::__throw_regex_error<regex_constants::error_complexity>();
+        auto __state = std::move(__states_.back());
+        __states_.pop_back();
+        if (auto [__success, __counter] = __state.__execute(__first, __last, *this); __success) {
+          __states_.push_back(std::move(__state));
+          return true;
+        } else {
           __gcounter += __counter;
-          if (__success) {
-            if (!__found_match || __best_state.__current_ < __state.__current_)
-              __best_state = std::move(__state);
-            if (__best_state.__current_ == __last) {
-              __states_.push_back(std::move(__best_state));
-              return true;
-            }
-            __found_match = true;
-          }
-        }
-        __states_.push_back(std::move(__best_state));
-        return __found_match;
-      } else {
-        size_t __gcounter = 0;
-        while (!__states_.empty()) {
-          if (__gcounter / _LIBCPP_REGEX_COMPLEXITY_FACTOR >= __length)
-            std::__throw_regex_error<regex_constants::error_complexity>();
-          auto __state = std::move(__states_.back());
-          __states_.pop_back();
-          if (auto [__success, __counter] = __state.__execute(__first, __last, *this); __success) {
-            __states_.push_back(std::move(__state));
-            return true;
-          } else {
-            __gcounter += __counter;
-          }
         }
-        return false;
       }
+      return false;
     }
-  };
+  }
+};
+
+template <class _CharT, class _Traits>
+class __interpreter {
+  friend __local_execution_state<_CharT, _Traits>;
+  friend __global_execution_state<_CharT, _Traits>;
+
+  vector<__interpreter_info<_CharT> > __machine_;
+  vector<size_t> __initial_loop_values_;
+  _Traits __traits_;
+  bool __find_longest_;
 
   void push_back(__interpreter_info<_CharT> __info) { __machine_.push_back(__info); }
 
@@ -797,7 +803,7 @@ class __interpreter {
             const _CharT* __first,
             const _CharT* __last,
             vector<sub_match<const _CharT*>>& __sub_matches) const {
-    using __local_state = typename __global_execution_state::__local_execution_state;
+    using __local_state = __local_execution_state<_CharT, _Traits>;
 
     __local_state __base_state{
         .__current_     = __first,

>From 9ef0af3afbc86b9c3279bb4999cef1ab27153fc6 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Sun, 29 Mar 2026 03:50:24 +0200
Subject: [PATCH 07/21] [libc++] Make the sub_match representation more compact
 for running the interpreter

---
 libcxx/include/__regex/interpreter.h | 36 ++++++++++++++++++----------
 1 file changed, 23 insertions(+), 13 deletions(-)

diff --git a/libcxx/include/__regex/interpreter.h b/libcxx/include/__regex/interpreter.h
index 5a52d5bb26eeb..4355b644b0306 100644
--- a/libcxx/include/__regex/interpreter.h
+++ b/libcxx/include/__regex/interpreter.h
@@ -154,7 +154,7 @@ struct __local_execution_state {
   using __global_state = __global_execution_state<_CharT, _Traits>;
 
   const _CharT* __current_;
-  vector<sub_match<const _CharT*> > __sub_matches_;
+  vector<pair<const _CharT*, const _CharT*>> __sub_matches_;
   size_t __current_pos_;
   unique_ptr<size_t[]> __loop_values_;
   unique_ptr<const _CharT*[]> __loop_starts_;
@@ -497,8 +497,8 @@ struct __local_execution_state {
       } break;
 
       case __match_backref: {
-        sub_match<const _CharT*>& __match = __sub_matches_[__read_uleb(__code, __current_pos) - 1];
-        if (!__match.matched)
+        auto& __match = __sub_matches_[__read_uleb(__code, __current_pos) - 1];
+        if (__match.first == nullptr)
           return {false, __counter};
 
         auto __len = __match.second - __match.first;
@@ -509,8 +509,8 @@ struct __local_execution_state {
       } break;
 
       case __match_icase_backref: {
-        sub_match<const _CharT*>& __match = __sub_matches_[__read_uleb(__code, __current_pos) - 1];
-        if (!__match.matched)
+        auto& __match = __sub_matches_[__read_uleb(__code, __current_pos) - 1];
+        if (__match.first == nullptr)
           return {false, __counter};
 
         auto __len = __match.second - __match.first;
@@ -548,9 +548,8 @@ struct __local_execution_state {
       } break;
 
       case __marked_subexpression_end: {
-        auto __match                    = __read_uleb(__code, __current_pos);
-        __sub_matches_[__match].second  = __current;
-        __sub_matches_[__match].matched = true;
+        auto __match                   = __read_uleb(__code, __current_pos);
+        __sub_matches_[__match].second = __current;
       } break;
 
       case __match_word_boundary: {
@@ -805,9 +804,20 @@ class __interpreter {
             vector<sub_match<const _CharT*>>& __sub_matches) const {
     using __local_state = __local_execution_state<_CharT, _Traits>;
 
+    auto __copy_to_submatches =
+        [&](const vector<pair<const _CharT*, const _CharT*>>& __from, vector<sub_match<const _CharT*>>& __to) {
+          std::transform(__from.begin(), __from.end(), __to.begin(), [&](pair<const _CharT*, const _CharT*> __v) {
+            sub_match<const _CharT*> __ret;
+            __ret.first   = __v.first ? __v.first : __last;
+            __ret.second  = __v.first ? __v.second : __last;
+            __ret.matched = __v.first;
+            return __ret;
+          });
+        };
+
     __local_state __base_state{
         .__current_     = __first,
-        .__sub_matches_ = std::move(__sub_matches),
+        .__sub_matches_ = vector<pair<const _CharT*, const _CharT*>>(__sub_matches.size()),
         .__current_pos_ = 0,
         .__loop_values_ = __initial_loop_values_.empty()
                             ? nullptr
@@ -836,7 +846,7 @@ class __interpreter {
           if (!__found_match || __best_state.__current_ < __state.__current_)
             __best_state = std::move(__state);
           if (__best_state.__current_ == __last) {
-            __sub_matches = std::move(__best_state.__sub_matches_);
+            __copy_to_submatches(__best_state.__sub_matches_, __sub_matches);
             return {true, __best_state.__current_};
           }
           __found_match = true;
@@ -844,11 +854,11 @@ class __interpreter {
       }
       if (!__found_match)
         return {false, {}};
-      __sub_matches = std::move(__best_state.__sub_matches_);
+      __copy_to_submatches(__best_state.__sub_matches_, __sub_matches);
       return {true, __best_state.__current_};
     } else {
       if (__base_state_matched) {
-        __sub_matches = std::move(__base_state.__sub_matches_);
+        __copy_to_submatches(__base_state.__sub_matches_, __sub_matches);
         return {true, __base_state.__current_};
       }
       while (!__gexec_state.__states_.empty()) {
@@ -857,7 +867,7 @@ class __interpreter {
         auto __state = std::move(__gexec_state.__states_.back());
         __gexec_state.__states_.pop_back();
         if (auto [__success, __counter] = __state.__execute(__first, __last, __gexec_state); __success) {
-          __sub_matches = std::move(__state.__sub_matches_);
+          __copy_to_submatches(__state.__sub_matches_, __sub_matches);
           return {true, __state.__current_};
         } else {
           __gcounter += __counter;

>From d515e58b1191baf6df1a9ca686050796a84c6836 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Mon, 30 Mar 2026 03:12:13 +0200
Subject: [PATCH 08/21] Avoid allocating sub_matches

---
 libcxx/include/__regex/interpreter.h | 29 +++++++++++++++-------------
 libcxx/include/regex                 |  4 ++++
 2 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/libcxx/include/__regex/interpreter.h b/libcxx/include/__regex/interpreter.h
index 4355b644b0306..c113fb6b85951 100644
--- a/libcxx/include/__regex/interpreter.h
+++ b/libcxx/include/__regex/interpreter.h
@@ -801,23 +801,26 @@ class __interpreter {
   __execute(regex_constants::match_flag_type __flags,
             const _CharT* __first,
             const _CharT* __last,
+            size_t __submatch_count,
             vector<sub_match<const _CharT*>>& __sub_matches) const {
     using __local_state = __local_execution_state<_CharT, _Traits>;
 
     auto __copy_to_submatches =
         [&](const vector<pair<const _CharT*, const _CharT*>>& __from, vector<sub_match<const _CharT*>>& __to) {
-          std::transform(__from.begin(), __from.end(), __to.begin(), [&](pair<const _CharT*, const _CharT*> __v) {
-            sub_match<const _CharT*> __ret;
-            __ret.first   = __v.first ? __v.first : __last;
-            __ret.second  = __v.first ? __v.second : __last;
-            __ret.matched = __v.first;
-            return __ret;
-          });
+          __to.clear();
+          std::transform(
+              __from.begin(), __from.end(), std::back_inserter(__to), [&](pair<const _CharT*, const _CharT*> __v) {
+                sub_match<const _CharT*> __ret;
+                __ret.first   = __v.first ? __v.first : __last;
+                __ret.second  = __v.first ? __v.second : __last;
+                __ret.matched = __v.first;
+                return __ret;
+              });
         };
 
     __local_state __base_state{
         .__current_     = __first,
-        .__sub_matches_ = vector<pair<const _CharT*, const _CharT*>>(__sub_matches.size()),
+        .__sub_matches_ = vector<pair<const _CharT*, const _CharT*>>(__submatch_count),
         .__current_pos_ = 0,
         .__loop_values_ = __initial_loop_values_.empty()
                             ? nullptr
@@ -884,12 +887,13 @@ class __interpreter {
     __unmatched.second  = __last;
     __unmatched.matched = false;
 
-    vector<sub_match<const _CharT*>> __sub_matches(__marked_count, __unmatched);
+    vector<sub_match<const _CharT*>> __sub_matches;
     if (auto [__success, __last_val] = __execute(
             __flags | ((__flags & regex_constants::__no_update_pos) ? regex_constants::match_flag_type()
                                                                     : regex_constants::__at_first),
             __first,
             __last,
+            __marked_count,
             __sub_matches);
         __success) {
       return {__first, __last_val, std::move(__sub_matches)};
@@ -901,14 +905,13 @@ class __interpreter {
     __flags |= regex_constants::match_prev_avail;
 
     for (++__first; __first != __last; ++__first) {
-      __sub_matches.assign(__marked_count, __unmatched);
-      if (auto [__success, __last_val] = __execute(__flags, __first, __last, __sub_matches); __success) {
+      if (auto [__success, __last_val] = __execute(__flags, __first, __last, __marked_count, __sub_matches);
+          __success) {
         return {__first, __last_val, std::move(__sub_matches)};
       }
     }
 
-    __sub_matches.assign(__marked_count, __unmatched);
-    if (auto [__success, __last_val] = __execute(__flags, __first, __last, __sub_matches); __success) {
+    if (auto [__success, __last_val] = __execute(__flags, __first, __last, __marked_count, __sub_matches); __success) {
       return {__first, __last_val, std::move(__sub_matches)};
     }
 
diff --git a/libcxx/include/regex b/libcxx/include/regex
index c0011c954cc26..87dc675960757 100644
--- a/libcxx/include/regex
+++ b/libcxx/include/regex
@@ -1292,6 +1292,7 @@ public:
         __state.__flags_ | (__state.__at_first_ ? regex_constants::__at_first : regex_constants::match_flag_type()),
         __state.__first_,
         __state.__last_,
+        __state.__sub_matches_.size(),
         __state.__sub_matches_);
     __state.__do_      = __res.first ? std::__state<_CharT>::__end_state : std::__state<_CharT>::__reject;
     __state.__current_ = __res.second;
@@ -1306,6 +1307,9 @@ public:
   }
 };
 
+static_assert(sizeof(__regex::__global_execution_state<char, regex_traits<char>>) == 40);
+static_assert(sizeof(__regex::__local_execution_state<char, regex_traits<char>>) == 56);
+
 template <class _CharT, class _Traits = regex_traits<_CharT> >
 class basic_regex;
 

>From 26239ece621942107144d65eab0da581f0383534 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Mon, 30 Mar 2026 04:27:43 +0200
Subject: [PATCH 09/21] Avoid extra __local_state on the stack

---
 libcxx/include/__regex/interpreter.h | 27 ++++++++++++++-------------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/libcxx/include/__regex/interpreter.h b/libcxx/include/__regex/interpreter.h
index c113fb6b85951..c321994eaa33e 100644
--- a/libcxx/include/__regex/interpreter.h
+++ b/libcxx/include/__regex/interpreter.h
@@ -836,8 +836,9 @@ class __interpreter {
 
     size_t __length = __last - __first + 1;
     if (__gexec_state.__machine_.__find_longest_) {
-      __local_state __best_state = __base_state_matched ? std::move(__base_state) : __local_state{};
-      bool __found_match         = __base_state_matched;
+      if (!__base_state_matched)
+        __base_state.__current_ = __first;
+      bool __found_match = __base_state_matched;
       while (!__gexec_state.__states_.empty()) {
         if (__gcounter / _LIBCPP_REGEX_COMPLEXITY_FACTOR >= __length)
           std::__throw_regex_error<regex_constants::error_complexity>();
@@ -846,19 +847,19 @@ class __interpreter {
         auto [__success, __counter] = __state.__execute(__first, __last, __gexec_state);
         __gcounter += __counter;
         if (__success) {
-          if (!__found_match || __best_state.__current_ < __state.__current_)
-            __best_state = std::move(__state);
-          if (__best_state.__current_ == __last) {
-            __copy_to_submatches(__best_state.__sub_matches_, __sub_matches);
-            return {true, __best_state.__current_};
+          if (!__found_match || __base_state.__current_ < __state.__current_)
+            __base_state = std::move(__state);
+          if (__base_state.__current_ == __last) {
+            __copy_to_submatches(__base_state.__sub_matches_, __sub_matches);
+            return {true, __base_state.__current_};
           }
           __found_match = true;
         }
       }
       if (!__found_match)
         return {false, {}};
-      __copy_to_submatches(__best_state.__sub_matches_, __sub_matches);
-      return {true, __best_state.__current_};
+      __copy_to_submatches(__base_state.__sub_matches_, __sub_matches);
+      return {true, __base_state.__current_};
     } else {
       if (__base_state_matched) {
         __copy_to_submatches(__base_state.__sub_matches_, __sub_matches);
@@ -867,11 +868,11 @@ class __interpreter {
       while (!__gexec_state.__states_.empty()) {
         if (__gcounter / _LIBCPP_REGEX_COMPLEXITY_FACTOR >= __length)
           std::__throw_regex_error<regex_constants::error_complexity>();
-        auto __state = std::move(__gexec_state.__states_.back());
+        __base_state = std::move(__gexec_state.__states_.back());
         __gexec_state.__states_.pop_back();
-        if (auto [__success, __counter] = __state.__execute(__first, __last, __gexec_state); __success) {
-          __copy_to_submatches(__state.__sub_matches_, __sub_matches);
-          return {true, __state.__current_};
+        if (auto [__success, __counter] = __base_state.__execute(__first, __last, __gexec_state); __success) {
+          __copy_to_submatches(__base_state.__sub_matches_, __sub_matches);
+          return {true, __base_state.__current_};
         } else {
           __gcounter += __counter;
         }

>From f7ed041393a8c68d77e78daec267012505f4d2d9 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Mon, 30 Mar 2026 11:08:04 +0200
Subject: [PATCH 10/21] Make local state smaller

---
 libcxx/include/__regex/interpreter.h | 46 +++++++++++++++-------------
 libcxx/include/regex                 |  2 +-
 2 files changed, 26 insertions(+), 22 deletions(-)

diff --git a/libcxx/include/__regex/interpreter.h b/libcxx/include/__regex/interpreter.h
index c321994eaa33e..9cc2dab5ce036 100644
--- a/libcxx/include/__regex/interpreter.h
+++ b/libcxx/include/__regex/interpreter.h
@@ -146,6 +146,16 @@ struct __search_result {
   ~__search_result() {}
 };
 
+template <class _CharT>
+union __loop_value {
+  __loop_value() = default;
+  __loop_value(size_t __v) : __int_(__v) {}
+  __loop_value(const _CharT* __v) : __ptr_(__v) {}
+
+  size_t __int_;
+  const _CharT* __ptr_;
+};
+
 template <class _CharT, class _Traits>
 struct __global_execution_state;
 
@@ -156,8 +166,7 @@ struct __local_execution_state {
   const _CharT* __current_;
   vector<pair<const _CharT*, const _CharT*>> __sub_matches_;
   size_t __current_pos_;
-  unique_ptr<size_t[]> __loop_values_;
-  unique_ptr<const _CharT*[]> __loop_starts_;
+  unique_ptr<__loop_value<_CharT>[]> __loop_values_;
 
   static pair<size_t, size_t>
   __read_uleb_impl(_LIBCPP_NOESCAPE const __interpreter_info<_CharT>* __machine, size_t __current_pos) {
@@ -185,12 +194,9 @@ struct __local_execution_state {
 
   void __copy_to(const _CharT* const __current, vector<__local_execution_state>& __vec, __global_state& __gstate) {
     auto __loop_value_count = __gstate.__machine_.__initial_loop_values_.size();
-    auto __loop_values_copy = std::make_unique_for_overwrite<size_t[]>(__loop_value_count);
+    auto __loop_values_copy = std::make_unique_for_overwrite<__loop_value<_CharT>[]>(__loop_value_count);
     std::copy_n(__loop_values_.get(), __loop_value_count, __loop_values_copy.get());
-    auto __loop_starts_copy = std::make_unique_for_overwrite<const _CharT*[]>(__loop_value_count);
-    std::copy_n(__loop_starts_.get(), __loop_value_count, __loop_starts_copy.get());
-    __vec.emplace_back(
-        __current, __sub_matches_, __current_pos_, std::move(__loop_values_copy), std::move(__loop_starts_copy));
+    __vec.emplace_back(__current, __sub_matches_, __current_pos_, std::move(__loop_values_copy));
   }
 
   static bool __is_word_boundary(
@@ -357,7 +363,7 @@ struct __local_execution_state {
     auto __submatch_base  = __read_uleb(__code, __current_pos);
     auto __loop_count     = __read_uleb(__code, __current_pos);
 
-    unique_ptr<size_t[]> __initial_loop_values = std::make_unique_for_overwrite<size_t[]>(__loop_count);
+    auto __initial_loop_values = std::make_unique_for_overwrite<__loop_value<_CharT>[]>(__loop_count);
 
     for (size_t __i = 0; __i != __loop_count; ++__i)
       __initial_loop_values[__i] = __read_uleb(__code, __current_pos);
@@ -369,7 +375,6 @@ struct __local_execution_state {
       __s.__sub_matches_.resize(__submatch_count);
     __s.__current_     = __current_;
     __s.__loop_values_ = std::move(__initial_loop_values);
-    __s.__loop_starts_ = std::make_unique<const _CharT*[]>(__loop_count);
     __s.__current_pos_ = __current_pos;
     if (__gexec_state.__execute(__first, __last) != __is_positive)
       return {false, __current_pos};
@@ -392,14 +397,14 @@ struct __local_execution_state {
     auto __loop_index     = __read_uleb(__code, __current_pos);
     auto __again_pos_base = __current_pos;
     auto __again_pos      = __again_pos_base - __read_uleb(__code, __current_pos);
-    if (__loop_values_[__loop_index] > 0) {
-      --__loop_values_[__loop_index];
+    if (__loop_values_[__loop_index + 1].__int_ > 0) {
+      --__loop_values_[__loop_index + 1].__int_;
       __current_pos = __again_pos;
       return __current_pos;
     }
-    if (__loop_starts_[__loop_index] != __current && __loop_values_[__loop_index + 1] > 0) {
-      --__loop_values_[__loop_index + 1];
-      __loop_starts_[__loop_index] = __current;
+    if (__loop_values_[__loop_index].__ptr_ != __current && __loop_values_[__loop_index + 2].__int_ > 0) {
+      --__loop_values_[__loop_index + 2].__int_;
+      __loop_values_[__loop_index] = __current;
       __copy_to(__current, __gstate.__states_, __gstate);
       if (!__is_greedy) {
         __gstate.__states_.back().__current_pos_ = __again_pos;
@@ -640,7 +645,7 @@ class __interpreter {
   friend __global_execution_state<_CharT, _Traits>;
 
   vector<__interpreter_info<_CharT> > __machine_;
-  vector<size_t> __initial_loop_values_;
+  vector<__loop_value<_CharT>> __initial_loop_values_;
   _Traits __traits_;
   bool __find_longest_;
 
@@ -720,6 +725,7 @@ class __interpreter {
     push_back(__greedy ? __state::__branch_n_to_m_matcher : __state::__branch_nongreedy_n_to_m_matcher);
     __write_uleb(__machine_, __initial_loop_values_.size());
     __write_uleb(__machine_, size() - __expr_start);
+    __initial_loop_values_.push_back(nullptr);
     __initial_loop_values_.push_back(__min);
     __initial_loop_values_.push_back(__max - __min);
   }
@@ -771,7 +777,7 @@ class __interpreter {
   void __push_no_word_boundary() { push_back(__state::__match_no_word_boundary); }
 
   struct __lookahead_info {
-    vector<size_t> __initial_loop_values_;
+    vector<__loop_value<_CharT>> __initial_loop_values_;
     size_t __lookahead_start_;
   };
 
@@ -790,8 +796,8 @@ class __interpreter {
     __write_uleb(__buffer, __marked_count);
     __write_uleb(__buffer, __marked_base);
     __write_uleb(__buffer, __initial_loop_values_.size());
-    for (size_t __val : __initial_loop_values_)
-      __write_uleb(__buffer, __val);
+    for (__loop_value<_CharT> __val : __initial_loop_values_)
+      __write_uleb(__buffer, __val.__int_);
     insert(__info.__lookahead_start_, __buffer);
   }
 
@@ -824,9 +830,7 @@ class __interpreter {
         .__current_pos_ = 0,
         .__loop_values_ = __initial_loop_values_.empty()
                             ? nullptr
-                            : std::make_unique_for_overwrite<size_t[]>(__initial_loop_values_.size()),
-        .__loop_starts_ =
-            __initial_loop_values_.empty() ? nullptr : std::make_unique<const _CharT*[]>(__initial_loop_values_.size()),
+                            : std::make_unique_for_overwrite<__loop_value<_CharT>[]>(__initial_loop_values_.size()),
     };
     if (!__initial_loop_values_.empty())
       std::copy(__initial_loop_values_.begin(), __initial_loop_values_.end(), __base_state.__loop_values_.get());
diff --git a/libcxx/include/regex b/libcxx/include/regex
index 87dc675960757..afef6f985b9c4 100644
--- a/libcxx/include/regex
+++ b/libcxx/include/regex
@@ -1308,7 +1308,7 @@ public:
 };
 
 static_assert(sizeof(__regex::__global_execution_state<char, regex_traits<char>>) == 40);
-static_assert(sizeof(__regex::__local_execution_state<char, regex_traits<char>>) == 56);
+static_assert(sizeof(__regex::__local_execution_state<char, regex_traits<char>>) == 48);
 
 template <class _CharT, class _Traits = regex_traits<_CharT> >
 class basic_regex;

>From 4fd5f16edd278c0c4b73ecdc1fa54313dedf7e36 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Mon, 30 Mar 2026 11:33:01 +0200
Subject: [PATCH 11/21] Make the local state more compact

---
 libcxx/include/__regex/interpreter.h | 35 +++++++++++++++-------------
 libcxx/include/regex                 |  4 ++--
 2 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/libcxx/include/__regex/interpreter.h b/libcxx/include/__regex/interpreter.h
index 9cc2dab5ce036..4f32620287b3e 100644
--- a/libcxx/include/__regex/interpreter.h
+++ b/libcxx/include/__regex/interpreter.h
@@ -164,7 +164,7 @@ struct __local_execution_state {
   using __global_state = __global_execution_state<_CharT, _Traits>;
 
   const _CharT* __current_;
-  vector<pair<const _CharT*, const _CharT*>> __sub_matches_;
+  unique_ptr<pair<const _CharT*, const _CharT*>[]> __sub_matches_;
   size_t __current_pos_;
   unique_ptr<__loop_value<_CharT>[]> __loop_values_;
 
@@ -196,7 +196,10 @@ struct __local_execution_state {
     auto __loop_value_count = __gstate.__machine_.__initial_loop_values_.size();
     auto __loop_values_copy = std::make_unique_for_overwrite<__loop_value<_CharT>[]>(__loop_value_count);
     std::copy_n(__loop_values_.get(), __loop_value_count, __loop_values_copy.get());
-    __vec.emplace_back(__current, __sub_matches_, __current_pos_, std::move(__loop_values_copy));
+    auto __sub_matches =
+        std::make_unique_for_overwrite<pair<const _CharT*, const _CharT*>[]>(__gstate.__submatch_count_);
+    std::copy_n(__sub_matches_.get(), __gstate.__submatch_count_, __sub_matches.get());
+    __vec.emplace_back(__current, std::move(__sub_matches), __current_pos_, std::move(__loop_values_copy));
   }
 
   static bool __is_word_boundary(
@@ -368,11 +371,11 @@ struct __local_execution_state {
     for (size_t __i = 0; __i != __loop_count; ++__i)
       __initial_loop_values[__i] = __read_uleb(__code, __current_pos);
 
-    __global_state __gexec_state{{}, __gstate.__machine_, __gstate.__flags_};
+    __global_state __gexec_state{{}, __gstate.__machine_, __submatch_count, __gstate.__flags_};
     __gexec_state.__flags_ &= ~regex_constants::__full_match;
     auto& __s = __gexec_state.__states_.emplace_back();
     if (__loop_count > 0)
-      __s.__sub_matches_.resize(__submatch_count);
+      __s.__sub_matches_ = std::make_unique<pair<const _CharT*, const _CharT*>[]>(__submatch_count);
     __s.__current_     = __current_;
     __s.__loop_values_ = std::move(__initial_loop_values);
     __s.__current_pos_ = __current_pos;
@@ -380,9 +383,7 @@ struct __local_execution_state {
       return {false, __current_pos};
     if (__is_positive) {
       auto& __matched_state = __gexec_state.__states_.back();
-      std::copy(__matched_state.__sub_matches_.begin(),
-                __matched_state.__sub_matches_.end(),
-                __sub_matches_.begin() + __submatch_base);
+      std::copy_n(__matched_state.__sub_matches_.get(), __submatch_count, __sub_matches_.get() + __submatch_base);
     }
     __current_pos += __jump_offset;
     return {true, __current_pos};
@@ -591,6 +592,7 @@ template <class _CharT, class _Traits>
 struct __global_execution_state {
   vector<__local_execution_state<_CharT, _Traits>> __states_;
   const __interpreter<_CharT, _Traits>& __machine_;
+  size_t __submatch_count_;
   regex_constants::match_flag_type __flags_;
 
   const vector<__interpreter_info<_CharT>>& __machine() { return __machine_.__machine_; }
@@ -812,10 +814,10 @@ class __interpreter {
     using __local_state = __local_execution_state<_CharT, _Traits>;
 
     auto __copy_to_submatches =
-        [&](const vector<pair<const _CharT*, const _CharT*>>& __from, vector<sub_match<const _CharT*>>& __to) {
+        [&](pair<const _CharT*, const _CharT*>* __from, size_t __count, vector<sub_match<const _CharT*>>& __to) {
           __to.clear();
           std::transform(
-              __from.begin(), __from.end(), std::back_inserter(__to), [&](pair<const _CharT*, const _CharT*> __v) {
+              __from, __from + __count, std::back_inserter(__to), [&](pair<const _CharT*, const _CharT*> __v) {
                 sub_match<const _CharT*> __ret;
                 __ret.first   = __v.first ? __v.first : __last;
                 __ret.second  = __v.first ? __v.second : __last;
@@ -825,8 +827,9 @@ class __interpreter {
         };
 
     __local_state __base_state{
-        .__current_     = __first,
-        .__sub_matches_ = vector<pair<const _CharT*, const _CharT*>>(__submatch_count),
+        .__current_ = __first,
+        .__sub_matches_ =
+            __submatch_count ? std::make_unique<pair<const _CharT*, const _CharT*>[]>(__submatch_count) : nullptr,
         .__current_pos_ = 0,
         .__loop_values_ = __initial_loop_values_.empty()
                             ? nullptr
@@ -835,7 +838,7 @@ class __interpreter {
     if (!__initial_loop_values_.empty())
       std::copy(__initial_loop_values_.begin(), __initial_loop_values_.end(), __base_state.__loop_values_.get());
 
-    __global_execution_state __gexec_state{{}, *this, __flags};
+    __global_execution_state __gexec_state{{}, *this, __submatch_count, __flags};
     auto [__base_state_matched, __gcounter] = __base_state.__execute(__first, __last, __gexec_state);
 
     size_t __length = __last - __first + 1;
@@ -854,7 +857,7 @@ class __interpreter {
           if (!__found_match || __base_state.__current_ < __state.__current_)
             __base_state = std::move(__state);
           if (__base_state.__current_ == __last) {
-            __copy_to_submatches(__base_state.__sub_matches_, __sub_matches);
+            __copy_to_submatches(__base_state.__sub_matches_.get(), __submatch_count, __sub_matches);
             return {true, __base_state.__current_};
           }
           __found_match = true;
@@ -862,11 +865,11 @@ class __interpreter {
       }
       if (!__found_match)
         return {false, {}};
-      __copy_to_submatches(__base_state.__sub_matches_, __sub_matches);
+      __copy_to_submatches(__base_state.__sub_matches_.get(), __submatch_count, __sub_matches);
       return {true, __base_state.__current_};
     } else {
       if (__base_state_matched) {
-        __copy_to_submatches(__base_state.__sub_matches_, __sub_matches);
+        __copy_to_submatches(__base_state.__sub_matches_.get(), __submatch_count, __sub_matches);
         return {true, __base_state.__current_};
       }
       while (!__gexec_state.__states_.empty()) {
@@ -875,7 +878,7 @@ class __interpreter {
         __base_state = std::move(__gexec_state.__states_.back());
         __gexec_state.__states_.pop_back();
         if (auto [__success, __counter] = __base_state.__execute(__first, __last, __gexec_state); __success) {
-          __copy_to_submatches(__base_state.__sub_matches_, __sub_matches);
+          __copy_to_submatches(__base_state.__sub_matches_.get(), __submatch_count, __sub_matches);
           return {true, __base_state.__current_};
         } else {
           __gcounter += __counter;
diff --git a/libcxx/include/regex b/libcxx/include/regex
index afef6f985b9c4..13492357a059d 100644
--- a/libcxx/include/regex
+++ b/libcxx/include/regex
@@ -1307,8 +1307,8 @@ public:
   }
 };
 
-static_assert(sizeof(__regex::__global_execution_state<char, regex_traits<char>>) == 40);
-static_assert(sizeof(__regex::__local_execution_state<char, regex_traits<char>>) == 48);
+static_assert(sizeof(__regex::__global_execution_state<char, regex_traits<char>>) == 48);
+static_assert(sizeof(__regex::__local_execution_state<char, regex_traits<char>>) == 32);
 
 template <class _CharT, class _Traits = regex_traits<_CharT> >
 class basic_regex;

>From 25585dcc4b57694bc3bd52f04dedd0163777dd6d Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Tue, 31 Mar 2026 03:08:52 +0200
Subject: [PATCH 12/21] Keep global state around

---
 libcxx/include/__regex/interpreter.h   | 56 +++++++++++++++-----------
 libcxx/include/regex                   |  2 +-
 libcxx/test/benchmarks/regex.bench.cpp | 11 +++++
 3 files changed, 45 insertions(+), 24 deletions(-)

diff --git a/libcxx/include/__regex/interpreter.h b/libcxx/include/__regex/interpreter.h
index 4f32620287b3e..9d5bf86bb7ca7 100644
--- a/libcxx/include/__regex/interpreter.h
+++ b/libcxx/include/__regex/interpreter.h
@@ -806,10 +806,9 @@ class __interpreter {
   size_t size() const { return __machine_.size(); }
 
   pair<bool, const _CharT*>
-  __execute(regex_constants::match_flag_type __flags,
+  __execute(__global_execution_state<_CharT, _Traits>& __gexec_state,
             const _CharT* __first,
             const _CharT* __last,
-            size_t __submatch_count,
             vector<sub_match<const _CharT*>>& __sub_matches) const {
     using __local_state = __local_execution_state<_CharT, _Traits>;
 
@@ -827,9 +826,10 @@ class __interpreter {
         };
 
     __local_state __base_state{
-        .__current_ = __first,
-        .__sub_matches_ =
-            __submatch_count ? std::make_unique<pair<const _CharT*, const _CharT*>[]>(__submatch_count) : nullptr,
+        .__current_     = __first,
+        .__sub_matches_ = __gexec_state.__submatch_count_
+                            ? std::make_unique<pair<const _CharT*, const _CharT*>[]>(__gexec_state.__submatch_count_)
+                            : nullptr,
         .__current_pos_ = 0,
         .__loop_values_ = __initial_loop_values_.empty()
                             ? nullptr
@@ -838,7 +838,6 @@ class __interpreter {
     if (!__initial_loop_values_.empty())
       std::copy(__initial_loop_values_.begin(), __initial_loop_values_.end(), __base_state.__loop_values_.get());
 
-    __global_execution_state __gexec_state{{}, *this, __submatch_count, __flags};
     auto [__base_state_matched, __gcounter] = __base_state.__execute(__first, __last, __gexec_state);
 
     size_t __length = __last - __first + 1;
@@ -857,7 +856,7 @@ class __interpreter {
           if (!__found_match || __base_state.__current_ < __state.__current_)
             __base_state = std::move(__state);
           if (__base_state.__current_ == __last) {
-            __copy_to_submatches(__base_state.__sub_matches_.get(), __submatch_count, __sub_matches);
+            __copy_to_submatches(__base_state.__sub_matches_.get(), __gexec_state.__submatch_count_, __sub_matches);
             return {true, __base_state.__current_};
           }
           __found_match = true;
@@ -865,11 +864,11 @@ class __interpreter {
       }
       if (!__found_match)
         return {false, {}};
-      __copy_to_submatches(__base_state.__sub_matches_.get(), __submatch_count, __sub_matches);
+      __copy_to_submatches(__base_state.__sub_matches_.get(), __gexec_state.__submatch_count_, __sub_matches);
       return {true, __base_state.__current_};
     } else {
       if (__base_state_matched) {
-        __copy_to_submatches(__base_state.__sub_matches_.get(), __submatch_count, __sub_matches);
+        __copy_to_submatches(__base_state.__sub_matches_.get(), __gexec_state.__submatch_count_, __sub_matches);
         return {true, __base_state.__current_};
       }
       while (!__gexec_state.__states_.empty()) {
@@ -878,7 +877,7 @@ class __interpreter {
         __base_state = std::move(__gexec_state.__states_.back());
         __gexec_state.__states_.pop_back();
         if (auto [__success, __counter] = __base_state.__execute(__first, __last, __gexec_state); __success) {
-          __copy_to_submatches(__base_state.__sub_matches_.get(), __submatch_count, __sub_matches);
+          __copy_to_submatches(__base_state.__sub_matches_.get(), __gexec_state.__submatch_count_, __sub_matches);
           return {true, __base_state.__current_};
         } else {
           __gcounter += __counter;
@@ -888,38 +887,49 @@ class __interpreter {
     }
   }
 
+  pair<bool, const _CharT*> __execute_match(
+      regex_constants::match_flag_type __flags,
+      const _CharT* __first,
+      const _CharT* __last,
+      size_t __submatch_count,
+      vector<sub_match<const _CharT*>>& __sub_matches) const {
+    __global_execution_state __gexec_state{{}, *this, __submatch_count, __flags};
+    return __execute(__gexec_state, __first, __last, __sub_matches);
+  }
+
   __search_result<_CharT> __execute_search(
-      const _CharT* __first, const _CharT* __last, regex_constants::match_flag_type __flags, size_t __marked_count) {
+      const _CharT* __first,
+      const _CharT* __last,
+      regex_constants::match_flag_type __flags,
+      size_t __marked_count) const {
     sub_match<const _CharT*> __unmatched;
     __unmatched.first   = __last;
     __unmatched.second  = __last;
     __unmatched.matched = false;
 
+    __global_execution_state __gexec_state{
+        {},
+        *this,
+        __marked_count,
+        __flags | ((__flags & regex_constants::__no_update_pos) ? regex_constants::match_flag_type()
+                                                                : regex_constants::__at_first)};
     vector<sub_match<const _CharT*>> __sub_matches;
-    if (auto [__success, __last_val] = __execute(
-            __flags | ((__flags & regex_constants::__no_update_pos) ? regex_constants::match_flag_type()
-                                                                    : regex_constants::__at_first),
-            __first,
-            __last,
-            __marked_count,
-            __sub_matches);
-        __success) {
+    if (auto [__success, __last_val] = __execute(__gexec_state, __first, __last, __sub_matches); __success) {
       return {__first, __last_val, std::move(__sub_matches)};
     }
 
     if (__first == __last || (__flags & regex_constants::match_continuous))
       return {};
 
-    __flags |= regex_constants::match_prev_avail;
+    __gexec_state.__flags_ = __flags | regex_constants::match_prev_avail;
 
     for (++__first; __first != __last; ++__first) {
-      if (auto [__success, __last_val] = __execute(__flags, __first, __last, __marked_count, __sub_matches);
-          __success) {
+      if (auto [__success, __last_val] = __execute(__gexec_state, __first, __last, __sub_matches); __success) {
         return {__first, __last_val, std::move(__sub_matches)};
       }
     }
 
-    if (auto [__success, __last_val] = __execute(__flags, __first, __last, __marked_count, __sub_matches); __success) {
+    if (auto [__success, __last_val] = __execute(__gexec_state, __first, __last, __sub_matches); __success) {
       return {__first, __last_val, std::move(__sub_matches)};
     }
 
diff --git a/libcxx/include/regex b/libcxx/include/regex
index 13492357a059d..6048744eeeae0 100644
--- a/libcxx/include/regex
+++ b/libcxx/include/regex
@@ -1288,7 +1288,7 @@ public:
       : __regex_search_state<_CharT>(__s), __machine_(std::move(__machine)) {}
 
   _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __exec(__state<_CharT>& __state) const override {
-    auto __res = __machine_.__execute(
+    auto __res = __machine_.__execute_match(
         __state.__flags_ | (__state.__at_first_ ? regex_constants::__at_first : regex_constants::match_flag_type()),
         __state.__first_,
         __state.__last_,
diff --git a/libcxx/test/benchmarks/regex.bench.cpp b/libcxx/test/benchmarks/regex.bench.cpp
index 8b218843dedc1..75174a7e71706 100644
--- a/libcxx/test/benchmarks/regex.bench.cpp
+++ b/libcxx/test/benchmarks/regex.bench.cpp
@@ -48,4 +48,15 @@ static void BM_regex_run_almost_match(benchmark::State& state) {
 }
 BENCHMARK(BM_regex_run_almost_match);
 
+static void BM_regex_run_any_matcher(benchmark::State& state) {
+  std::regex r(".*");
+  std::string input;
+  input.append(1 << 16, 'a');
+
+  for (auto _ : state) {
+    std::regex_search(input, r);
+  }
+}
+BENCHMARK(BM_regex_run_any_matcher);
+
 BENCHMARK_MAIN();

>From b7604c69c530c954e849dd3ab49437513610be4a Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Tue, 31 Mar 2026 04:04:02 +0200
Subject: [PATCH 13/21] Add preserve_none

---
 libcxx/include/__regex/interpreter.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libcxx/include/__regex/interpreter.h b/libcxx/include/__regex/interpreter.h
index 9d5bf86bb7ca7..3dec7c9294e7c 100644
--- a/libcxx/include/__regex/interpreter.h
+++ b/libcxx/include/__regex/interpreter.h
@@ -418,6 +418,7 @@ struct __local_execution_state {
     return __current_pos;
   }
 
+  [[clang::preserve_none]]
   pair<bool, size_t> __execute(const _CharT* __first, const _CharT* __last, __global_state& __gstate) {
     const __interpreter_info<_CharT>* const __code = __gstate.__machine().data();
     auto __current_pos                             = __current_pos_;
@@ -805,6 +806,7 @@ class __interpreter {
 
   size_t size() const { return __machine_.size(); }
 
+  [[clang::preserve_none]]
   pair<bool, const _CharT*>
   __execute(__global_execution_state<_CharT, _Traits>& __gexec_state,
             const _CharT* __first,

>From ce44d8eab490f0fdcff84506dc7be76c160b3e17 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Mon, 6 Apr 2026 14:26:47 +0200
Subject: [PATCH 14/21] Make state handling more efficient

---
 libcxx/include/__regex/interpreter.h | 246 ++++++++++++++++-----------
 libcxx/include/regex                 |   4 +-
 2 files changed, 153 insertions(+), 97 deletions(-)

diff --git a/libcxx/include/__regex/interpreter.h b/libcxx/include/__regex/interpreter.h
index 3dec7c9294e7c..5e081f2e99662 100644
--- a/libcxx/include/__regex/interpreter.h
+++ b/libcxx/include/__regex/interpreter.h
@@ -163,10 +163,14 @@ template <class _CharT, class _Traits>
 struct __local_execution_state {
   using __global_state = __global_execution_state<_CharT, _Traits>;
 
+  pair<const _CharT*, const _CharT*>& __get_submatch(size_t __n) {
+    return *reinterpret_cast<pair<const _CharT*, const _CharT*>*>(
+        reinterpret_cast<char*>(this) - sizeof(pair<const _CharT*, const _CharT*>) * (__n + 1));
+  }
+
   const _CharT* __current_;
-  unique_ptr<pair<const _CharT*, const _CharT*>[]> __sub_matches_;
   size_t __current_pos_;
-  unique_ptr<__loop_value<_CharT>[]> __loop_values_;
+  __loop_value<_CharT> __loop_values_[];
 
   static pair<size_t, size_t>
   __read_uleb_impl(_LIBCPP_NOESCAPE const __interpreter_info<_CharT>* __machine, size_t __current_pos) {
@@ -192,16 +196,6 @@ struct __local_execution_state {
     return __val;
   }
 
-  void __copy_to(const _CharT* const __current, vector<__local_execution_state>& __vec, __global_state& __gstate) {
-    auto __loop_value_count = __gstate.__machine_.__initial_loop_values_.size();
-    auto __loop_values_copy = std::make_unique_for_overwrite<__loop_value<_CharT>[]>(__loop_value_count);
-    std::copy_n(__loop_values_.get(), __loop_value_count, __loop_values_copy.get());
-    auto __sub_matches =
-        std::make_unique_for_overwrite<pair<const _CharT*, const _CharT*>[]>(__gstate.__submatch_count_);
-    std::copy_n(__sub_matches_.get(), __gstate.__submatch_count_, __sub_matches.get());
-    __vec.emplace_back(__current, std::move(__sub_matches), __current_pos_, std::move(__loop_values_copy));
-  }
-
   static bool __is_word_boundary(
       const _CharT* __first, const _CharT* __last, const _CharT* const __current, __global_state& __gstate) {
     auto __is_word_char = [&](char __c) {
@@ -354,40 +348,42 @@ struct __local_execution_state {
     return {__found, false, __current_pos};
   }
 
-  pair<bool, size_t> __exec_lookahead(
-      const _CharT* const __first,
-      const _CharT* const __last,
-      const __global_state& __gstate,
-      const __interpreter_info<_CharT>* const __code,
-      size_t __current_pos,
-      bool __is_positive) {
-    auto __jump_offset    = __read_uleb(__code, __current_pos);
-    auto __submatch_count = __read_uleb(__code, __current_pos);
-    auto __submatch_base  = __read_uleb(__code, __current_pos);
-    auto __loop_count     = __read_uleb(__code, __current_pos);
-
-    auto __initial_loop_values = std::make_unique_for_overwrite<__loop_value<_CharT>[]>(__loop_count);
-
-    for (size_t __i = 0; __i != __loop_count; ++__i)
-      __initial_loop_values[__i] = __read_uleb(__code, __current_pos);
-
-    __global_state __gexec_state{{}, __gstate.__machine_, __submatch_count, __gstate.__flags_};
-    __gexec_state.__flags_ &= ~regex_constants::__full_match;
-    auto& __s = __gexec_state.__states_.emplace_back();
-    if (__loop_count > 0)
-      __s.__sub_matches_ = std::make_unique<pair<const _CharT*, const _CharT*>[]>(__submatch_count);
-    __s.__current_     = __current_;
-    __s.__loop_values_ = std::move(__initial_loop_values);
-    __s.__current_pos_ = __current_pos;
-    if (__gexec_state.__execute(__first, __last) != __is_positive)
-      return {false, __current_pos};
-    if (__is_positive) {
-      auto& __matched_state = __gexec_state.__states_.back();
-      std::copy_n(__matched_state.__sub_matches_.get(), __submatch_count, __sub_matches_.get() + __submatch_base);
-    }
-    __current_pos += __jump_offset;
-    return {true, __current_pos};
+  /*
+pair<bool, size_t> __exec_lookahead(
+    const _CharT* const __first,
+    const _CharT* const __last,
+    const __global_state& __gstate,
+    const __interpreter_info<_CharT>* const __code,
+    size_t __current_pos,
+    bool __is_positive) {
+  auto __jump_offset    = __read_uleb(__code, __current_pos);
+  auto __submatch_count = __read_uleb(__code, __current_pos);
+  auto __submatch_base  = __read_uleb(__code, __current_pos);
+  auto __loop_count     = __read_uleb(__code, __current_pos);
+
+  auto __initial_loop_values = std::make_unique_for_overwrite<__loop_value<_CharT>[]>(__loop_count);
+
+  for (size_t __i = 0; __i != __loop_count; ++__i)
+    __initial_loop_values[__i] = __read_uleb(__code, __current_pos);
+
+  __global_state __gexec_state{{}, __gstate.__machine_, __submatch_count, __gstate.__flags_};
+  __gexec_state.__flags_ &= ~regex_constants::__full_match;
+  auto& __s = __gexec_state.__states_.emplace_back();
+  if (__loop_count > 0)
+    __s.__sub_matches_ = std::make_unique<pair<const _CharT*, const _CharT*>[]>(__submatch_count);
+  __s.__current_     = __current_;
+  __s.__loop_values_ = std::move(__initial_loop_values);
+  __s.__current_pos_ = __current_pos;
+  if (__gexec_state.__execute(__first, __last) != __is_positive)
+    return {false, __current_pos};
+  if (__is_positive) {
+    auto& __matched_state = __gexec_state.__states_.back();
+    std::copy_n(__matched_state.__sub_matches_.get(), __submatch_count, __get_submatch(__submatch_base));
   }
+  __current_pos += __jump_offset;
+  return {true, __current_pos};
+}
+  */
 
   size_t __exec_branch_n_to_m_matcher(
       __global_state& __gstate,
@@ -406,7 +402,8 @@ struct __local_execution_state {
     if (__loop_values_[__loop_index].__ptr_ != __current && __loop_values_[__loop_index + 2].__int_ > 0) {
       --__loop_values_[__loop_index + 2].__int_;
       __loop_values_[__loop_index] = __current;
-      __copy_to(__current, __gstate.__states_, __gstate);
+      __gstate.__states_.push(this);
+      __gstate.__states_.back().__current_ = __current;
       if (!__is_greedy) {
         __gstate.__states_.back().__current_pos_ = __again_pos;
       } else {
@@ -487,7 +484,8 @@ struct __local_execution_state {
 
       case __branch_alternative: {
         auto __offset = __read_uleb(__code, __current_pos);
-        __copy_to(__current, __gstate.__states_, __gstate);
+        __gstate.__states_.push(this);
+        __gstate.__states_.back().__current_     = __current;
         __gstate.__states_.back().__current_pos_ = __current_pos + __offset;
         break;
       }
@@ -504,7 +502,7 @@ struct __local_execution_state {
       } break;
 
       case __match_backref: {
-        auto& __match = __sub_matches_[__read_uleb(__code, __current_pos) - 1];
+        auto& __match = __get_submatch(__read_uleb(__code, __current_pos) - 1);
         if (__match.first == nullptr)
           return {false, __counter};
 
@@ -516,7 +514,7 @@ struct __local_execution_state {
       } break;
 
       case __match_icase_backref: {
-        auto& __match = __sub_matches_[__read_uleb(__code, __current_pos) - 1];
+        auto& __match = __get_submatch(__read_uleb(__code, __current_pos) - 1);
         if (__match.first == nullptr)
           return {false, __counter};
 
@@ -551,12 +549,12 @@ struct __local_execution_state {
 
       case __marked_subexpression_begin: {
         auto __match                  = __read_uleb(__code, __current_pos);
-        __sub_matches_[__match].first = __current;
+        __get_submatch(__match).first = __current;
       } break;
 
       case __marked_subexpression_end: {
         auto __match                   = __read_uleb(__code, __current_pos);
-        __sub_matches_[__match].second = __current;
+        __get_submatch(__match).second = __current;
       } break;
 
       case __match_word_boundary: {
@@ -571,13 +569,13 @@ struct __local_execution_state {
 
       case __negative_lookahead:
       case __positive_lookahead: {
-        if (auto __result =
-                __exec_lookahead(__first, __last, __gstate, __code, __current_pos, (__st == __positive_lookahead));
-            __result.first)
-          __current_pos = __result.second;
-        else
-          return {false, __counter};
-      } break;
+        // if (auto __result =
+        //         __exec_lookahead(__first, __last, __gstate, __code, __current_pos, (__st == __positive_lookahead));
+        //     __result.first)
+        //   __current_pos = __result.second;
+        // else
+        //   return {false, __counter};
+      } // break;
 
       default:
         std::__libcpp_unreachable();
@@ -586,12 +584,63 @@ struct __local_execution_state {
   }
 };
 
+template <class _CharT, class _Traits>
+class __local_execution_state_stack {
+  char* __data_begin_ = nullptr;
+  size_t __base_offset_;
+  size_t __object_size_;
+  size_t __size_     = 0;
+  size_t __capacity_ = 0;
+
+public:
+  using value_type = __local_execution_state<_CharT, _Traits>;
+
+  static_assert(__is_trivially_copyable(value_type) && __is_trivially_destructible(value_type));
+
+  __local_execution_state_stack(size_t __loop_value_count, size_t __submatch_count)
+      : __base_offset_(__submatch_count * sizeof(pair<const _CharT*, const _CharT*>)),
+        __object_size_(__base_offset_ + sizeof(value_type) + __loop_value_count * sizeof(__loop_value<_CharT>)) {}
+
+  __local_execution_state_stack(const __local_execution_state_stack&)            = delete;
+  __local_execution_state_stack& operator=(const __local_execution_state_stack&) = delete;
+  ~__local_execution_state_stack() { __builtin_free(__data_begin_); }
+
+  bool empty() const { return __size_ == 0; }
+
+  value_type& back() {
+    return *reinterpret_cast<value_type*>(__data_begin_ + __object_size_ * (__size_ - 1) + __base_offset_);
+  }
+
+  void push(const value_type* __val) {
+    if (__size_ == __capacity_) [[unlikely]] {
+      auto __new_cap = 2 * __capacity_ + 1;
+      if (auto __new_ptr = __builtin_realloc(__data_begin_, __new_cap * __object_size_)) {
+        __data_begin_ = static_cast<char*>(__new_ptr);
+        __capacity_   = __new_cap;
+      } else {
+        std::__throw_bad_alloc();
+      }
+    }
+    __builtin_memcpy((__data_begin_ + __object_size_ * __size_),
+                     reinterpret_cast<const char*>(__val) - __base_offset_,
+                     __object_size_);
+    ++__size_;
+  }
+
+  void pop(value_type* __tmp) {
+    _LIBCPP_ASSERT_INTERNAL(__size_ != 0, "Trying to pop from empty stack!");
+    --__size_;
+    __builtin_memcpy(
+        reinterpret_cast<char*>(__tmp) - __base_offset_, __data_begin_ + __object_size_ * __size_, __object_size_);
+  }
+};
+
 template <class _CharT, class _Traits>
 class __interpreter;
 
 template <class _CharT, class _Traits>
 struct __global_execution_state {
-  vector<__local_execution_state<_CharT, _Traits>> __states_;
+  __local_execution_state_stack<_CharT, _Traits> __states_;
   const __interpreter<_CharT, _Traits>& __machine_;
   size_t __submatch_count_;
   regex_constants::match_flag_type __flags_;
@@ -806,7 +855,7 @@ class __interpreter {
 
   size_t size() const { return __machine_.size(); }
 
-  [[clang::preserve_none]]
+  // [[clang::preserve_none]]
   pair<bool, const _CharT*>
   __execute(__global_execution_state<_CharT, _Traits>& __gexec_state,
             const _CharT* __first,
@@ -818,7 +867,10 @@ class __interpreter {
         [&](pair<const _CharT*, const _CharT*>* __from, size_t __count, vector<sub_match<const _CharT*>>& __to) {
           __to.clear();
           std::transform(
-              __from, __from + __count, std::back_inserter(__to), [&](pair<const _CharT*, const _CharT*> __v) {
+              std::make_reverse_iterator(__from + __count),
+              std::make_reverse_iterator(__from),
+              std::back_inserter(__to),
+              [&](pair<const _CharT*, const _CharT*> __v) {
                 sub_match<const _CharT*> __ret;
                 __ret.first   = __v.first ? __v.first : __last;
                 __ret.second  = __v.first ? __v.second : __last;
@@ -827,60 +879,63 @@ class __interpreter {
               });
         };
 
-    __local_state __base_state{
-        .__current_     = __first,
-        .__sub_matches_ = __gexec_state.__submatch_count_
-                            ? std::make_unique<pair<const _CharT*, const _CharT*>[]>(__gexec_state.__submatch_count_)
-                            : nullptr,
-        .__current_pos_ = 0,
-        .__loop_values_ = __initial_loop_values_.empty()
-                            ? nullptr
-                            : std::make_unique_for_overwrite<__loop_value<_CharT>[]>(__initial_loop_values_.size()),
-    };
-    if (!__initial_loop_values_.empty())
-      std::copy(__initial_loop_values_.begin(), __initial_loop_values_.end(), __base_state.__loop_values_.get());
+    const auto __sizeof_submatches  = sizeof(pair<const _CharT*, const _CharT*>) * __gexec_state.__submatch_count_;
+    const auto __sizeof_loop_values = sizeof(__loop_value<_CharT>) * __initial_loop_values_.size();
+    const auto __state_size         = __sizeof_submatches + sizeof(__local_state) + __sizeof_loop_values;
+
+    auto* __base_state_start      = static_cast<char*>(__builtin_alloca(2 * __state_size));
+    auto* __base_state_submatches = reinterpret_cast<pair<const _CharT*, const _CharT*>*>(__base_state_start);
+    auto* __base_state            = reinterpret_cast<__local_state*>(__base_state_start + __sizeof_submatches);
+    auto* __tmp_state_start       = __base_state_start + __state_size;
+    auto* __tmp_state             = reinterpret_cast<__local_state*>(__tmp_state_start + __sizeof_submatches);
+
+    std::uninitialized_fill_n(
+        __base_state_submatches, __gexec_state.__submatch_count_, pair<const _CharT*, const _CharT*>{nullptr, nullptr});
+    std::__construct_at(__base_state, __first, 0);
+    std::uninitialized_copy(
+        __initial_loop_values_.begin(),
+        __initial_loop_values_.end(),
+        reinterpret_cast<__loop_value<_CharT>*>(__base_state_start + __sizeof_submatches + sizeof(__local_state)));
 
-    auto [__base_state_matched, __gcounter] = __base_state.__execute(__first, __last, __gexec_state);
+    auto [__base_state_matched, __gcounter] = __base_state->__execute(__first, __last, __gexec_state);
 
     size_t __length = __last - __first + 1;
     if (__gexec_state.__machine_.__find_longest_) {
       if (!__base_state_matched)
-        __base_state.__current_ = __first;
+        __base_state->__current_ = __first;
       bool __found_match = __base_state_matched;
       while (!__gexec_state.__states_.empty()) {
         if (__gcounter / _LIBCPP_REGEX_COMPLEXITY_FACTOR >= __length)
           std::__throw_regex_error<regex_constants::error_complexity>();
-        auto __state = std::move(__gexec_state.__states_.back());
-        __gexec_state.__states_.pop_back();
-        auto [__success, __counter] = __state.__execute(__first, __last, __gexec_state);
+        __gexec_state.__states_.pop(__tmp_state);
+        auto [__success, __counter] = __tmp_state->__execute(__first, __last, __gexec_state);
         __gcounter += __counter;
         if (__success) {
-          if (!__found_match || __base_state.__current_ < __state.__current_)
-            __base_state = std::move(__state);
-          if (__base_state.__current_ == __last) {
-            __copy_to_submatches(__base_state.__sub_matches_.get(), __gexec_state.__submatch_count_, __sub_matches);
-            return {true, __base_state.__current_};
+          if (!__found_match || __base_state->__current_ < __tmp_state->__current_)
+            __builtin_memcpy(__base_state_start, __tmp_state_start, __state_size);
+          if (__base_state->__current_ == __last) {
+            __copy_to_submatches(__base_state_submatches, __gexec_state.__submatch_count_, __sub_matches);
+            return {true, __base_state->__current_};
           }
           __found_match = true;
         }
       }
       if (!__found_match)
         return {false, {}};
-      __copy_to_submatches(__base_state.__sub_matches_.get(), __gexec_state.__submatch_count_, __sub_matches);
-      return {true, __base_state.__current_};
+      __copy_to_submatches(__base_state_submatches, __gexec_state.__submatch_count_, __sub_matches);
+      return {true, __base_state->__current_};
     } else {
       if (__base_state_matched) {
-        __copy_to_submatches(__base_state.__sub_matches_.get(), __gexec_state.__submatch_count_, __sub_matches);
-        return {true, __base_state.__current_};
+        __copy_to_submatches(__base_state_submatches, __gexec_state.__submatch_count_, __sub_matches);
+        return {true, __base_state->__current_};
       }
       while (!__gexec_state.__states_.empty()) {
         if (__gcounter / _LIBCPP_REGEX_COMPLEXITY_FACTOR >= __length)
           std::__throw_regex_error<regex_constants::error_complexity>();
-        __base_state = std::move(__gexec_state.__states_.back());
-        __gexec_state.__states_.pop_back();
-        if (auto [__success, __counter] = __base_state.__execute(__first, __last, __gexec_state); __success) {
-          __copy_to_submatches(__base_state.__sub_matches_.get(), __gexec_state.__submatch_count_, __sub_matches);
-          return {true, __base_state.__current_};
+        __gexec_state.__states_.pop(__base_state);
+        if (auto [__success, __counter] = __base_state->__execute(__first, __last, __gexec_state); __success) {
+          __copy_to_submatches(__base_state_submatches, __gexec_state.__submatch_count_, __sub_matches);
+          return {true, __base_state->__current_};
         } else {
           __gcounter += __counter;
         }
@@ -895,7 +950,8 @@ class __interpreter {
       const _CharT* __last,
       size_t __submatch_count,
       vector<sub_match<const _CharT*>>& __sub_matches) const {
-    __global_execution_state __gexec_state{{}, *this, __submatch_count, __flags};
+    __global_execution_state<_CharT, _Traits> __gexec_state{
+        {__initial_loop_values_.size(), __sub_matches.size()}, *this, __submatch_count, __flags};
     return __execute(__gexec_state, __first, __last, __sub_matches);
   }
 
@@ -909,8 +965,8 @@ class __interpreter {
     __unmatched.second  = __last;
     __unmatched.matched = false;
 
-    __global_execution_state __gexec_state{
-        {},
+    __global_execution_state<_CharT, _Traits> __gexec_state{
+        {__initial_loop_values_.size(), __marked_count},
         *this,
         __marked_count,
         __flags | ((__flags & regex_constants::__no_update_pos) ? regex_constants::match_flag_type()
diff --git a/libcxx/include/regex b/libcxx/include/regex
index 6048744eeeae0..c5bad522a16f0 100644
--- a/libcxx/include/regex
+++ b/libcxx/include/regex
@@ -1307,8 +1307,8 @@ public:
   }
 };
 
-static_assert(sizeof(__regex::__global_execution_state<char, regex_traits<char>>) == 48);
-static_assert(sizeof(__regex::__local_execution_state<char, regex_traits<char>>) == 32);
+static_assert(sizeof(__regex::__global_execution_state<char, regex_traits<char>>) == 64);
+static_assert(sizeof(__regex::__local_execution_state<char, regex_traits<char>>) == 16);
 
 template <class _CharT, class _Traits = regex_traits<_CharT> >
 class basic_regex;

>From 609b0eca3cad91be202462c3eacbca49ccef62d5 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Tue, 7 Apr 2026 02:44:16 +0200
Subject: [PATCH 15/21] Make most bracket expressions faster

---
 libcxx/include/__regex/interpreter.h   | 69 ++++++++++++++++++++++++++
 libcxx/test/benchmarks/regex.bench.cpp | 23 +++++++++
 2 files changed, 92 insertions(+)

diff --git a/libcxx/include/__regex/interpreter.h b/libcxx/include/__regex/interpreter.h
index 5e081f2e99662..fd4304bc21931 100644
--- a/libcxx/include/__regex/interpreter.h
+++ b/libcxx/include/__regex/interpreter.h
@@ -85,6 +85,7 @@ enum class __state : uint8_t {
   __match_icase_backref,
   __match_character_list,
   __match_no_character_list,
+  __match_simple_character_list,
   __marked_subexpression_begin,
   __marked_subexpression_end,
   __branch_n_to_m_matcher,
@@ -100,6 +101,7 @@ enum class __state : uint8_t {
 
 template <class _CharT>
 union __interpreter_info {
+  __interpreter_info() = default;
   __interpreter_info(__state __st) : __state_(__st) {}
   __interpreter_info(_CharT __c) : __char_(__c) {}
   __interpreter_info(uint8_t __int) : __int_(__int) {}
@@ -531,6 +533,20 @@ pair<bool, size_t> __exec_lookahead(
         __current += __len;
       } break;
 
+      case __match_simple_character_list: {
+        if (__current == __last)
+          return {false, __counter};
+
+        using _SetT = unsigned _BitInt(256);
+
+        _SetT __set;
+        __builtin_memcpy(&__set, __code + __current_pos, sizeof(_SetT));
+        __current_pos += sizeof(_SetT);
+        if (!(__set & (_SetT(1) << *__current)))
+          return {false, __counter};
+        ++__current;
+      } break;
+
       case __match_character_list:
       case __match_no_character_list: {
         if (__current == __last)
@@ -801,6 +817,59 @@ class __interpreter {
   }
 
   void __push_bracket_expr(bool __negate, const __bracket_expr<_CharT, _Traits>& __expr) {
+    bool __has_digraph_range = false;
+    for (size_t __i = 1; __i < __expr.__ranges_.size(); __i += 2) {
+      if (__expr.__ranges_[__i] != '\0')
+        __has_digraph_range = true;
+    }
+
+    if constexpr (__is_same(_CharT, char)) {
+      if (!__has_digraph_range && __expr.__digraphs_.empty() && __expr.__equivalences_.empty()) {
+        using _SetT = unsigned _BitInt(256);
+
+        _SetT __set = 0;
+
+        if (__expr.__neg_mask_ != 0 || !__expr.__neg_chars_.empty()) {
+          for (size_t __i = 0; __i != 256; ++__i) {
+            if (__traits_.isctype(char(__i), __expr.__neg_mask_))
+              __set |= _SetT(1) << __i;
+          }
+          for (auto __c : __expr.__neg_chars_)
+            __set |= _SetT(1) << __c;
+          __set = ~__set;
+        }
+
+        for (auto __c : __expr.__chars_)
+          __set |= _SetT(1) << __c;
+
+        for (size_t __i = 0; __i != __expr.__ranges_.size(); __i += 4) {
+          for (char __j = __expr.__ranges_[__i]; __j != __expr.__ranges_[__i + 2]; ++__j)
+            __set |= _SetT(1) << __j;
+        }
+
+        if (__expr.__mask_ != 0) {
+          for (size_t __i = 0; __i != 256; ++__i) {
+            if (__traits_.isctype(char(__i), __expr.__mask_))
+              __set |= _SetT(1) << __i;
+          }
+        }
+
+        if (__negate)
+          __set = ~__set;
+
+        if (__builtin_popcountg(__set) == 1) {
+          __push_char_matcher(__builtin_ctzg(__set));
+          return;
+        }
+
+        push_back(__state::__match_simple_character_list);
+        __interpreter_info<_CharT> __buffer[sizeof(_SetT)];
+        __builtin_memcpy(__buffer, &__set, sizeof(_SetT));
+        append_range(__buffer);
+        return;
+      }
+    }
+
     push_back(__negate ? __state::__match_no_character_list : __state::__match_character_list);
 
     _CharT __buffer[std::max(sizeof(typename _Traits::char_class_type) / sizeof(_CharT), size_t(1))];
diff --git a/libcxx/test/benchmarks/regex.bench.cpp b/libcxx/test/benchmarks/regex.bench.cpp
index 75174a7e71706..725c0ec50a77f 100644
--- a/libcxx/test/benchmarks/regex.bench.cpp
+++ b/libcxx/test/benchmarks/regex.bench.cpp
@@ -59,4 +59,27 @@ static void BM_regex_run_any_matcher(benchmark::State& state) {
 }
 BENCHMARK(BM_regex_run_any_matcher);
 
+static void BM_regex_run_alphabet_matcher(benchmark::State& state) {
+  std::regex r("[a-zA-Z]*");
+  std::string input;
+  input.append(1 << 16, 'a');
+
+  for (auto _ : state) {
+    std::regex_search(input, r);
+  }
+}
+BENCHMARK(BM_regex_run_alphabet_matcher);
+
+static void BM_regex_run_mail_matcher(benchmark::State& state) {
+  std::regex r(
+      R"regex((?:(?:[^<>()\[\].,;:\s@"]+(?:\.[^<>()\[\].,;:\s@"]+)*)|".+")@(?:(?:[^<>()\[\].,;:\s@"]+\.)+[^<>()\[\].,;:\s@"]{2,}))regex");
+  std::string input;
+  input.append(1 << 8, 'a');
+
+  for (auto _ : state) {
+    std::regex_search(input, r);
+  }
+}
+BENCHMARK(BM_regex_run_mail_matcher);
+
 BENCHMARK_MAIN();

>From b30f7acede2f18f63656a7a045ccbfb53831f2f5 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Thu, 9 Apr 2026 07:02:25 +0200
Subject: [PATCH 16/21] Make alternatives deterministic if they have a disjunct
 set of matching characters

---
 libcxx/include/__regex/interpreter.h | 219 +++++++++++++++++++++------
 1 file changed, 169 insertions(+), 50 deletions(-)

diff --git a/libcxx/include/__regex/interpreter.h b/libcxx/include/__regex/interpreter.h
index fd4304bc21931..e7723ce92bb6a 100644
--- a/libcxx/include/__regex/interpreter.h
+++ b/libcxx/include/__regex/interpreter.h
@@ -71,12 +71,17 @@ struct __state {
 };
 
 namespace __regex {
+using _MatchingSetT        = unsigned _BitInt(256);
+using _MatchingSetWithEndT = unsigned _BitInt(257);
+
 enum class __state : uint8_t {
+  // Anchors
   __start_anchor,
   __end_anchor,
   __multiline_start_anchor,
   __multiline_end_anchor,
-  __branch_alternative,
+
+  // Consuming matches
   __match_any,
   __match_any_except_newline,
   __match_char,
@@ -86,16 +91,29 @@ enum class __state : uint8_t {
   __match_character_list,
   __match_no_character_list,
   __match_simple_character_list,
+
+  // Marked subexpressions
   __marked_subexpression_begin,
   __marked_subexpression_end,
-  __branch_n_to_m_matcher,
-  __branch_nongreedy_n_to_m_matcher,
-  __match_n_to_m_times,
+
+  // Non-consuming matches
   __match_word_boundary,
   __match_no_word_boundary,
+
+  // Lookahead
   __positive_lookahead,
   __negative_lookahead,
+
+  // Jumps
   __relative_jump,
+  __conditional_jump,
+
+  // Branches
+  __branch_n_to_m_matcher,
+  __branch_nongreedy_n_to_m_matcher,
+  __branch_alternative,
+
+  // End state
   __end_state,
 };
 
@@ -111,11 +129,37 @@ union __interpreter_info {
 
   __state __state_;
   _CharT __char_;
-  uint8_t __int_;
+  unsigned _BitInt(8) __int_;
 };
 
 static_assert(sizeof(__interpreter_info<char>) == 1);
 
+template <class _CharT>
+pair<size_t, size_t>
+__read_uleb_impl(_LIBCPP_NOESCAPE const __interpreter_info<_CharT>* __machine, size_t __current_pos) {
+  size_t __result = 0;
+  size_t __shift  = 0;
+
+  uint8_t __byte;
+  do {
+    __byte = __machine[__current_pos++].__int_;
+    __result |= (__byte & 0x7f) << __shift;
+    __shift += 7;
+  } while (__byte & 0x80);
+  return {__result, __current_pos};
+}
+
+template <class _CharT>
+size_t __read_uleb(const __interpreter_info<_CharT>* __machine, size_t& __current_pos) {
+  auto __val = __machine[__current_pos++].__int_;
+  if (__val & 0x80) {
+    auto __res    = __read_uleb_impl(__machine, __current_pos);
+    __current_pos = __res.second;
+    return __res.first;
+  }
+  return __val;
+}
+
 template <class _CharT, class _Traits>
 struct __bracket_expr {
   vector<_CharT> __chars_;
@@ -174,30 +218,6 @@ struct __local_execution_state {
   size_t __current_pos_;
   __loop_value<_CharT> __loop_values_[];
 
-  static pair<size_t, size_t>
-  __read_uleb_impl(_LIBCPP_NOESCAPE const __interpreter_info<_CharT>* __machine, size_t __current_pos) {
-    size_t __result = 0;
-    size_t __shift  = 0;
-
-    uint8_t __byte;
-    do {
-      __byte = __machine[__current_pos++].__int_;
-      __result |= (__byte & 0x7f) << __shift;
-      __shift += 7;
-    } while (__byte & 0x80);
-    return {__result, __current_pos};
-  }
-
-  static size_t __read_uleb(const __interpreter_info<_CharT>* __machine, size_t& __current_pos) {
-    auto __val = __machine[__current_pos++].__int_;
-    if (__val & 0x80) {
-      auto __res    = __read_uleb_impl(__machine, __current_pos);
-      __current_pos = __res.second;
-      return __res.first;
-    }
-    return __val;
-  }
-
   static bool __is_word_boundary(
       const _CharT* __first, const _CharT* __last, const _CharT* const __current, __global_state& __gstate) {
     auto __is_word_char = [&](char __c) {
@@ -489,13 +509,22 @@ pair<bool, size_t> __exec_lookahead(
         __gstate.__states_.push(this);
         __gstate.__states_.back().__current_     = __current;
         __gstate.__states_.back().__current_pos_ = __current_pos + __offset;
-        break;
-      }
+      } break;
 
       case __relative_jump: {
         __current_pos += __read_uleb(__code, __current_pos);
-        break;
-      }
+      } break;
+
+      case __conditional_jump: {
+        _MatchingSetT __set;
+        __builtin_memcpy(&__set, __code + __current_pos, sizeof(_MatchingSetT));
+        __current_pos += sizeof(_MatchingSetT);
+        auto __jump_offset = __read_uleb(__code, __current_pos);
+        if (__current == __last)
+          return {false, __counter};
+        if (!(__set & (_MatchingSetT(1) << *__current)))
+          __current_pos += __jump_offset;
+      } break;
 
       case __branch_n_to_m_matcher:
       case __branch_nongreedy_n_to_m_matcher: {
@@ -537,12 +566,10 @@ pair<bool, size_t> __exec_lookahead(
         if (__current == __last)
           return {false, __counter};
 
-        using _SetT = unsigned _BitInt(256);
-
-        _SetT __set;
-        __builtin_memcpy(&__set, __code + __current_pos, sizeof(_SetT));
-        __current_pos += sizeof(_SetT);
-        if (!(__set & (_SetT(1) << *__current)))
+        _MatchingSetT __set;
+        __builtin_memcpy(&__set, __code + __current_pos, sizeof(_MatchingSetT));
+        __current_pos += sizeof(_MatchingSetT);
+        if (!(__set & (_MatchingSetT(1) << *__current)))
           return {false, __counter};
         ++__current;
       } break;
@@ -751,6 +778,85 @@ class __interpreter {
     __write_uleb(__machine, __offset);
   }
 
+  // This function returns the set of characters that _might_ match - there is no guarantee that any characters will
+  // actually be a match. This should never return an empty set, as that needs special handling.
+  inline _MatchingSetWithEndT __get_possibly_matching_characters(const __interpreter_info<char>* __m, size_t __pos) {
+    switch (__m[__pos++].__state_) {
+      using enum __state;
+    case __match_any_except_newline:
+      return ~(_MatchingSetT(1) << '\n');
+
+    case __match_char:
+      return _MatchingSetT(1) << __m[__pos].__char_;
+
+    case __match_simple_character_list: {
+      _MatchingSetT __set;
+      __builtin_memcpy(&__set, __m + __pos, sizeof(_MatchingSetT));
+      return __set;
+    }
+
+    case __marked_subexpression_begin:
+    case __marked_subexpression_end: {
+      __read_uleb(__m, __pos);
+      [[clang::musttail]] return __get_possibly_matching_characters(__m, __pos);
+    }
+
+    case __relative_jump: {
+      __pos += __read_uleb(__m, __pos);
+      [[clang::musttail]] return __get_possibly_matching_characters(__m, __pos);
+    }
+
+    case __branch_n_to_m_matcher:
+    case __branch_nongreedy_n_to_m_matcher: {
+      auto __loop_index = __read_uleb(__m, __pos);
+      __read_uleb(__m, __pos);
+      if (__initial_loop_values_[__loop_index + 1].__int_ == 0)
+        return ~_MatchingSetWithEndT();
+      [[clang::musttail]] return __get_possibly_matching_characters(__m, __pos);
+    }
+
+    case __start_anchor:
+    case __multiline_start_anchor:
+    case __match_word_boundary:
+    case __match_no_word_boundary: {
+      [[clang::musttail]] return __get_possibly_matching_characters(__m, __pos);
+    }
+
+    case __end_anchor:
+    case __multiline_end_anchor: {
+      return _MatchingSetWithEndT(1) << 256;
+    }
+
+    case __match_any: {
+      return ~_MatchingSetT();
+    }
+
+    case __conditional_jump: {
+      _MatchingSetT __set;
+      __builtin_memcpy(&__set, __m + __pos, sizeof(_MatchingSetT));
+      __pos += sizeof(_MatchingSetT);
+      auto __jump_offset = __read_uleb(__m, __pos);
+      return __set | __get_possibly_matching_characters(__m, __pos + __jump_offset);
+    }
+
+    // FIXME: Most of these should get some proper handling in here
+    case __match_icase_char:
+    case __branch_alternative:
+    case __match_character_list:
+    case __match_no_character_list:
+
+    // These can cause non-regular expressions, so claim anything could match
+    case __positive_lookahead:
+    case __negative_lookahead:
+    case __match_backref:
+    case __match_icase_backref:
+
+    // The end state actually matches anything
+    case __end_state:
+      return ~_MatchingSetWithEndT();
+    }
+  }
+
 public:
   __interpreter(const _Traits& __traits, bool __find_longest) : __traits_(__traits), __find_longest_(__find_longest) {
     __machine_.reserve(16);
@@ -810,10 +916,25 @@ class __interpreter {
     insert(__expr2_start, __buffer);
     __expr2_start += __buffer.size();
     __buffer.clear();
+
+    if constexpr (__is_same(_CharT, char)) {
+      if (__expr2_start != __machine_.size()) {
+        if (auto __expr1_set = __get_possibly_matching_characters(__machine_.data(), __expr1_start);
+            (__expr1_set & __get_possibly_matching_characters(__machine_.data(), __expr2_start)) == _MatchingSetT()) {
+          __buffer.push_back(__state::__conditional_jump);
+          __interpreter_info<_CharT> __sbuffer[sizeof(_MatchingSetT)];
+          __builtin_memcpy(__sbuffer, &__expr1_set, sizeof(_MatchingSetT));
+          __buffer.append_range(__sbuffer);
+          __write_uleb(__buffer, __expr2_start - __expr1_start);
+          insert(__expr1_start, __buffer);
+          return;
+        }
+      }
+    }
+
     __buffer.push_back(__state::__branch_alternative);
     __write_uleb(__buffer, __expr2_start - __expr1_start);
     insert(__expr1_start, __buffer);
-    __expr2_start += __buffer.size();
   }
 
   void __push_bracket_expr(bool __negate, const __bracket_expr<_CharT, _Traits>& __expr) {
@@ -825,32 +946,30 @@ class __interpreter {
 
     if constexpr (__is_same(_CharT, char)) {
       if (!__has_digraph_range && __expr.__digraphs_.empty() && __expr.__equivalences_.empty()) {
-        using _SetT = unsigned _BitInt(256);
-
-        _SetT __set = 0;
+        _MatchingSetT __set = 0;
 
         if (__expr.__neg_mask_ != 0 || !__expr.__neg_chars_.empty()) {
           for (size_t __i = 0; __i != 256; ++__i) {
             if (__traits_.isctype(char(__i), __expr.__neg_mask_))
-              __set |= _SetT(1) << __i;
+              __set |= _MatchingSetT(1) << __i;
           }
           for (auto __c : __expr.__neg_chars_)
-            __set |= _SetT(1) << __c;
+            __set |= _MatchingSetT(1) << __c;
           __set = ~__set;
         }
 
         for (auto __c : __expr.__chars_)
-          __set |= _SetT(1) << __c;
+          __set |= _MatchingSetT(1) << __c;
 
         for (size_t __i = 0; __i != __expr.__ranges_.size(); __i += 4) {
           for (char __j = __expr.__ranges_[__i]; __j != __expr.__ranges_[__i + 2]; ++__j)
-            __set |= _SetT(1) << __j;
+            __set |= _MatchingSetT(1) << __j;
         }
 
         if (__expr.__mask_ != 0) {
           for (size_t __i = 0; __i != 256; ++__i) {
             if (__traits_.isctype(char(__i), __expr.__mask_))
-              __set |= _SetT(1) << __i;
+              __set |= _MatchingSetT(1) << __i;
           }
         }
 
@@ -863,8 +982,8 @@ class __interpreter {
         }
 
         push_back(__state::__match_simple_character_list);
-        __interpreter_info<_CharT> __buffer[sizeof(_SetT)];
-        __builtin_memcpy(__buffer, &__set, sizeof(_SetT));
+        __interpreter_info<_CharT> __buffer[sizeof(_MatchingSetT)];
+        __builtin_memcpy(__buffer, &__set, sizeof(_MatchingSetT));
         append_range(__buffer);
         return;
       }

>From 57daa178359a8b0b5d3281a0a98e0c2073eb3d80 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Sun, 12 Apr 2026 15:19:20 +0200
Subject: [PATCH 17/21] Make loops determenistic

---
 libcxx/include/__regex/basic_parser.h      |   1 +
 libcxx/include/__regex/ecma_parser.h       |   1 +
 libcxx/include/__regex/interpreter.h       | 201 ++++++++++++++++++++-
 libcxx/include/__type_traits/make_signed.h |   5 +
 libcxx/test/benchmarks/regex.bench.cpp     |  11 ++
 5 files changed, 211 insertions(+), 8 deletions(-)

diff --git a/libcxx/include/__regex/basic_parser.h b/libcxx/include/__regex/basic_parser.h
index 9b8caeb688f4a..e9948015dcd84 100644
--- a/libcxx/include/__regex/basic_parser.h
+++ b/libcxx/include/__regex/basic_parser.h
@@ -229,6 +229,7 @@ class __parser {
   void __parse_basic() {
     __parse_basic_expr();
     __machine_.__push_end_state();
+    __machine_.__optimize();
   }
 
   void __parse_grep() {
diff --git a/libcxx/include/__regex/ecma_parser.h b/libcxx/include/__regex/ecma_parser.h
index 6499349410a0e..06bb235caeeb9 100644
--- a/libcxx/include/__regex/ecma_parser.h
+++ b/libcxx/include/__regex/ecma_parser.h
@@ -294,6 +294,7 @@ class __parser {
     if (__first_ != __last_)
       std::__throw_regex_error<regex_constants::__re_err_parse>();
     __machine_.__push_end_state();
+    __machine_.__optimize();
   }
 
   __interpreter<_CharT, _Traits> __extract_interpreter() { return std::move(__machine_); }
diff --git a/libcxx/include/__regex/interpreter.h b/libcxx/include/__regex/interpreter.h
index e7723ce92bb6a..88149795daef1 100644
--- a/libcxx/include/__regex/interpreter.h
+++ b/libcxx/include/__regex/interpreter.h
@@ -106,7 +106,8 @@ enum class __state : uint8_t {
 
   // Jumps
   __relative_jump,
-  __conditional_jump,
+  __conditional_jump_forward,
+  __conditional_jump_backward,
 
   // Branches
   __branch_n_to_m_matcher,
@@ -515,11 +516,14 @@ pair<bool, size_t> __exec_lookahead(
         __current_pos += __read_uleb(__code, __current_pos);
       } break;
 
-      case __conditional_jump: {
+      case __conditional_jump_forward:
+      case __conditional_jump_backward: {
         _MatchingSetT __set;
         __builtin_memcpy(&__set, __code + __current_pos, sizeof(_MatchingSetT));
         __current_pos += sizeof(_MatchingSetT);
-        auto __jump_offset = __read_uleb(__code, __current_pos);
+        auto __jump_offset = std::__to_signed_like(__read_uleb(__code, __current_pos));
+        if (__st == __conditional_jump_backward)
+          __jump_offset *= -1;
         if (__current == __last)
           return {false, __counter};
         if (!(__set & (_MatchingSetT(1) << *__current)))
@@ -781,10 +785,11 @@ class __interpreter {
   // This function returns the set of characters that _might_ match - there is no guarantee that any characters will
   // actually be a match. This should never return an empty set, as that needs special handling.
   inline _MatchingSetWithEndT __get_possibly_matching_characters(const __interpreter_info<char>* __m, size_t __pos) {
-    switch (__m[__pos++].__state_) {
+    auto __state = __m[__pos++].__state_;
+    switch (__state) {
       using enum __state;
     case __match_any_except_newline:
-      return ~(_MatchingSetT(1) << '\n');
+      return ~(_MatchingSetT(1) << '\n' | _MatchingSetWithEndT(1) << 256);
 
     case __match_char:
       return _MatchingSetT(1) << __m[__pos].__char_;
@@ -831,11 +836,14 @@ class __interpreter {
       return ~_MatchingSetT();
     }
 
-    case __conditional_jump: {
+    case __conditional_jump_forward:
+    case __conditional_jump_backward: {
       _MatchingSetT __set;
       __builtin_memcpy(&__set, __m + __pos, sizeof(_MatchingSetT));
       __pos += sizeof(_MatchingSetT);
-      auto __jump_offset = __read_uleb(__m, __pos);
+      auto __jump_offset = std::__to_signed_like(__read_uleb(__m, __pos));
+      if (__state == __conditional_jump_backward)
+        __jump_offset *= -1;
       return __set | __get_possibly_matching_characters(__m, __pos + __jump_offset);
     }
 
@@ -862,6 +870,183 @@ class __interpreter {
     __machine_.reserve(16);
   }
 
+  void __fix_jumps(size_t __updated_instruction, ssize_t __offset) {
+    vector<pair<size_t, ssize_t>> __todo;
+    __todo.emplace_back(__updated_instruction, __offset);
+    auto __code = __machine_.data();
+
+    while (!__todo.empty()) {
+      size_t __pos = 0;
+      switch (__code[__pos++].__state_) {
+        using enum __state;
+      case __start_anchor:
+      case __end_anchor:
+      case __multiline_start_anchor:
+      case __multiline_end_anchor:
+      case __match_any:
+      case __match_any_except_newline:
+      case __match_word_boundary:
+      case __match_no_word_boundary:
+        break;
+
+      // Consuming matches
+      case __match_char:
+      case __match_icase_char:
+        ++__pos;
+        break;
+
+      case __match_simple_character_list:
+        __pos += sizeof(_MatchingSetT);
+        break;
+
+      case __match_backref:
+      case __match_icase_backref:
+      case __marked_subexpression_begin:
+      case __marked_subexpression_end:
+        __read_uleb(__code, __pos);
+        break;
+
+      case __match_character_list:
+      case __match_no_character_list: {
+        static constexpr auto __buffer_size =
+            std::max(sizeof(typename _Traits::char_class_type) / sizeof(_CharT), size_t(1));
+        __pos += 2 * __buffer_size;
+        for (size_t __i = 0; __i != 6; ++__i)
+          __read_uleb(__code, __pos);
+      } break;
+
+      // Lookahead
+      case __positive_lookahead:
+      case __negative_lookahead:
+        std::__libcpp_unreachable();
+
+      // Jumps
+      case __relative_jump: {
+        auto __instr_start = __pos;
+        auto __jump_offset = __read_uleb(__code, __pos);
+        if (__pos < __todo.back().first && __pos + __jump_offset > __todo.back().first)
+          __jump_offset += __todo.back().second;
+        auto __num_size = __pos - __instr_start;
+        vector<__interpreter_info<_CharT>> __buffer;
+        __write_uleb(__buffer, __jump_offset);
+        if (__buffer.size() == __num_size) {
+          std::copy(__buffer.begin(), __buffer.end(), __code + __instr_start);
+        } else {
+
+        }
+      }
+
+      case __conditional_jump_forward:
+      case __conditional_jump_backward:
+
+      // Branches
+      case __branch_n_to_m_matcher:
+      case __branch_nongreedy_n_to_m_matcher:
+      case __branch_alternative:
+
+      // End state
+      case __end_state:
+        return;
+      }
+    }
+  }
+
+  void __optimize() {
+    auto __code  = __machine_.data();
+    size_t __pos = 0;
+    while (__pos != __machine_.size()) {
+      switch (__code[__pos++].__state_) {
+        using enum __state;
+      case __start_anchor:
+      case __end_anchor:
+      case __multiline_start_anchor:
+      case __multiline_end_anchor:
+      case __match_any:
+      case __match_any_except_newline:
+      case __match_word_boundary:
+      case __match_no_word_boundary:
+        break;
+
+      case __match_char:
+      case __match_icase_char:
+        ++__pos;
+        break;
+
+      case __match_simple_character_list:
+        __pos += sizeof(_MatchingSetT);
+        break;
+
+      case __match_backref:
+      case __match_icase_backref:
+      case __marked_subexpression_begin:
+      case __marked_subexpression_end:
+      case __relative_jump:
+        __read_uleb(__code, __pos);
+        break;
+
+      case __match_character_list:
+      case __match_no_character_list: {
+        static constexpr auto __buffer_size =
+            std::max(sizeof(typename _Traits::char_class_type) / sizeof(_CharT), size_t(1));
+        __pos += 2 * __buffer_size;
+        for (size_t __i = 0; __i != 6; ++__i)
+          __read_uleb(__code, __pos);
+      } break;
+
+      // Lookahead
+      case __positive_lookahead:
+      case __negative_lookahead:
+        return;
+
+      // Jumps
+      case __conditional_jump_forward:
+      case __conditional_jump_backward:
+        __pos += sizeof(_MatchingSetT);
+        __read_uleb(__code, __pos);
+        break;
+
+      // Branches
+      case __branch_n_to_m_matcher:
+      case __branch_nongreedy_n_to_m_matcher: {
+        auto __instr_start    = __pos - 1;
+        auto __loop_index     = __read_uleb(__code, __pos);
+        auto __again_pos_base = __pos;
+        auto __again_pos      = __again_pos_base - __read_uleb(__code, __pos);
+        auto __instr_size     = __pos - __instr_start;
+
+        if (__initial_loop_values_[__loop_index + 1].__int_ != 0 ||
+            __initial_loop_values_[__loop_index + 2].__int_ != numeric_limits<size_t>::max())
+          break;
+
+        if constexpr (__is_same(_CharT, char)) {
+          if (auto __expr1_set = __get_possibly_matching_characters(__machine_.data(), __again_pos);
+              (__expr1_set & __get_possibly_matching_characters(__machine_.data(), __pos)) == _MatchingSetT()) {
+            {
+              vector<__interpreter_info<_CharT>> __buffer;
+              __buffer.push_back(__state::__conditional_jump_backward);
+              __interpreter_info<_CharT> __sbuffer[sizeof(_MatchingSetT)];
+              __builtin_memcpy(__sbuffer, &__expr1_set, sizeof(_MatchingSetT));
+              __buffer.append_range(__sbuffer);
+              __write_uleb(__buffer, __instr_start - __again_pos);
+              __machine_.erase(__machine_.begin() + __instr_start, __machine_.begin() + __instr_start + __instr_size);
+              __machine_.insert(__machine_.begin() + __instr_start, __buffer.begin(), __buffer.end());
+              __fix_jumps(__instr_start, __buffer.size() - __instr_size);
+            }
+            [[clang::musttail]] return __optimize();
+          }
+        }
+        break;
+      }
+
+      case __branch_alternative:
+
+      // End state
+      case __end_state:
+        return;
+      }
+    }
+  }
+
   void __push_any_matcher() { push_back(__state::__match_any); }
   void __push_any_except_newline_matcher() { push_back(__state::__match_any_except_newline); }
   void __push_end_state() { push_back(__state::__end_state); }
@@ -921,7 +1106,7 @@ class __interpreter {
       if (__expr2_start != __machine_.size()) {
         if (auto __expr1_set = __get_possibly_matching_characters(__machine_.data(), __expr1_start);
             (__expr1_set & __get_possibly_matching_characters(__machine_.data(), __expr2_start)) == _MatchingSetT()) {
-          __buffer.push_back(__state::__conditional_jump);
+          __buffer.push_back(__state::__conditional_jump_forward);
           __interpreter_info<_CharT> __sbuffer[sizeof(_MatchingSetT)];
           __builtin_memcpy(__sbuffer, &__expr1_set, sizeof(_MatchingSetT));
           __buffer.append_range(__sbuffer);
diff --git a/libcxx/include/__type_traits/make_signed.h b/libcxx/include/__type_traits/make_signed.h
index dff23d880dc30..42a060084a259 100644
--- a/libcxx/include/__type_traits/make_signed.h
+++ b/libcxx/include/__type_traits/make_signed.h
@@ -74,6 +74,11 @@ struct _LIBCPP_NO_SPECIALIZATIONS make_signed {
   using type _LIBCPP_NODEBUG = __make_signed_t<_Tp>;
 };
 
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __make_signed_t<_Tp> __to_signed_like(_Tp __x) _NOEXCEPT {
+  return static_cast<__make_signed_t<_Tp> >(__x);
+}
+
 #if _LIBCPP_STD_VER >= 14
 template <class _Tp>
 using make_signed_t = __make_signed_t<_Tp>;
diff --git a/libcxx/test/benchmarks/regex.bench.cpp b/libcxx/test/benchmarks/regex.bench.cpp
index 725c0ec50a77f..05b861171d9c5 100644
--- a/libcxx/test/benchmarks/regex.bench.cpp
+++ b/libcxx/test/benchmarks/regex.bench.cpp
@@ -70,6 +70,17 @@ static void BM_regex_run_alphabet_matcher(benchmark::State& state) {
 }
 BENCHMARK(BM_regex_run_alphabet_matcher);
 
+static void BM_regex_run_alternation_loop_matcher(benchmark::State& state) {
+  std::regex r("(a|b)*c");
+  std::string input;
+  input.append(1 << 8, 'a');
+
+  for (auto _ : state) {
+    std::regex_search(input, r);
+  }
+}
+BENCHMARK(BM_regex_run_alternation_loop_matcher);
+
 static void BM_regex_run_mail_matcher(benchmark::State& state) {
   std::regex r(
       R"regex((?:(?:[^<>()\[\].,;:\s@"]+(?:\.[^<>()\[\].,;:\s@"]+)*)|".+")@(?:(?:[^<>()\[\].,;:\s@"]+\.)+[^<>()\[\].,;:\s@"]{2,}))regex");

>From 70903b1d8eb2556fe390f6220a20766e055026fe Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Thu, 20 Aug 2026 18:34:12 +0200
Subject: [PATCH 18/21] Fix stuff

---
 libcxx/include/__regex/interpreter.h | 190 +--------------------------
 1 file changed, 6 insertions(+), 184 deletions(-)

diff --git a/libcxx/include/__regex/interpreter.h b/libcxx/include/__regex/interpreter.h
index 88149795daef1..b9c38fd6b9468 100644
--- a/libcxx/include/__regex/interpreter.h
+++ b/libcxx/include/__regex/interpreter.h
@@ -16,9 +16,10 @@
 #include <__algorithm/transform.h>
 #include <__config>
 #include <__iterator/back_insert_iterator.h>
-#include <__locale>
+#include <__locale_dir/ctype_base.h>
 #include <__regex/regex_error.h>
 #include <__utility/pair.h>
+#include <__utility/scope_guard.h>
 #include <__utility/to_underlying.h>
 #include <__vector/vector.h>
 #include <stack>
@@ -438,7 +439,6 @@ pair<bool, size_t> __exec_lookahead(
     return __current_pos;
   }
 
-  [[clang::preserve_none]]
   pair<bool, size_t> __execute(const _CharT* __first, const _CharT* __last, __global_state& __gstate) {
     const __interpreter_info<_CharT>* const __code = __gstate.__machine().data();
     auto __current_pos                             = __current_pos_;
@@ -803,12 +803,12 @@ class __interpreter {
     case __marked_subexpression_begin:
     case __marked_subexpression_end: {
       __read_uleb(__m, __pos);
-      [[clang::musttail]] return __get_possibly_matching_characters(__m, __pos);
+      return __get_possibly_matching_characters(__m, __pos);
     }
 
     case __relative_jump: {
       __pos += __read_uleb(__m, __pos);
-      [[clang::musttail]] return __get_possibly_matching_characters(__m, __pos);
+      return __get_possibly_matching_characters(__m, __pos);
     }
 
     case __branch_n_to_m_matcher:
@@ -817,14 +817,14 @@ class __interpreter {
       __read_uleb(__m, __pos);
       if (__initial_loop_values_[__loop_index + 1].__int_ == 0)
         return ~_MatchingSetWithEndT();
-      [[clang::musttail]] return __get_possibly_matching_characters(__m, __pos);
+      return __get_possibly_matching_characters(__m, __pos);
     }
 
     case __start_anchor:
     case __multiline_start_anchor:
     case __match_word_boundary:
     case __match_no_word_boundary: {
-      [[clang::musttail]] return __get_possibly_matching_characters(__m, __pos);
+      return __get_possibly_matching_characters(__m, __pos);
     }
 
     case __end_anchor:
@@ -870,183 +870,6 @@ class __interpreter {
     __machine_.reserve(16);
   }
 
-  void __fix_jumps(size_t __updated_instruction, ssize_t __offset) {
-    vector<pair<size_t, ssize_t>> __todo;
-    __todo.emplace_back(__updated_instruction, __offset);
-    auto __code = __machine_.data();
-
-    while (!__todo.empty()) {
-      size_t __pos = 0;
-      switch (__code[__pos++].__state_) {
-        using enum __state;
-      case __start_anchor:
-      case __end_anchor:
-      case __multiline_start_anchor:
-      case __multiline_end_anchor:
-      case __match_any:
-      case __match_any_except_newline:
-      case __match_word_boundary:
-      case __match_no_word_boundary:
-        break;
-
-      // Consuming matches
-      case __match_char:
-      case __match_icase_char:
-        ++__pos;
-        break;
-
-      case __match_simple_character_list:
-        __pos += sizeof(_MatchingSetT);
-        break;
-
-      case __match_backref:
-      case __match_icase_backref:
-      case __marked_subexpression_begin:
-      case __marked_subexpression_end:
-        __read_uleb(__code, __pos);
-        break;
-
-      case __match_character_list:
-      case __match_no_character_list: {
-        static constexpr auto __buffer_size =
-            std::max(sizeof(typename _Traits::char_class_type) / sizeof(_CharT), size_t(1));
-        __pos += 2 * __buffer_size;
-        for (size_t __i = 0; __i != 6; ++__i)
-          __read_uleb(__code, __pos);
-      } break;
-
-      // Lookahead
-      case __positive_lookahead:
-      case __negative_lookahead:
-        std::__libcpp_unreachable();
-
-      // Jumps
-      case __relative_jump: {
-        auto __instr_start = __pos;
-        auto __jump_offset = __read_uleb(__code, __pos);
-        if (__pos < __todo.back().first && __pos + __jump_offset > __todo.back().first)
-          __jump_offset += __todo.back().second;
-        auto __num_size = __pos - __instr_start;
-        vector<__interpreter_info<_CharT>> __buffer;
-        __write_uleb(__buffer, __jump_offset);
-        if (__buffer.size() == __num_size) {
-          std::copy(__buffer.begin(), __buffer.end(), __code + __instr_start);
-        } else {
-
-        }
-      }
-
-      case __conditional_jump_forward:
-      case __conditional_jump_backward:
-
-      // Branches
-      case __branch_n_to_m_matcher:
-      case __branch_nongreedy_n_to_m_matcher:
-      case __branch_alternative:
-
-      // End state
-      case __end_state:
-        return;
-      }
-    }
-  }
-
-  void __optimize() {
-    auto __code  = __machine_.data();
-    size_t __pos = 0;
-    while (__pos != __machine_.size()) {
-      switch (__code[__pos++].__state_) {
-        using enum __state;
-      case __start_anchor:
-      case __end_anchor:
-      case __multiline_start_anchor:
-      case __multiline_end_anchor:
-      case __match_any:
-      case __match_any_except_newline:
-      case __match_word_boundary:
-      case __match_no_word_boundary:
-        break;
-
-      case __match_char:
-      case __match_icase_char:
-        ++__pos;
-        break;
-
-      case __match_simple_character_list:
-        __pos += sizeof(_MatchingSetT);
-        break;
-
-      case __match_backref:
-      case __match_icase_backref:
-      case __marked_subexpression_begin:
-      case __marked_subexpression_end:
-      case __relative_jump:
-        __read_uleb(__code, __pos);
-        break;
-
-      case __match_character_list:
-      case __match_no_character_list: {
-        static constexpr auto __buffer_size =
-            std::max(sizeof(typename _Traits::char_class_type) / sizeof(_CharT), size_t(1));
-        __pos += 2 * __buffer_size;
-        for (size_t __i = 0; __i != 6; ++__i)
-          __read_uleb(__code, __pos);
-      } break;
-
-      // Lookahead
-      case __positive_lookahead:
-      case __negative_lookahead:
-        return;
-
-      // Jumps
-      case __conditional_jump_forward:
-      case __conditional_jump_backward:
-        __pos += sizeof(_MatchingSetT);
-        __read_uleb(__code, __pos);
-        break;
-
-      // Branches
-      case __branch_n_to_m_matcher:
-      case __branch_nongreedy_n_to_m_matcher: {
-        auto __instr_start    = __pos - 1;
-        auto __loop_index     = __read_uleb(__code, __pos);
-        auto __again_pos_base = __pos;
-        auto __again_pos      = __again_pos_base - __read_uleb(__code, __pos);
-        auto __instr_size     = __pos - __instr_start;
-
-        if (__initial_loop_values_[__loop_index + 1].__int_ != 0 ||
-            __initial_loop_values_[__loop_index + 2].__int_ != numeric_limits<size_t>::max())
-          break;
-
-        if constexpr (__is_same(_CharT, char)) {
-          if (auto __expr1_set = __get_possibly_matching_characters(__machine_.data(), __again_pos);
-              (__expr1_set & __get_possibly_matching_characters(__machine_.data(), __pos)) == _MatchingSetT()) {
-            {
-              vector<__interpreter_info<_CharT>> __buffer;
-              __buffer.push_back(__state::__conditional_jump_backward);
-              __interpreter_info<_CharT> __sbuffer[sizeof(_MatchingSetT)];
-              __builtin_memcpy(__sbuffer, &__expr1_set, sizeof(_MatchingSetT));
-              __buffer.append_range(__sbuffer);
-              __write_uleb(__buffer, __instr_start - __again_pos);
-              __machine_.erase(__machine_.begin() + __instr_start, __machine_.begin() + __instr_start + __instr_size);
-              __machine_.insert(__machine_.begin() + __instr_start, __buffer.begin(), __buffer.end());
-              __fix_jumps(__instr_start, __buffer.size() - __instr_size);
-            }
-            [[clang::musttail]] return __optimize();
-          }
-        }
-        break;
-      }
-
-      case __branch_alternative:
-
-      // End state
-      case __end_state:
-        return;
-      }
-    }
-  }
-
   void __push_any_matcher() { push_back(__state::__match_any); }
   void __push_any_except_newline_matcher() { push_back(__state::__match_any_except_newline); }
   void __push_end_state() { push_back(__state::__end_state); }
@@ -1228,7 +1051,6 @@ class __interpreter {
 
   size_t size() const { return __machine_.size(); }
 
-  // [[clang::preserve_none]]
   pair<bool, const _CharT*>
   __execute(__global_execution_state<_CharT, _Traits>& __gexec_state,
             const _CharT* __first,

>From 8a084d8a072853fbd83563be58fc0ecf16313085 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Thu, 20 Aug 2026 23:06:20 +0200
Subject: [PATCH 19/21] fix lookahead

---
 libcxx/include/__regex/basic_parser.h |   1 -
 libcxx/include/__regex/ecma_parser.h  |   1 -
 libcxx/include/__regex/interpreter.h  | 264 ++++++++++++++------------
 libcxx/include/__regex/regex_error.h  |   2 +
 4 files changed, 141 insertions(+), 127 deletions(-)

diff --git a/libcxx/include/__regex/basic_parser.h b/libcxx/include/__regex/basic_parser.h
index e9948015dcd84..9b8caeb688f4a 100644
--- a/libcxx/include/__regex/basic_parser.h
+++ b/libcxx/include/__regex/basic_parser.h
@@ -229,7 +229,6 @@ class __parser {
   void __parse_basic() {
     __parse_basic_expr();
     __machine_.__push_end_state();
-    __machine_.__optimize();
   }
 
   void __parse_grep() {
diff --git a/libcxx/include/__regex/ecma_parser.h b/libcxx/include/__regex/ecma_parser.h
index 06bb235caeeb9..6499349410a0e 100644
--- a/libcxx/include/__regex/ecma_parser.h
+++ b/libcxx/include/__regex/ecma_parser.h
@@ -294,7 +294,6 @@ class __parser {
     if (__first_ != __last_)
       std::__throw_regex_error<regex_constants::__re_err_parse>();
     __machine_.__push_end_state();
-    __machine_.__optimize();
   }
 
   __interpreter<_CharT, _Traits> __extract_interpreter() { return std::move(__machine_); }
diff --git a/libcxx/include/__regex/interpreter.h b/libcxx/include/__regex/interpreter.h
index b9c38fd6b9468..cb9977b03c11b 100644
--- a/libcxx/include/__regex/interpreter.h
+++ b/libcxx/include/__regex/interpreter.h
@@ -13,6 +13,7 @@
 #include <__algorithm/equal.h>
 #include <__algorithm/min.h>
 #include <__algorithm/reverse.h>
+#include <__algorithm/reverse_copy.h>
 #include <__algorithm/transform.h>
 #include <__config>
 #include <__iterator/back_insert_iterator.h>
@@ -372,42 +373,43 @@ struct __local_execution_state {
     return {__found, false, __current_pos};
   }
 
-  /*
-pair<bool, size_t> __exec_lookahead(
-    const _CharT* const __first,
-    const _CharT* const __last,
-    const __global_state& __gstate,
-    const __interpreter_info<_CharT>* const __code,
-    size_t __current_pos,
-    bool __is_positive) {
-  auto __jump_offset    = __read_uleb(__code, __current_pos);
-  auto __submatch_count = __read_uleb(__code, __current_pos);
-  auto __submatch_base  = __read_uleb(__code, __current_pos);
-  auto __loop_count     = __read_uleb(__code, __current_pos);
-
-  auto __initial_loop_values = std::make_unique_for_overwrite<__loop_value<_CharT>[]>(__loop_count);
-
-  for (size_t __i = 0; __i != __loop_count; ++__i)
-    __initial_loop_values[__i] = __read_uleb(__code, __current_pos);
-
-  __global_state __gexec_state{{}, __gstate.__machine_, __submatch_count, __gstate.__flags_};
-  __gexec_state.__flags_ &= ~regex_constants::__full_match;
-  auto& __s = __gexec_state.__states_.emplace_back();
-  if (__loop_count > 0)
-    __s.__sub_matches_ = std::make_unique<pair<const _CharT*, const _CharT*>[]>(__submatch_count);
-  __s.__current_     = __current_;
-  __s.__loop_values_ = std::move(__initial_loop_values);
-  __s.__current_pos_ = __current_pos;
-  if (__gexec_state.__execute(__first, __last) != __is_positive)
-    return {false, __current_pos};
-  if (__is_positive) {
-    auto& __matched_state = __gexec_state.__states_.back();
-    std::copy_n(__matched_state.__sub_matches_.get(), __submatch_count, __get_submatch(__submatch_base));
+  pair<bool, size_t> __exec_lookahead(
+      const _CharT* const __first,
+      const _CharT* const __last,
+      const _CharT* __current,
+      const __global_state& __gstate,
+      const __interpreter_info<_CharT>* const __code,
+      size_t __current_pos,
+      bool __is_positive) {
+    auto __jump_offset    = __read_uleb(__code, __current_pos);
+    auto __submatch_count = __read_uleb(__code, __current_pos);
+    auto __submatch_base  = __read_uleb(__code, __current_pos);
+    auto __loop_count     = __read_uleb(__code, __current_pos);
+
+    vector<__loop_value<_CharT>> __initial_loop_values;
+
+    for (size_t __i = 0; __i != __loop_count; ++__i)
+      __initial_loop_values.push_back(__read_uleb(__code, __current_pos));
+
+    __global_state __gexec_state{
+        {__loop_count, __gstate.__states_.__get_submatch_count()},
+        __gstate.__machine_,
+        __submatch_count,
+        __gstate.__flags_};
+    __gexec_state.__flags_ &= ~regex_constants::__full_match;
+    vector<sub_match<const _CharT*>> __sub_matches;
+    if (__gexec_state.__execute(__first, __current, __last, __sub_matches, __current_pos, __initial_loop_values)
+            .first != __is_positive)
+      return {false, __current_pos};
+    if (__is_positive) {
+      size_t __index = 0;
+      for (auto __iter = __sub_matches.begin(); __iter != __sub_matches.end(); ++__iter) {
+        __get_submatch(__submatch_base + __index++) = *__iter;
+      }
+    }
+    __current_pos += __jump_offset;
+    return {true, __current_pos};
   }
-  __current_pos += __jump_offset;
-  return {true, __current_pos};
-}
-  */
 
   size_t __exec_branch_n_to_m_matcher(
       __global_state& __gstate,
@@ -616,13 +618,13 @@ pair<bool, size_t> __exec_lookahead(
 
       case __negative_lookahead:
       case __positive_lookahead: {
-        // if (auto __result =
-        //         __exec_lookahead(__first, __last, __gstate, __code, __current_pos, (__st == __positive_lookahead));
-        //     __result.first)
-        //   __current_pos = __result.second;
-        // else
-        //   return {false, __counter};
-      } // break;
+        if (auto __result = __exec_lookahead(
+                __first, __last, __current, __gstate, __code, __current_pos, (__st == __positive_lookahead));
+            __result.first)
+          __current_pos = __result.second;
+        else
+          return {false, __counter};
+      } break;
 
       default:
         std::__libcpp_unreachable();
@@ -634,8 +636,8 @@ pair<bool, size_t> __exec_lookahead(
 template <class _CharT, class _Traits>
 class __local_execution_state_stack {
   char* __data_begin_ = nullptr;
-  size_t __base_offset_;
-  size_t __object_size_;
+  const size_t __base_offset_;
+  const size_t __object_size_;
   size_t __size_     = 0;
   size_t __capacity_ = 0;
 
@@ -652,6 +654,8 @@ class __local_execution_state_stack {
   __local_execution_state_stack& operator=(const __local_execution_state_stack&) = delete;
   ~__local_execution_state_stack() { __builtin_free(__data_begin_); }
 
+  size_t __get_submatch_count() const { return __base_offset_ / sizeof(pair<const _CharT*, const _CharT*>); }
+
   bool empty() const { return __size_ == 0; }
 
   value_type& back() {
@@ -736,6 +740,96 @@ struct __global_execution_state {
       return false;
     }
   }
+
+  pair<bool, const _CharT*>
+  __execute(const _CharT* __first,
+            const _CharT* __current,
+            const _CharT* __last,
+            vector<sub_match<const _CharT*>>& __sub_matches,
+            size_t __exec_pos,
+            const vector<__loop_value<_CharT>>& __initial_loop_values) {
+    using __local_state = __local_execution_state<_CharT, _Traits>;
+
+    auto __copy_to_submatches =
+        [&](pair<const _CharT*, const _CharT*>* __from, size_t __count, vector<sub_match<const _CharT*>>& __to) {
+          __to.clear();
+          std::transform(
+              std::make_reverse_iterator(__from + __count),
+              std::make_reverse_iterator(__from),
+              std::back_inserter(__to),
+              [&](pair<const _CharT*, const _CharT*> __v) {
+                sub_match<const _CharT*> __ret;
+                __ret.first   = __v.first ? __v.first : __last;
+                __ret.second  = __v.first ? __v.second : __last;
+                __ret.matched = __v.first;
+                return __ret;
+              });
+        };
+
+    const auto __sizeof_submatches  = sizeof(pair<const _CharT*, const _CharT*>) * __submatch_count_;
+    const auto __sizeof_loop_values = sizeof(__loop_value<_CharT>) * __initial_loop_values.size();
+    const auto __state_size         = __sizeof_submatches + sizeof(__local_state) + __sizeof_loop_values;
+
+    auto* __base_state_start      = static_cast<char*>(__builtin_alloca(2 * __state_size));
+    auto* __base_state_submatches = reinterpret_cast<pair<const _CharT*, const _CharT*>*>(__base_state_start);
+    auto* __base_state            = reinterpret_cast<__local_state*>(__base_state_start + __sizeof_submatches);
+    auto* __tmp_state_start       = __base_state_start + __state_size;
+    auto* __tmp_state             = reinterpret_cast<__local_state*>(__tmp_state_start + __sizeof_submatches);
+
+    std::uninitialized_fill_n(
+        __base_state_submatches, __submatch_count_, pair<const _CharT*, const _CharT*>{nullptr, nullptr});
+    std::__construct_at(__base_state, __current, __exec_pos);
+    std::uninitialized_copy(
+        __initial_loop_values.begin(),
+        __initial_loop_values.end(),
+        reinterpret_cast<__loop_value<_CharT>*>(__base_state_start + __sizeof_submatches + sizeof(__local_state)));
+
+    auto [__base_state_matched, __gcounter] = __base_state->__execute(__first, __last, *this);
+
+    size_t __length = __last - __first + 1;
+    if (__machine_.__find_longest_) {
+      if (!__base_state_matched)
+        __base_state->__current_ = __current;
+      bool __found_match = __base_state_matched;
+      while (!__states_.empty()) {
+        if (__gcounter / _LIBCPP_REGEX_COMPLEXITY_FACTOR >= __length)
+          std::__throw_regex_error<regex_constants::error_complexity>();
+        __states_.pop(__tmp_state);
+        auto [__success, __counter] = __tmp_state->__execute(__first, __last, *this);
+        __gcounter += __counter;
+        if (__success) {
+          if (!__found_match || __base_state->__current_ < __tmp_state->__current_)
+            __builtin_memcpy(__base_state_start, __tmp_state_start, __state_size);
+          if (__base_state->__current_ == __last) {
+            __copy_to_submatches(__base_state_submatches, __submatch_count_, __sub_matches);
+            return {true, __base_state->__current_};
+          }
+          __found_match = true;
+        }
+      }
+      if (!__found_match)
+        return {false, {}};
+      __copy_to_submatches(__base_state_submatches, __submatch_count_, __sub_matches);
+      return {true, __base_state->__current_};
+    } else {
+      if (__base_state_matched) {
+        __copy_to_submatches(__base_state_submatches, __submatch_count_, __sub_matches);
+        return {true, __base_state->__current_};
+      }
+      while (!__states_.empty()) {
+        if (__gcounter / _LIBCPP_REGEX_COMPLEXITY_FACTOR >= __length)
+          std::__throw_regex_error<regex_constants::error_complexity>();
+        __states_.pop(__base_state);
+        if (auto [__success, __counter] = __base_state->__execute(__first, __last, *this); __success) {
+          __copy_to_submatches(__base_state_submatches, __submatch_count_, __sub_matches);
+          return {true, __base_state->__current_};
+        } else {
+          __gcounter += __counter;
+        }
+      }
+      return {false, {}};
+    }
+  }
 };
 
 template <class _CharT, class _Traits>
@@ -1056,87 +1150,7 @@ class __interpreter {
             const _CharT* __first,
             const _CharT* __last,
             vector<sub_match<const _CharT*>>& __sub_matches) const {
-    using __local_state = __local_execution_state<_CharT, _Traits>;
-
-    auto __copy_to_submatches =
-        [&](pair<const _CharT*, const _CharT*>* __from, size_t __count, vector<sub_match<const _CharT*>>& __to) {
-          __to.clear();
-          std::transform(
-              std::make_reverse_iterator(__from + __count),
-              std::make_reverse_iterator(__from),
-              std::back_inserter(__to),
-              [&](pair<const _CharT*, const _CharT*> __v) {
-                sub_match<const _CharT*> __ret;
-                __ret.first   = __v.first ? __v.first : __last;
-                __ret.second  = __v.first ? __v.second : __last;
-                __ret.matched = __v.first;
-                return __ret;
-              });
-        };
-
-    const auto __sizeof_submatches  = sizeof(pair<const _CharT*, const _CharT*>) * __gexec_state.__submatch_count_;
-    const auto __sizeof_loop_values = sizeof(__loop_value<_CharT>) * __initial_loop_values_.size();
-    const auto __state_size         = __sizeof_submatches + sizeof(__local_state) + __sizeof_loop_values;
-
-    auto* __base_state_start      = static_cast<char*>(__builtin_alloca(2 * __state_size));
-    auto* __base_state_submatches = reinterpret_cast<pair<const _CharT*, const _CharT*>*>(__base_state_start);
-    auto* __base_state            = reinterpret_cast<__local_state*>(__base_state_start + __sizeof_submatches);
-    auto* __tmp_state_start       = __base_state_start + __state_size;
-    auto* __tmp_state             = reinterpret_cast<__local_state*>(__tmp_state_start + __sizeof_submatches);
-
-    std::uninitialized_fill_n(
-        __base_state_submatches, __gexec_state.__submatch_count_, pair<const _CharT*, const _CharT*>{nullptr, nullptr});
-    std::__construct_at(__base_state, __first, 0);
-    std::uninitialized_copy(
-        __initial_loop_values_.begin(),
-        __initial_loop_values_.end(),
-        reinterpret_cast<__loop_value<_CharT>*>(__base_state_start + __sizeof_submatches + sizeof(__local_state)));
-
-    auto [__base_state_matched, __gcounter] = __base_state->__execute(__first, __last, __gexec_state);
-
-    size_t __length = __last - __first + 1;
-    if (__gexec_state.__machine_.__find_longest_) {
-      if (!__base_state_matched)
-        __base_state->__current_ = __first;
-      bool __found_match = __base_state_matched;
-      while (!__gexec_state.__states_.empty()) {
-        if (__gcounter / _LIBCPP_REGEX_COMPLEXITY_FACTOR >= __length)
-          std::__throw_regex_error<regex_constants::error_complexity>();
-        __gexec_state.__states_.pop(__tmp_state);
-        auto [__success, __counter] = __tmp_state->__execute(__first, __last, __gexec_state);
-        __gcounter += __counter;
-        if (__success) {
-          if (!__found_match || __base_state->__current_ < __tmp_state->__current_)
-            __builtin_memcpy(__base_state_start, __tmp_state_start, __state_size);
-          if (__base_state->__current_ == __last) {
-            __copy_to_submatches(__base_state_submatches, __gexec_state.__submatch_count_, __sub_matches);
-            return {true, __base_state->__current_};
-          }
-          __found_match = true;
-        }
-      }
-      if (!__found_match)
-        return {false, {}};
-      __copy_to_submatches(__base_state_submatches, __gexec_state.__submatch_count_, __sub_matches);
-      return {true, __base_state->__current_};
-    } else {
-      if (__base_state_matched) {
-        __copy_to_submatches(__base_state_submatches, __gexec_state.__submatch_count_, __sub_matches);
-        return {true, __base_state->__current_};
-      }
-      while (!__gexec_state.__states_.empty()) {
-        if (__gcounter / _LIBCPP_REGEX_COMPLEXITY_FACTOR >= __length)
-          std::__throw_regex_error<regex_constants::error_complexity>();
-        __gexec_state.__states_.pop(__base_state);
-        if (auto [__success, __counter] = __base_state->__execute(__first, __last, __gexec_state); __success) {
-          __copy_to_submatches(__base_state_submatches, __gexec_state.__submatch_count_, __sub_matches);
-          return {true, __base_state->__current_};
-        } else {
-          __gcounter += __counter;
-        }
-      }
-      return {false, {}};
-    }
+    return __gexec_state.__execute(__first, __first, __last, __sub_matches, 0, __initial_loop_values_);
   }
 
   pair<bool, const _CharT*> __execute_match(
diff --git a/libcxx/include/__regex/regex_error.h b/libcxx/include/__regex/regex_error.h
index 4bf29d74c7282..35f8cb2ed6147 100644
--- a/libcxx/include/__regex/regex_error.h
+++ b/libcxx/include/__regex/regex_error.h
@@ -155,6 +155,7 @@ enum error_type {
 
 } // namespace regex_constants
 
+_LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS
 class _LIBCPP_EXPORTED_FROM_ABI regex_error : public runtime_error {
   regex_constants::error_type __code_;
 
@@ -164,6 +165,7 @@ class _LIBCPP_EXPORTED_FROM_ABI regex_error : public runtime_error {
   ~regex_error() _NOEXCEPT override;
   [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI regex_constants::error_type code() const { return __code_; }
 };
+_LIBCPP_END_EXPLICIT_ABI_ANNOTATIONS
 
 template <regex_constants::error_type _Ev>
 [[__noreturn__]] inline _LIBCPP_HIDE_FROM_ABI void __throw_regex_error() {

>From 51e0fd702c7075cdce4c7d4d9656c300d40ec49e Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Fri, 21 Aug 2026 15:53:08 +0200
Subject: [PATCH 20/21] Fixes

---
 libcxx/include/__regex/basic_parser.h    |  6 +-
 libcxx/include/__regex/ecma_parser.h     |  6 +-
 libcxx/include/__regex/extended_parser.h |  4 +-
 libcxx/include/__regex/interpreter.h     | 79 ++++++++++++------------
 libcxx/include/__regex/parser_common.h   |  4 +-
 libcxx/include/regex                     | 10 +--
 6 files changed, 52 insertions(+), 57 deletions(-)

diff --git a/libcxx/include/__regex/basic_parser.h b/libcxx/include/__regex/basic_parser.h
index 9b8caeb688f4a..27f4093e785dc 100644
--- a/libcxx/include/__regex/basic_parser.h
+++ b/libcxx/include/__regex/basic_parser.h
@@ -9,17 +9,15 @@
 #ifndef _LIBCPP___REGEX_BASIC_PARSER_H
 #define _LIBCPP___REGEX_BASIC_PARSER_H
 
-#include <__algorithm/search.h>
 #include <__config>
 #include <__iterator/next.h>
 #include <__regex/interpreter.h>
 #include <__regex/parser_common.h>
 #include <__regex/regex_error.h>
-#include <__utility/exchange.h>
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-namespace __regex::__basic::inline __preserve_none {
+namespace __regex::__basic {
 
 template <class _CharT, class _Traits, class _ForwardIterator>
 class __parser {
@@ -260,7 +258,7 @@ class __parser {
   __interpreter<_CharT, _Traits> __extract_interpreter() { return std::move(__machine_); }
   size_t mark_count() const { return __marked_count_; }
 };
-} // namespace __regex::__basic::inline __preserve_none
+} // namespace __regex::__basic
 
 _LIBCPP_END_NAMESPACE_STD
 
diff --git a/libcxx/include/__regex/ecma_parser.h b/libcxx/include/__regex/ecma_parser.h
index 6499349410a0e..4e0599ad1add8 100644
--- a/libcxx/include/__regex/ecma_parser.h
+++ b/libcxx/include/__regex/ecma_parser.h
@@ -11,7 +11,9 @@
 
 #include <__config>
 #include <__regex/interpreter.h>
+#include <__regex/parser_common.h>
 #include <__regex/regex_error.h>
+#include <__utility/exchange.h>
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -211,7 +213,7 @@ class __parser {
     }
 
     case '[':
-      return __parse_bracket_expression(__machine_, __first_, __last_, __flags_);
+      return __regex::__parse_bracket_expression(__machine_, __first_, __last_, __flags_);
 
     case '(': {
       ++__first_;
@@ -263,7 +265,7 @@ class __parser {
 
     if (!__parse_atom())
       return false;
-    __parse_dupl_symbol(__machine_, __first_, __last_, __expr_start, true);
+    __regex::__parse_dupl_symbol(__machine_, __first_, __last_, __expr_start, true);
     return true;
   }
 
diff --git a/libcxx/include/__regex/extended_parser.h b/libcxx/include/__regex/extended_parser.h
index 76e2fa411a422..0176883fd4bc8 100644
--- a/libcxx/include/__regex/extended_parser.h
+++ b/libcxx/include/__regex/extended_parser.h
@@ -9,13 +9,11 @@
 #ifndef _LIBCPP___REGEX_EXTENDED_PARSER_H
 #define _LIBCPP___REGEX_EXTENDED_PARSER_H
 
-#include <__algorithm/search.h>
 #include <__config>
 #include <__iterator/next.h>
 #include <__regex/interpreter.h>
 #include <__regex/parser_common.h>
 #include <__regex/regex_error.h>
-#include <__utility/exchange.h>
 #include <string>
 
 _LIBCPP_BEGIN_NAMESPACE_STD
@@ -81,7 +79,7 @@ class __parser {
     default:
       if (regex_constants::__get_grammar(__flags_) == regex_constants::awk) {
         __first_ = __next;
-        __machine_.__push_char_matcher(__parse_awk_escape<_CharT>(__first_, __last_));
+        __machine_.__push_char_matcher(__regex::__parse_awk_escape<_CharT>(__first_, __last_));
         return true;
       }
       auto __val = __machine_.__get_traits().value(*__next, 10);
diff --git a/libcxx/include/__regex/interpreter.h b/libcxx/include/__regex/interpreter.h
index cb9977b03c11b..8a9afab40cd6a 100644
--- a/libcxx/include/__regex/interpreter.h
+++ b/libcxx/include/__regex/interpreter.h
@@ -9,21 +9,18 @@
 #ifndef _LIBCPP___REGEX_INTERPRETER_H
 #define _LIBCPP___REGEX_INTERPRETER_H
 
-#include <__algorithm/copy_if.h>
 #include <__algorithm/equal.h>
-#include <__algorithm/min.h>
-#include <__algorithm/reverse.h>
-#include <__algorithm/reverse_copy.h>
 #include <__algorithm/transform.h>
 #include <__config>
 #include <__iterator/back_insert_iterator.h>
 #include <__locale_dir/ctype_base.h>
+#include <__memory/uninitialized_algorithms.h>
 #include <__regex/regex_error.h>
+#include <__type_traits/make_signed.h>
 #include <__utility/pair.h>
 #include <__utility/scope_guard.h>
-#include <__utility/to_underlying.h>
+#include <__utility/unreachable.h>
 #include <__vector/vector.h>
-#include <stack>
 #include <string_view>
 
 _LIBCPP_BEGIN_NAMESPACE_STD
@@ -73,8 +70,8 @@ struct __state {
 };
 
 namespace __regex {
-using _MatchingSetT        = unsigned _BitInt(256);
-using _MatchingSetWithEndT = unsigned _BitInt(257);
+using _MatchingSetT _LIBCPP_NODEBUG        = unsigned _BitInt(256);
+using _MatchingSetWithEndT _LIBCPP_NODEBUG = unsigned _BitInt(257);
 
 enum class __state : uint8_t {
   // Anchors
@@ -156,7 +153,7 @@ template <class _CharT>
 size_t __read_uleb(const __interpreter_info<_CharT>* __machine, size_t& __current_pos) {
   auto __val = __machine[__current_pos++].__int_;
   if (__val & 0x80) {
-    auto __res    = __read_uleb_impl(__machine, __current_pos);
+    auto __res    = __regex::__read_uleb_impl(__machine, __current_pos);
     __current_pos = __res.second;
     return __res.first;
   }
@@ -210,7 +207,7 @@ struct __global_execution_state;
 
 template <class _CharT, class _Traits>
 struct __local_execution_state {
-  using __global_state = __global_execution_state<_CharT, _Traits>;
+  using __global_state _LIBCPP_NODEBUG = __global_execution_state<_CharT, _Traits>;
 
   pair<const _CharT*, const _CharT*>& __get_submatch(size_t __n) {
     return *reinterpret_cast<pair<const _CharT*, const _CharT*>*>(
@@ -259,19 +256,19 @@ struct __local_execution_state {
     for (size_t __i = 0; __i != __buffer_size; ++__i)
       __buffer[__i] = __code[__current_pos++].__char_;
     typename _Traits::char_class_type __mask;
-    __builtin_memcpy(&__mask, __buffer, sizeof(typename _Traits::char_class_type));
+    __builtin_memcpy(std::addressof(__mask), __buffer, sizeof(typename _Traits::char_class_type));
 
     for (size_t __i = 0; __i != __buffer_size; ++__i)
       __buffer[__i] = __code[__current_pos++].__char_;
     typename _Traits::char_class_type __neg_mask;
-    __builtin_memcpy(&__neg_mask, __buffer, sizeof(typename _Traits::char_class_type));
+    __builtin_memcpy(std::addressof(__neg_mask), __buffer, sizeof(typename _Traits::char_class_type));
 
-    auto __chars       = __read_uleb(__code, __current_pos);
-    auto __digraphs    = __read_uleb(__code, __current_pos) * 2;
-    auto __ranges      = __read_uleb(__code, __current_pos) * 4;
-    auto __neg_chars   = __read_uleb(__code, __current_pos);
-    auto __equiv_count = __read_uleb(__code, __current_pos);
-    auto __equiv_size  = __read_uleb(__code, __current_pos);
+    auto __chars       = __regex::__read_uleb(__code, __current_pos);
+    auto __digraphs    = __regex::__read_uleb(__code, __current_pos) * 2;
+    auto __ranges      = __regex::__read_uleb(__code, __current_pos) * 4;
+    auto __neg_chars   = __regex::__read_uleb(__code, __current_pos);
+    auto __equiv_count = __regex::__read_uleb(__code, __current_pos);
+    auto __equiv_size  = __regex::__read_uleb(__code, __current_pos);
 
     bool __found = false;
 
@@ -355,7 +352,7 @@ struct __local_execution_state {
     auto __after_pos   = __current_pos + __equiv_size;
     auto __transformed = __gstate.__machine_.__traits_.transform_primary(__current, __current + 1);
     for (size_t __i = 0; __i != __equiv_count; ++__i) {
-      auto __size = __read_uleb(__code, __current_pos);
+      auto __size = __regex::__read_uleb(__code, __current_pos);
       basic_string<_CharT> __str;
       std::transform(__code + __current_pos,
                      __code + __current_pos + __size,
@@ -381,15 +378,15 @@ struct __local_execution_state {
       const __interpreter_info<_CharT>* const __code,
       size_t __current_pos,
       bool __is_positive) {
-    auto __jump_offset    = __read_uleb(__code, __current_pos);
-    auto __submatch_count = __read_uleb(__code, __current_pos);
-    auto __submatch_base  = __read_uleb(__code, __current_pos);
-    auto __loop_count     = __read_uleb(__code, __current_pos);
+    auto __jump_offset    = __regex::__read_uleb(__code, __current_pos);
+    auto __submatch_count = __regex::__read_uleb(__code, __current_pos);
+    auto __submatch_base  = __regex::__read_uleb(__code, __current_pos);
+    auto __loop_count     = __regex::__read_uleb(__code, __current_pos);
 
     vector<__loop_value<_CharT>> __initial_loop_values;
 
     for (size_t __i = 0; __i != __loop_count; ++__i)
-      __initial_loop_values.push_back(__read_uleb(__code, __current_pos));
+      __initial_loop_values.push_back(__regex::__read_uleb(__code, __current_pos));
 
     __global_state __gexec_state{
         {__loop_count, __gstate.__states_.__get_submatch_count()},
@@ -417,9 +414,9 @@ struct __local_execution_state {
       const _CharT* const __current,
       size_t __current_pos,
       bool __is_greedy) {
-    auto __loop_index     = __read_uleb(__code, __current_pos);
+    auto __loop_index     = __regex::__read_uleb(__code, __current_pos);
     auto __again_pos_base = __current_pos;
-    auto __again_pos      = __again_pos_base - __read_uleb(__code, __current_pos);
+    auto __again_pos      = __again_pos_base - __regex::__read_uleb(__code, __current_pos);
     if (__loop_values_[__loop_index + 1].__int_ > 0) {
       --__loop_values_[__loop_index + 1].__int_;
       __current_pos = __again_pos;
@@ -508,14 +505,14 @@ struct __local_execution_state {
       } break;
 
       case __branch_alternative: {
-        auto __offset = __read_uleb(__code, __current_pos);
+        auto __offset = __regex::__read_uleb(__code, __current_pos);
         __gstate.__states_.push(this);
         __gstate.__states_.back().__current_     = __current;
         __gstate.__states_.back().__current_pos_ = __current_pos + __offset;
       } break;
 
       case __relative_jump: {
-        __current_pos += __read_uleb(__code, __current_pos);
+        __current_pos += __regex::__read_uleb(__code, __current_pos);
       } break;
 
       case __conditional_jump_forward:
@@ -523,7 +520,7 @@ struct __local_execution_state {
         _MatchingSetT __set;
         __builtin_memcpy(&__set, __code + __current_pos, sizeof(_MatchingSetT));
         __current_pos += sizeof(_MatchingSetT);
-        auto __jump_offset = std::__to_signed_like(__read_uleb(__code, __current_pos));
+        auto __jump_offset = std::__to_signed_like(__regex::__read_uleb(__code, __current_pos));
         if (__st == __conditional_jump_backward)
           __jump_offset *= -1;
         if (__current == __last)
@@ -539,7 +536,7 @@ struct __local_execution_state {
       } break;
 
       case __match_backref: {
-        auto& __match = __get_submatch(__read_uleb(__code, __current_pos) - 1);
+        auto& __match = __get_submatch(__regex::__read_uleb(__code, __current_pos) - 1);
         if (__match.first == nullptr)
           return {false, __counter};
 
@@ -551,7 +548,7 @@ struct __local_execution_state {
       } break;
 
       case __match_icase_backref: {
-        auto& __match = __get_submatch(__read_uleb(__code, __current_pos) - 1);
+        auto& __match = __get_submatch(__regex::__read_uleb(__code, __current_pos) - 1);
         if (__match.first == nullptr)
           return {false, __counter};
 
@@ -597,12 +594,12 @@ struct __local_execution_state {
       } break;
 
       case __marked_subexpression_begin: {
-        auto __match                  = __read_uleb(__code, __current_pos);
+        auto __match                  = __regex::__read_uleb(__code, __current_pos);
         __get_submatch(__match).first = __current;
       } break;
 
       case __marked_subexpression_end: {
-        auto __match                   = __read_uleb(__code, __current_pos);
+        auto __match                   = __regex::__read_uleb(__code, __current_pos);
         __get_submatch(__match).second = __current;
       } break;
 
@@ -896,19 +893,19 @@ class __interpreter {
 
     case __marked_subexpression_begin:
     case __marked_subexpression_end: {
-      __read_uleb(__m, __pos);
+      __regex::__read_uleb(__m, __pos);
       return __get_possibly_matching_characters(__m, __pos);
     }
 
     case __relative_jump: {
-      __pos += __read_uleb(__m, __pos);
+      __pos += __regex::__read_uleb(__m, __pos);
       return __get_possibly_matching_characters(__m, __pos);
     }
 
     case __branch_n_to_m_matcher:
     case __branch_nongreedy_n_to_m_matcher: {
-      auto __loop_index = __read_uleb(__m, __pos);
-      __read_uleb(__m, __pos);
+      auto __loop_index = __regex::__read_uleb(__m, __pos);
+      __regex::__read_uleb(__m, __pos);
       if (__initial_loop_values_[__loop_index + 1].__int_ == 0)
         return ~_MatchingSetWithEndT();
       return __get_possibly_matching_characters(__m, __pos);
@@ -935,7 +932,7 @@ class __interpreter {
       _MatchingSetT __set;
       __builtin_memcpy(&__set, __m + __pos, sizeof(_MatchingSetT));
       __pos += sizeof(_MatchingSetT);
-      auto __jump_offset = std::__to_signed_like(__read_uleb(__m, __pos));
+      auto __jump_offset = std::__to_signed_like(__regex::__read_uleb(__m, __pos));
       if (__state == __conditional_jump_backward)
         __jump_offset *= -1;
       return __set | __get_possibly_matching_characters(__m, __pos + __jump_offset);
@@ -1025,7 +1022,7 @@ class __interpreter {
             (__expr1_set & __get_possibly_matching_characters(__machine_.data(), __expr2_start)) == _MatchingSetT()) {
           __buffer.push_back(__state::__conditional_jump_forward);
           __interpreter_info<_CharT> __sbuffer[sizeof(_MatchingSetT)];
-          __builtin_memcpy(__sbuffer, &__expr1_set, sizeof(_MatchingSetT));
+          __builtin_memcpy(__sbuffer, std::addressof(__expr1_set), sizeof(_MatchingSetT));
           __buffer.append_range(__sbuffer);
           __write_uleb(__buffer, __expr2_start - __expr1_start);
           insert(__expr1_start, __buffer);
@@ -1094,9 +1091,9 @@ class __interpreter {
     push_back(__negate ? __state::__match_no_character_list : __state::__match_character_list);
 
     _CharT __buffer[std::max(sizeof(typename _Traits::char_class_type) / sizeof(_CharT), size_t(1))];
-    __builtin_memcpy(__buffer, &__expr.__mask_, sizeof(__buffer));
+    __builtin_memcpy(__buffer, std::addressof(__expr.__mask_), sizeof(__buffer));
     append_range(__buffer);
-    __builtin_memcpy(__buffer, &__expr.__neg_mask_, sizeof(__buffer));
+    __builtin_memcpy(__buffer, std::addressof(__expr.__neg_mask_), sizeof(__buffer));
     append_range(__buffer);
 
     basic_string<_CharT> __equivalences_buffer;
diff --git a/libcxx/include/__regex/parser_common.h b/libcxx/include/__regex/parser_common.h
index f7ea5418b0cc0..b47da1eb24987 100644
--- a/libcxx/include/__regex/parser_common.h
+++ b/libcxx/include/__regex/parser_common.h
@@ -350,12 +350,12 @@ bool __parse_expression_term(
     return false;
   if (*__first == '[' && *__next == '.') {
     __first = ++__next;
-    __parse_collating_symbol(__machine, __end_range, __first, __last);
+    __regex::__parse_collating_symbol(__machine, __end_range, __first, __last);
   } else if (auto __grammar = regex_constants::__get_grammar(__flags);
              __grammar == regex_constants::awk && *__first == '\\') {
     if (++__first == __last)
       return false;
-    __start_range = __parse_awk_escape<_CharT>(__first, __last);
+    __start_range = __regex::__parse_awk_escape<_CharT>(__first, __last);
   } else if (__grammar == regex_constants::ECMAScript && *__first == '\\') {
     if (++__first == __last)
       return false;
diff --git a/libcxx/include/regex b/libcxx/include/regex
index c5bad522a16f0..5b2fb412317d8 100644
--- a/libcxx/include/regex
+++ b/libcxx/include/regex
@@ -1242,7 +1242,7 @@ class __owns_one_state : public __has_one_state<_CharT> {
 public:
   _LIBCPP_HIDE_FROM_ABI explicit __owns_one_state(__node<_CharT>* __s) : base(__s) {}
 
-  ~__owns_one_state() override;
+  _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~__owns_one_state() override;
 };
 
 template <class _CharT>
@@ -1273,9 +1273,9 @@ void __empty_state<_CharT>::__exec(__state& __s) const {
 template <class _CharT>
 class __regex_search_state : public __empty_state<_CharT> {
 public:
-  explicit __regex_search_state(__node<_CharT>* __s) : __empty_state<_CharT>(__s) {}
+  _LIBCPP_HIDE_FROM_ABI explicit __regex_search_state(__node<_CharT>* __s) : __empty_state<_CharT>(__s) {}
 
-  virtual __regex::__search_result<_CharT> __exec_regex_search(
+  _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual __regex::__search_result<_CharT> __exec_regex_search(
       const _CharT* __first, const _CharT* __last, regex_constants::match_flag_type, size_t __marked_count) = 0;
 };
 
@@ -1298,7 +1298,7 @@ public:
     __state.__current_ = __res.second;
   }
 
-  __regex::__search_result<_CharT> __exec_regex_search(
+  _LIBCPP_HIDE_FROM_ABI __regex::__search_result<_CharT> __exec_regex_search(
       const _CharT* __first,
       const _CharT* __last,
       regex_constants::match_flag_type __flags,
@@ -2591,7 +2591,7 @@ bool basic_regex<_CharT, _Traits>::__search(
       return false;
     }
     vector<sub_match<const _CharT*>> __sub_matches(std::move(__res.__sub_matches_));
-    std::__destroy_at(&__res.__sub_matches_);
+    std::__destroy_at(std::addressof(__res.__sub_matches_));
     __m.__matches_[0].first   = __res.__match_first_;
     __m.__matches_[0].second  = __res.__match_last_;
     __m.__matches_[0].matched = true;

>From 2808b5a183828664ef1545dfb8c1eb4f52051b27 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Fri, 21 Aug 2026 16:47:16 +0200
Subject: [PATCH 21/21] More fixes

---
 libcxx/include/__regex/basic_parser.h    | 15 +++++++++++++++
 libcxx/include/__regex/ecma_parser.h     | 15 +++++++++++++++
 libcxx/include/__regex/extended_parser.h | 11 +++++++++++
 libcxx/include/__regex/interpreter.h     | 12 ++++++++++++
 libcxx/include/__regex/parser_common.h   | 15 +++++++++++++++
 libcxx/include/__regex/regex_error.h     |  4 ++++
 libcxx/include/module.modulemap.in       | 10 +++++++++-
 7 files changed, 81 insertions(+), 1 deletion(-)

diff --git a/libcxx/include/__regex/basic_parser.h b/libcxx/include/__regex/basic_parser.h
index 27f4093e785dc..cb777b7894334 100644
--- a/libcxx/include/__regex/basic_parser.h
+++ b/libcxx/include/__regex/basic_parser.h
@@ -9,11 +9,24 @@
 #ifndef _LIBCPP___REGEX_BASIC_PARSER_H
 #define _LIBCPP___REGEX_BASIC_PARSER_H
 
+#include <__algorithm/find.h>
 #include <__config>
+#include <__cstddef/size_t.h>
 #include <__iterator/next.h>
 #include <__regex/interpreter.h>
 #include <__regex/parser_common.h>
 #include <__regex/regex_error.h>
+#include <__utility/move.h>
+#include <__utility/swap.h>
+#include <cstdint>
+#include <limits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -262,4 +275,6 @@ class __parser {
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___REGEX_BASIC_PARSER_H
diff --git a/libcxx/include/__regex/ecma_parser.h b/libcxx/include/__regex/ecma_parser.h
index 4e0599ad1add8..8b55c66a25083 100644
--- a/libcxx/include/__regex/ecma_parser.h
+++ b/libcxx/include/__regex/ecma_parser.h
@@ -10,10 +10,23 @@
 #define _LIBCPP___REGEX_ECMA_PARSER_H
 
 #include <__config>
+#include <__cstddef/size_t.h>
+#include <__iterator/next.h>
+#include <__locale_dir/ctype_base.h>
 #include <__regex/interpreter.h>
 #include <__regex/parser_common.h>
 #include <__regex/regex_error.h>
 #include <__utility/exchange.h>
+#include <__utility/move.h>
+#include <cstdint>
+#include <limits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -305,4 +318,6 @@ class __parser {
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___REGEX_ECMA_PARSER_H
diff --git a/libcxx/include/__regex/extended_parser.h b/libcxx/include/__regex/extended_parser.h
index 0176883fd4bc8..9a48fa4662e5c 100644
--- a/libcxx/include/__regex/extended_parser.h
+++ b/libcxx/include/__regex/extended_parser.h
@@ -9,13 +9,22 @@
 #ifndef _LIBCPP___REGEX_EXTENDED_PARSER_H
 #define _LIBCPP___REGEX_EXTENDED_PARSER_H
 
+#include <__algorithm/find.h>
 #include <__config>
 #include <__iterator/next.h>
 #include <__regex/interpreter.h>
 #include <__regex/parser_common.h>
 #include <__regex/regex_error.h>
+#include <cstdint>
 #include <string>
 
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace __regex::__extended {
@@ -213,4 +222,6 @@ class __parser {
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___REGEX_EXTENDED_PARSER_H
diff --git a/libcxx/include/__regex/interpreter.h b/libcxx/include/__regex/interpreter.h
index 8a9afab40cd6a..73a5f1a4d7d7b 100644
--- a/libcxx/include/__regex/interpreter.h
+++ b/libcxx/include/__regex/interpreter.h
@@ -10,19 +10,29 @@
 #define _LIBCPP___REGEX_INTERPRETER_H
 
 #include <__algorithm/equal.h>
+#include <__algorithm/max.h>
 #include <__algorithm/transform.h>
 #include <__config>
 #include <__iterator/back_insert_iterator.h>
 #include <__locale_dir/ctype_base.h>
+#include <__memory/construct_at.h>
 #include <__memory/uninitialized_algorithms.h>
 #include <__regex/regex_error.h>
 #include <__type_traits/make_signed.h>
+#include <__utility/move.h>
 #include <__utility/pair.h>
 #include <__utility/scope_guard.h>
 #include <__utility/unreachable.h>
 #include <__vector/vector.h>
 #include <string_view>
 
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _CharT>
@@ -1206,4 +1216,6 @@ class __interpreter {
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___REGEX_INTERPRETER_H
diff --git a/libcxx/include/__regex/parser_common.h b/libcxx/include/__regex/parser_common.h
index b47da1eb24987..6635b64724480 100644
--- a/libcxx/include/__regex/parser_common.h
+++ b/libcxx/include/__regex/parser_common.h
@@ -11,8 +11,21 @@
 
 #include <__algorithm/search.h>
 #include <__config>
+#include <__cstddef/size_t.h>
+#include <__iterator/next.h>
+#include <__locale_dir/ctype_base.h>
 #include <__regex/interpreter.h>
 #include <__regex/regex_error.h>
+#include <__utility/move.h>
+#include <limits>
+#include <string>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -550,4 +563,6 @@ bool __parse_dupl_symbol(
 
 _LIBCPP_END_NAMESPACE_STD
 
+_LIBCPP_POP_MACROS
+
 #endif // _LIBCPP___REGEX_BASIC_PARSER_H
diff --git a/libcxx/include/__regex/regex_error.h b/libcxx/include/__regex/regex_error.h
index 35f8cb2ed6147..2dcdfc3780bac 100644
--- a/libcxx/include/__regex/regex_error.h
+++ b/libcxx/include/__regex/regex_error.h
@@ -12,6 +12,10 @@
 #include <__config>
 #include <stdexcept>
 
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 #define _LIBCPP_REGEX_COMPLEXITY_FACTOR 4096
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 4512cc71153ca..ad20f1d2b7ecf 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -1701,7 +1701,7 @@ module std {
     module noexcept_move_assign_container     { header "__memory/noexcept_move_assign_container.h" }
     module out_ptr                            { header "__memory/out_ptr.h" }
     module pointer_traits                     { header "__memory/pointer_traits.h" }
-    module pstl                               { header "__memory/pstl.h" }    
+    module pstl                               { header "__memory/pstl.h" }
     module ranges_construct_at                { header "__memory/ranges_construct_at.h" }
     module ranges_destroy                     { header "__memory/ranges_destroy.h" }
     module ranges_uninitialized_algorithms {
@@ -2055,6 +2055,14 @@ module std {
 
   module regex {
     header "regex"
+
+    module basic_parser    { header "__regex/basic_parser.h" }
+    module ecma_parser     { header "__regex/ecma_parser.h" }
+    module extended_parser { header "__regex/extended_parser.h" }
+    module interpreter     { header "__regex/interpreter.h" }
+    module parser_common   { header "__regex/parser_common.h" }
+    module regex_error     { header "__regex/regex_error.h" }
+
     export *
     export std.iterator.reverse_iterator
   }



More information about the libcxx-commits mailing list