@@ -2720,6 +2720,72 @@ constexpr bool starts_with_anchor(const flags & f, ctll::list<capture_with_name<
27202720
27212721#endif
27222722
2723+ #ifndef CTRE__HAS_IMPLICIT_ANCHOR__HPP
2724+ #define CTRE__HAS_IMPLICIT_ANCHOR__HPP
2725+
2726+ namespace ctre {
2727+
2728+ template<typename... Content>
2729+ constexpr bool has_implicit_anchor(ctll::list<repeat<0, 0, any>, Content...>) noexcept {
2730+ return true;
2731+ }
2732+ template<typename... Content>
2733+ constexpr bool has_implicit_anchor(ctll::list<repeat<1, 0, any>, Content...>) noexcept {
2734+ return true;
2735+ }
2736+
2737+ template<typename... Content>
2738+ constexpr bool has_implicit_anchor(ctll::list<possessive_repeat<0, 0, any>, Content...>) noexcept {
2739+ return true;
2740+ }
2741+
2742+ template<typename... Content>
2743+ constexpr bool has_implicit_anchor(ctll::list<possessive_repeat<1, 0, any>, Content...>) noexcept {
2744+ return true;
2745+ }
2746+
2747+ template<typename... Content>
2748+ constexpr bool has_implicit_anchor(ctll::list<lazy_repeat<0, 0, any>, Content...>) noexcept {
2749+ return true;
2750+ }
2751+
2752+ template<typename... Content>
2753+ constexpr bool has_implicit_anchor(ctll::list<lazy_repeat<1, 0, any>, Content...>) noexcept {
2754+ return true;
2755+ }
2756+
2757+ template<typename... Content, typename... Tail>
2758+ constexpr bool has_implicit_anchor(ctll::list<sequence<Content...>, Tail...>) noexcept {
2759+ return has_implicit_anchor(ctll::list<Content..., Tail...>{});
2760+ }
2761+
2762+ //TODO: we may check captures as implicit anchors*, but they must not be backreferenced because for example "(.+)X\1" will not work properly with "1234X2345"
2763+ /*
2764+ template<size_t Id, typename... Content, typename... Tail>
2765+ constexpr bool has_implicit_anchor(ctll::list<capture<Id, Content...>, Tail...>) noexcept {
2766+ //Id must not be backreferenced
2767+ return !id_backreference(Id) && has_implicit_anchor(ctll::list<Content..., Tail...>{});
2768+ }
2769+
2770+ template<size_t Id, typename Name, typename... Content, typename... Tail>
2771+ constexpr bool has_implicit_anchor(ctll::list<capture_with_name<Id, Name, Content...>, Tail...>) noexcept {
2772+ //Id must not be backreferenced
2773+ return !id_backreference(Id) && has_implicit_anchor(ctll::list<Content..., Tail...>{});
2774+ }
2775+ */
2776+
2777+ template<typename... Opts, typename... Tail>
2778+ constexpr bool has_implicit_anchor(ctll::list<select<Opts...>, Tail...>) noexcept {
2779+ return (has_implicit_anchor(ctll::list<Opts, Tail...>{}) && ...);
2780+ }
2781+
2782+ constexpr bool has_implicit_anchor(...) noexcept {
2783+ return false;
2784+ }
2785+ }
2786+
2787+ #endif
2788+
27232789#ifndef CTRE__RETURN_TYPE__HPP
27242790#define CTRE__RETURN_TYPE__HPP
27252791
@@ -4878,7 +4944,7 @@ struct search_method {
48784944 template <typename Modifier = singleline, typename ResultIterator = void, typename RE, typename IteratorBegin, typename IteratorEnd> constexpr CTRE_FORCE_INLINE static auto exec(IteratorBegin orig_begin, IteratorBegin begin, IteratorEnd end, RE) noexcept {
48794945 using result_iterator = std::conditional_t<std::is_same_v<ResultIterator, void>, IteratorBegin, ResultIterator>;
48804946
4881- constexpr bool fixed = starts_with_anchor(Modifier{}, ctll::list<RE>{});
4947+ constexpr bool fixed = starts_with_anchor(Modifier{}, ctll::list<RE>{}) || has_implicit_anchor(ctll::list<RE>{}) ;
48824948
48834949 auto it = begin;
48844950
0 commit comments