@@ -2264,6 +2264,80 @@ template <auto V, auto... Value, auto... Name, typename... Ts, typename Paramete
2264
2264
#ifndef CTRE__EVALUATION__HPP
2265
2265
#define CTRE__EVALUATION__HPP
2266
2266
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
+
2267
2341
#ifndef CTRE__RETURN_TYPE__HPP
2268
2342
#define CTRE__RETURN_TYPE__HPP
2269
2343
@@ -3239,14 +3313,16 @@ template <typename Iterator, typename EndIterator, typename Pattern>
3239
3313
constexpr inline auto search_re (const Iterator begin, const EndIterator end, Pattern pattern) noexcept {
3240
3314
using return_type = decltype (regex_results (std::declval<Iterator>(), find_captures (pattern)));
3241
3315
3316
+ [[maybe_unused]] constexpr bool fixed = starts_with_anchor (ctll::list<Pattern>{});
3317
+
3242
3318
auto it = begin;
3243
- for (; end != it; ++it) {
3319
+ for (; end != it && !fixed ; ++it) {
3244
3320
if (auto out = evaluate (begin, it, end, return_type{}, ctll::list<start_mark, Pattern, end_mark, accept>())) {
3245
3321
return out;
3246
3322
}
3247
3323
}
3248
3324
3249
- // in case the RE is empty
3325
+ // in case the RE is empty or fixed
3250
3326
return evaluate (begin, it, end, return_type{}, ctll::list<start_mark, Pattern, end_mark, accept>());
3251
3327
}
3252
3328
0 commit comments