@@ -2264,6 +2264,80 @@ template <auto V, auto... Value, auto... Name, typename... Ts, typename Paramete
22642264#ifndef CTRE__EVALUATION__HPP
22652265#define CTRE__EVALUATION__HPP
22662266
2267+ #ifndef CTRE__STARTS_WITH_ANCHOR__HPP
2268+ #define CTRE__STARTS_WITH_ANCHOR__HPP
2269+
2270+ namespace ctre {
2271+
2272+ template <typename ... Content>
2273+ constexpr bool starts_with_anchor (ctll::list<Content...>) noexcept {
2274+ return false ;
2275+ }
2276+
2277+ template <typename ... Content>
2278+ constexpr bool starts_with_anchor (ctll::list<assert_begin, Content...>) noexcept {
2279+ // yes! start anchor is here
2280+ return true ;
2281+ }
2282+
2283+ template <typename ... Options, typename ... Content>
2284+ constexpr bool starts_with_anchor (ctll::list<select<Options...>, Content...>) noexcept {
2285+ // check if all options starts with anchor or if they are empty, there is an anchor behind them
2286+ return (starts_with_anchor (ctll::list<Options, Content...>{}) && ... && true );
2287+ }
2288+
2289+ template <typename ... Optional, typename ... Content>
2290+ constexpr bool starts_with_anchor (ctll::list<optional<Optional...>, Content...>) noexcept {
2291+ // check if all options starts with anchor or if they are empty, there is an anchor behind them
2292+ return starts_with_anchor (ctll::list<Optional..., Content...>{}) && starts_with_anchor (ctll::list<Content...>{});
2293+ }
2294+
2295+ template <typename ... Optional, typename ... Content>
2296+ constexpr bool starts_with_anchor (ctll::list<lazy_optional<Optional...>, Content...>) noexcept {
2297+ // check if all options starts with anchor or if they are empty, there is an anchor behind them
2298+ return starts_with_anchor (ctll::list<Optional..., Content...>{}) && starts_with_anchor (ctll::list<Content...>{});
2299+ }
2300+
2301+ template <typename ... Seq, typename ... Content>
2302+ constexpr bool starts_with_anchor (ctll::list<sequence<Seq...>, Content...>) noexcept {
2303+ // check if all options starts with anchor or if they are empty, there is an anchor behind them
2304+ return starts_with_anchor (ctll::list<Seq..., Content...>{});
2305+ }
2306+
2307+ template <size_t A, size_t B, typename ... Seq, typename ... Content>
2308+ constexpr bool starts_with_anchor (ctll::list<repeat<A, B, Seq...>, Content...>) noexcept {
2309+ // check if all options starts with anchor or if they are empty, there is an anchor behind them
2310+ return starts_with_anchor (ctll::list<Seq..., Content...>{});
2311+ }
2312+
2313+ template <size_t A, size_t B, typename ... Seq, typename ... Content>
2314+ constexpr bool starts_with_anchor (ctll::list<lazy_repeat<A, B, Seq...>, Content...>) noexcept {
2315+ // check if all options starts with anchor or if they are empty, there is an anchor behind them
2316+ return starts_with_anchor (ctll::list<Seq..., Content...>{});
2317+ }
2318+
2319+ template <size_t A, size_t B, typename ... Seq, typename ... Content>
2320+ constexpr bool starts_with_anchor (ctll::list<possessive_repeat<A, B, Seq...>, Content...>) noexcept {
2321+ // check if all options starts with anchor or if they are empty, there is an anchor behind them
2322+ return starts_with_anchor (ctll::list<Seq..., Content...>{});
2323+ }
2324+
2325+ template <size_t Index, typename ... Seq, typename ... Content>
2326+ constexpr bool starts_with_anchor (ctll::list<capture<Index, Seq...>, Content...>) noexcept {
2327+ // check if all options starts with anchor or if they are empty, there is an anchor behind them
2328+ return starts_with_anchor (ctll::list<Seq..., Content...>{});
2329+ }
2330+
2331+ template <size_t Index, typename ... Seq, typename ... Content>
2332+ constexpr bool starts_with_anchor (ctll::list<capture_with_name<Index, Seq...>, Content...>) noexcept {
2333+ // check if all options starts with anchor or if they are empty, there is an anchor behind them
2334+ return starts_with_anchor (ctll::list<Seq..., Content...>{});
2335+ }
2336+
2337+ }
2338+
2339+ #endif
2340+
22672341#ifndef CTRE__RETURN_TYPE__HPP
22682342#define CTRE__RETURN_TYPE__HPP
22692343
@@ -3239,14 +3313,16 @@ template <typename Iterator, typename EndIterator, typename Pattern>
32393313constexpr inline auto search_re (const Iterator begin, const EndIterator end, Pattern pattern) noexcept {
32403314 using return_type = decltype (regex_results (std::declval<Iterator>(), find_captures (pattern)));
32413315
3316+ [[maybe_unused]] constexpr bool fixed = starts_with_anchor (ctll::list<Pattern>{});
3317+
32423318 auto it = begin;
3243- for (; end != it; ++it) {
3319+ for (; end != it && !fixed ; ++it) {
32443320 if (auto out = evaluate (begin, it, end, return_type{}, ctll::list<start_mark, Pattern, end_mark, accept>())) {
32453321 return out;
32463322 }
32473323 }
32483324
3249- // in case the RE is empty
3325+ // in case the RE is empty or fixed
32503326 return evaluate (begin, it, end, return_type{}, ctll::list<start_mark, Pattern, end_mark, accept>());
32513327}
32523328
0 commit comments