diff --git a/clang-bench.txt b/clang-bench.txt deleted file mode 100644 index 264827a2..00000000 --- a/clang-bench.txt +++ /dev/null @@ -1,20 +0,0 @@ -//--------- ABCD|DEFGH|EFGHI|A{4,} -egrep 0m49.353s -CTRE 0m10.093s -PCRE 0m12.515s -std::regex 21m9.309s -//--------- [0-9a-fA-F]{8,16} -egrep 0m32.256s -CTRE 0m14.197s -PCRE 0m17.832s -std::regex 2m34.505s -//--------- ^([0-9]{4,16})?[aA] -egrep 0m12.880s -CTRE 0m7.596s -PCRE 0m6.590s -std::regex 7m54.793s -//--------- ([aAbB]{4,}|[xXyY]{4,}|[1234]{4,})0 -egrep 1m56.412s -CTRE 0m59.864s -PCRE 0m43.486s -std::regex 27m35.004s diff --git a/include/ctre/evaluation.hpp b/include/ctre/evaluation.hpp index caeefe2f..1776bd5c 100644 --- a/include/ctre/evaluation.hpp +++ b/include/ctre/evaluation.hpp @@ -17,12 +17,14 @@ #endif namespace ctre { + enum match_type { full_match, partial_match }; // calling with pattern prepare stack and triplet of iterators template -constexpr inline auto match_re(const Iterator begin, const EndIterator end, Pattern pattern) noexcept { +constexpr inline auto match_re(const Iterator begin, const EndIterator end, Pattern pattern, + const match_type mtype = full_match) noexcept { using return_type = decltype(regex_results(std::declval(), find_captures(pattern))); - return evaluate(begin, begin, end, return_type{}, ctll::list()); + return evaluate(begin, begin, end, mtype, return_type{}, ctll::list()); } template @@ -31,13 +33,13 @@ constexpr inline auto search_re(const Iterator begin, const EndIterator end, Pat auto it = begin; for (; end != it; ++it) { - if (auto out = evaluate(begin, it, end, return_type{}, ctll::list())) { + if (auto out = evaluate(begin, it, end, full_match, return_type{}, ctll::list())) { return out; } } // in case the RE is empty - return evaluate(begin, it, end, return_type{}, ctll::list()); + return evaluate(begin, it, end, full_match, return_type{}, ctll::list()); } @@ -49,7 +51,8 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator, Iterator, const EndIterat // if we found "accept" object on stack => ACCEPT template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator, Iterator, const EndIterator, R captures, ctll::list) noexcept { +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator, Iterator, const EndIterator, + const match_type, R captures, ctll::list) noexcept { return captures.matched(); } @@ -61,19 +64,22 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator, Iterator, const EndIterat // mark start of outer capture template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list) noexcept { - return evaluate(begin, current, end, captures.set_start_mark(current), ctll::list()); +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, + const match_type mtype, R captures, ctll::list) noexcept { + return evaluate(begin, current, end, mtype, captures.set_start_mark(current), ctll::list()); } // mark end of outer capture template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list) noexcept { - return evaluate(begin, current, end, captures.set_end_mark(current), ctll::list()); +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, + const match_type mtype, R captures, ctll::list) noexcept { + return evaluate(begin, current, end, mtype, captures.set_end_mark(current), ctll::list()); } // mark end of cycle template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator, Iterator current, const EndIterator, R captures, ctll::list) noexcept { +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator, Iterator current, const EndIterator, + const match_type, R captures, ctll::list) noexcept { return captures.set_end_mark(current).matched(); } @@ -81,10 +87,19 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator, Iterator current, const E // matching everything which behave as a one character matcher template ::template value())>)>> -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list) noexcept { - if (end == current) return not_matched; +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, + const match_type mtype, R captures, ctll::list) noexcept { + if (end == current) + { + if (mtype == partial_match) + { + return captures.set_end_mark(current).matched(); + } + else + return not_matched; + } if (!CharacterLike::match_char(*current)) return not_matched; - return evaluate(begin, current+1, end, captures, ctll::list()); + return evaluate(begin, current+1, end, mtype, captures, ctll::list()); } // matching strings in patterns @@ -107,11 +122,12 @@ template co } template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list, Tail...>) noexcept { +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, + const match_type mtype, R captures, ctll::list, Tail...>) noexcept { if constexpr (sizeof...(String) == 0) { - return evaluate(begin, current, end, captures, ctll::list()); + return evaluate(begin, current, end, mtype, captures, ctll::list()); } else if (auto tmp = evaluate_match_string(current, end); tmp.match) { - return evaluate(begin, tmp.current, end, captures, ctll::list()); + return evaluate(begin, tmp.current, end, mtype, captures, ctll::list()); } else { return not_matched; } @@ -119,26 +135,29 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c // matching select in patterns template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list, Tail...>) noexcept { - if (auto r = evaluate(begin, current, end, captures, ctll::list())) { +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, + const match_type mtype, R captures, ctll::list, Tail...>) noexcept { + if (auto r = evaluate(begin, current, end, mtype, captures, ctll::list())) { return r; } else { - return evaluate(begin, current, end, captures, ctll::list, Tail...>()); + return evaluate(begin, current, end, mtype, captures, ctll::list, Tail...>()); } } template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator, Iterator, const EndIterator, R, ctll::list, Tail...>) noexcept { +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator, Iterator, const EndIterator, + const match_type, R, ctll::list, Tail...>) noexcept { // no previous option was matched => REJECT return not_matched; } // matching optional in patterns template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list, Tail...>) noexcept { - if (auto r1 = evaluate(begin, current, end, captures, ctll::list, Tail...>())) { +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, + const match_type mtype, R captures, ctll::list, Tail...>) noexcept { + if (auto r1 = evaluate(begin, current, end, mtype, captures, ctll::list, Tail...>())) { return r1; - } else if (auto r2 = evaluate(begin, current, end, captures, ctll::list())) { + } else if (auto r2 = evaluate(begin, current, end, mtype, captures, ctll::list())) { return r2; } else { return not_matched; @@ -147,10 +166,11 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c // lazy optional template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list, Tail...>) noexcept { - if (auto r1 = evaluate(begin, current, end, captures, ctll::list())) { +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, + const match_type mtype, R captures, ctll::list, Tail...>) noexcept { + if (auto r1 = evaluate(begin, current, end, mtype, captures, ctll::list())) { return r1; - } else if (auto r2 = evaluate(begin, current, end, captures, ctll::list, Tail...>())) { + } else if (auto r2 = evaluate(begin, current, end, mtype, captures, ctll::list, Tail...>())) { return r2; } else { return not_matched; @@ -159,44 +179,50 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c // matching sequence in patterns template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list, Tail...>) noexcept { +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, + const match_type mtype, R captures, ctll::list, Tail...>) noexcept { if constexpr (sizeof...(TailContent) > 0) { - return evaluate(begin, current, end, captures, ctll::list, Tail...>()); + return evaluate(begin, current, end, mtype, captures, ctll::list, Tail...>()); } else { - return evaluate(begin, current, end, captures, ctll::list()); + return evaluate(begin, current, end, mtype, captures, ctll::list()); } } // matching empty in patterns template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list) noexcept { - return evaluate(begin, current, end, captures, ctll::list()); +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, + const match_type mtype, R captures, ctll::list) noexcept { + return evaluate(begin, current, end, mtype, captures, ctll::list()); } // matching asserts template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list) noexcept { +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, + const match_type mtype, R captures, ctll::list) noexcept { if (begin != current) { return not_matched; } - return evaluate(begin, current, end, captures, ctll::list()); + return evaluate(begin, current, end, mtype, captures, ctll::list()); } template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list) noexcept { +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, + const match_type mtype, R captures, ctll::list) noexcept { if (end != current) { return not_matched; } - return evaluate(begin, current, end, captures, ctll::list()); + return evaluate(begin, current, end, mtype, captures, ctll::list()); } // lazy repeat template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list, Tail...>) noexcept { +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, + const match_type mtype, R captures, ctll::list, Tail...>) noexcept { // A..B size_t i{0}; for (; i < A && (A != 0); ++i) { - if (auto outer_result = evaluate(begin, current, end, captures, ctll::list, end_cycle_mark>())) { + if (auto outer_result = evaluate(begin, current, end, mtype, captures, + ctll::list, end_cycle_mark>())) { captures = outer_result.unmatch(); current = outer_result.get_end_position(); } else { @@ -204,12 +230,12 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c } } - if (auto outer_result = evaluate(begin, current, end, captures, ctll::list())) { + if (auto outer_result = evaluate(begin, current, end, mtype, captures, ctll::list())) { return outer_result; } else { for (; (i < B) || (B == 0); ++i) { - if (auto inner_result = evaluate(begin, current, end, captures, ctll::list, end_cycle_mark>())) { - if (auto outer_result = evaluate(begin, inner_result.get_end_position(), end, inner_result.unmatch(), ctll::list())) { + if (auto inner_result = evaluate(begin, current, end, mtype, captures, ctll::list, end_cycle_mark>())) { + if (auto outer_result = evaluate(begin, inner_result.get_end_position(), end, mtype, inner_result.unmatch(), ctll::list())) { return outer_result; } else { captures = inner_result.unmatch(); @@ -220,26 +246,27 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c return not_matched; } } - return evaluate(begin, current, end, captures, ctll::list()); + return evaluate(begin, current, end, mtype, captures, ctll::list()); } } // possessive repeat template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list, Tail...>) noexcept { +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, + const match_type mtype, R captures, ctll::list, Tail...>) noexcept { for (size_t i{0}; (i < B) || (B == 0); ++i) { // try as many of inner as possible and then try outer once - if (auto inner_result = evaluate(begin, current, end, captures, ctll::list, end_cycle_mark>())) { + if (auto inner_result = evaluate(begin, current, end, mtype, captures, ctll::list, end_cycle_mark>())) { captures = inner_result.unmatch(); current = inner_result.get_end_position(); } else { if (i < A && (A != 0)) return not_matched; - else return evaluate(begin, current, end, captures, ctll::list()); + else return evaluate(begin, current, end, mtype, captures, ctll::list()); } } - return evaluate(begin, current, end, captures, ctll::list()); + return evaluate(begin, current, end, mtype, captures, ctll::list()); } // (gready) repeat @@ -247,18 +274,22 @@ template , Tail...> stack) { #else -constexpr inline R evaluate_recursive(size_t i, const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list, Tail...> stack) { +constexpr inline R evaluate_recursive(size_t i, const Iterator begin, Iterator current, const EndIterator end, const match_type mtype, R captures, ctll::list, Tail...> stack) { #endif if ((B == 0) || (i < B)) { // a*ab // aab - - if (auto inner_result = evaluate(begin, current, end, captures, ctll::list, end_cycle_mark>())) { + + if (auto inner_result = evaluate(begin, current, end, mtype, captures, ctll::list, end_cycle_mark>())) { // TODO MSVC issue: // if I uncomment this return it will not fail in constexpr (but the matching result will not be correct) - // return inner_result + if (mtype == partial_match && end == inner_result.get_end_position()) + return inner_result; // I tried to add all constructors to R but without any success + if (auto rec_result = evaluate_recursive(i+1, begin, inner_result.get_end_position(), end, + mtype, inner_result.unmatch(), stack)) { + #ifdef CTRE_MSVC_GREEDY_WORKAROUND evaluate_recursive(result, i+1, begin, inner_result.get_end_position(), end, inner_result.unmatch(), stack); if (result) { @@ -271,6 +302,7 @@ constexpr inline R evaluate_recursive(size_t i, const Iterator begin, Iterator c #endif } } + #ifdef CTRE_MSVC_GREEDY_WORKAROUND result = evaluate(begin, current, end, captures, ctll::list()); #else @@ -278,20 +310,21 @@ constexpr inline R evaluate_recursive(size_t i, const Iterator begin, Iterator c #endif } - // (gready) repeat optimization // basic one, if you are at the end of RE, just change it into possessive // TODO do the same if there is no collision with rest of the RE template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list,assert_end, Tail...>) { - return evaluate(begin, current, end, captures, ctll::list, assert_end, Tail...>()); +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, + match_type mtype, R captures, ctll::list,assert_end, Tail...>) { + return evaluate(begin, current, end, mtype, captures, ctll::list, assert_end, Tail...>()); } template struct identify_type; // (greedy) repeat template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, [[maybe_unused]] ctll::list, Tail...> stack) { +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, + const match_type mtype, R captures, [[maybe_unused]] ctll::list, Tail...> stack) { // check if it can be optimized #ifndef CTRE_DISABLE_GREEDY_OPT if constexpr (collides(calculate_first(Content{}...), calculate_first(Tail{}...))) { @@ -299,13 +332,14 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c // A..B size_t i{0}; for (; i < A && (A != 0); ++i) { - if (auto inner_result = evaluate(begin, current, end, captures, ctll::list, end_cycle_mark>())) { + if (auto inner_result = evaluate(begin, current, end, mtype, captures, ctll::list, end_cycle_mark>())) { captures = inner_result.unmatch(); current = inner_result.get_end_position(); } else { return not_matched; } } + #ifdef CTRE_MSVC_GREEDY_WORKAROUND R result; evaluate_recursive(result, i, begin, current, end, captures, stack); @@ -313,10 +347,11 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c #else return evaluate_recursive(i, begin, current, end, captures, stack); #endif + #ifndef CTRE_DISABLE_GREEDY_OPT } else { // if there is no collision we can go possessive - return evaluate(begin, current, end, captures, ctll::list, Tail...>()); + return evaluate(begin, current, end, mtype, captures, ctll::list, Tail...>()); } #endif @@ -324,58 +359,67 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c // repeat lazy_star template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list, Tail...>) noexcept { - return evaluate(begin, current, end, captures, ctll::list, Tail...>()); +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, + const match_type mtype, R captures, ctll::list, Tail...>) noexcept { + return evaluate(begin, current, end, mtype, captures, ctll::list, Tail...>()); } // repeat (lazy_plus) template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list, Tail...>) noexcept { - return evaluate(begin, current, end, captures, ctll::list, Tail...>()); +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, + const match_type mtype, R captures, ctll::list, Tail...>) noexcept { + return evaluate(begin, current, end, mtype, captures, ctll::list, Tail...>()); } // repeat (possessive_star) template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list, Tail...>) noexcept { - return evaluate(begin, current, end, captures, ctll::list, Tail...>()); +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, + const match_type mtype, R captures, ctll::list, Tail...>) noexcept { + return evaluate(begin, current, end, mtype, captures, ctll::list, Tail...>()); } // repeat (possessive_plus) template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list, Tail...>) noexcept { - return evaluate(begin, current, end, captures, ctll::list, Tail...>()); +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, + const match_type mtype, R captures, ctll::list, Tail...>) noexcept { + return evaluate(begin, current, end, mtype, captures, ctll::list, Tail...>()); } // repeat (greedy) star template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list, Tail...>) noexcept { - return evaluate(begin, current, end, captures, ctll::list, Tail...>()); +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, + const match_type mtype, R captures, ctll::list, Tail...>) noexcept { + return evaluate(begin, current, end, mtype, captures, ctll::list, Tail...>()); } // repeat (greedy) plus template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list, Tail...>) noexcept { - return evaluate(begin, current, end, captures, ctll::list, Tail...>()); +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, + const match_type mtype, R captures, ctll::list, Tail...>) noexcept { + return evaluate(begin, current, end, mtype, captures, ctll::list, Tail...>()); } // capture (numeric ID) template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list, Tail...>) noexcept { - return evaluate(begin, current, end, captures.template start_capture(current), ctll::list, numeric_mark, Tail...>()); +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, + const match_type mtype, R captures, ctll::list, Tail...>) noexcept { + return evaluate(begin, current, end, mtype, captures.template start_capture(current), ctll::list, numeric_mark, Tail...>()); } // capture end mark (numeric and string ID) template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list, Tail...>) noexcept { - return evaluate(begin, current, end, captures.template end_capture(current), ctll::list()); +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, + const match_type mtype, R captures, ctll::list, Tail...>) noexcept { + return evaluate(begin, current, end, mtype, captures.template end_capture(current), ctll::list()); } // capture (string ID) template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list, Tail...>) noexcept { - return evaluate(begin, current, end, captures.template start_capture(current), ctll::list, numeric_mark, Tail...>()); +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, + const match_type mtype, R captures, ctll::list, Tail...>) noexcept { + return evaluate(begin, current, end, mtype, captures.template start_capture(current), ctll::list, numeric_mark, Tail...>()); } // backreference support (match agains content of iterators) @@ -393,11 +437,12 @@ template constexpr CTRE_FORCE_INLINE s // backreference with name template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list, Tail...>) noexcept { +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, + const match_type mtype, R captures, ctll::list, Tail...>) noexcept { if (const auto ref = captures.template get()) { if (auto tmp = match_against_range(current, end, ref.begin(), ref.end()); tmp.match) { - return evaluate(begin, tmp.current, end, captures, ctll::list()); + return evaluate(begin, tmp.current, end, mtype, captures, ctll::list()); } } return not_matched; @@ -405,11 +450,12 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c // backreference template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list, Tail...>) noexcept { +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, + const match_type mtype, R captures, ctll::list, Tail...>) noexcept { if (const auto ref = captures.template get()) { if (auto tmp = match_against_range(current, end, ref.begin(), ref.end()); tmp.match) { - return evaluate(begin, tmp.current, end, captures, ctll::list()); + return evaluate(begin, tmp.current, end, mtype, captures, ctll::list()); } } return not_matched; @@ -417,17 +463,17 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c // end of lookahead template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator, Iterator, const EndIterator, R captures, ctll::list) noexcept { +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator, Iterator, const EndIterator, const match_type, R captures, ctll::list) noexcept { return captures.matched(); } // lookahead positive template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list, Tail...>) noexcept { +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, const match_type mtype, R captures, ctll::list, Tail...>) noexcept { - if (auto lookahead_result = evaluate(begin, current, end, captures, ctll::list, end_lookahead_mark>())) { + if (auto lookahead_result = evaluate(begin, current, end, mtype, captures, ctll::list, end_lookahead_mark>())) { captures = lookahead_result.unmatch(); - return evaluate(begin, current, end, captures, ctll::list()); + return evaluate(begin, current, end, mtype, captures, ctll::list()); } else { return not_matched; } @@ -435,12 +481,12 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c // lookahead negative template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list, Tail...>) noexcept { +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, const match_type mtype, R captures, ctll::list, Tail...>) noexcept { - if (auto lookahead_result = evaluate(begin, current, end, captures, ctll::list, end_lookahead_mark>())) { + if (auto lookahead_result = evaluate(begin, current, end, mtype, captures, ctll::list, end_lookahead_mark>())) { return not_matched; } else { - return evaluate(begin, current, end, captures, ctll::list()); + return evaluate(begin, current, end, mtype, captures, ctll::list()); } } diff --git a/include/ctre/wrapper.hpp b/include/ctre/wrapper.hpp index 3c0ecaff..ace4645d 100644 --- a/include/ctre/wrapper.hpp +++ b/include/ctre/wrapper.hpp @@ -32,40 +32,42 @@ template class RangeLikeType { }; template struct regular_expression { - template constexpr CTRE_FORCE_INLINE static auto match_2(IteratorBegin begin, IteratorEnd end) noexcept { - return match_re(begin, end, RE()); + template + constexpr CTRE_FORCE_INLINE static auto match_2(IteratorBegin begin, IteratorEnd end, const match_type mtype) noexcept { + return match_re(begin, end, RE(), mtype); } template constexpr CTRE_FORCE_INLINE static auto search_2(IteratorBegin begin, IteratorEnd end) noexcept { return search_re(begin, end, RE()); } constexpr CTRE_FORCE_INLINE regular_expression() noexcept { }; constexpr CTRE_FORCE_INLINE regular_expression(RE) noexcept { }; - template constexpr CTRE_FORCE_INLINE static auto match(Iterator begin, Iterator end) noexcept { - return match_re(begin, end, RE()); + template constexpr CTRE_FORCE_INLINE static auto match(Iterator begin, Iterator end, + match_type mtype = full_match) noexcept { + return match_re(begin, end, RE(), mtype); } - static constexpr CTRE_FORCE_INLINE auto match(const char * s) noexcept { - return match_2(s, zero_terminated_string_end_iterator()); + static constexpr CTRE_FORCE_INLINE auto match(const char * s, const match_type mtype = full_match) noexcept { + return match_2(s, zero_terminated_string_end_iterator(), mtype); } - static constexpr CTRE_FORCE_INLINE auto match(const wchar_t * s) noexcept { - return match_2(s, zero_terminated_string_end_iterator()); + static constexpr CTRE_FORCE_INLINE auto match(const wchar_t * s, const match_type mtype = full_match) noexcept { + return match_2(s, zero_terminated_string_end_iterator(), mtype); } - static constexpr CTRE_FORCE_INLINE auto match(const std::string & s) noexcept { - return match_2(s.c_str(), zero_terminated_string_end_iterator()); + static constexpr CTRE_FORCE_INLINE auto match(const std::string & s, const match_type mtype = full_match) noexcept { + return match_2(s.c_str(), zero_terminated_string_end_iterator(), mtype); } - static constexpr CTRE_FORCE_INLINE auto match(const std::wstring & s) noexcept { - return match_2(s.c_str(), zero_terminated_string_end_iterator()); + static constexpr CTRE_FORCE_INLINE auto match(const std::wstring & s, const match_type mtype = full_match) noexcept { + return match_2(s.c_str(), zero_terminated_string_end_iterator(), mtype); } - static constexpr CTRE_FORCE_INLINE auto match(std::string_view sv) noexcept { - return match(sv.begin(), sv.end()); + static constexpr CTRE_FORCE_INLINE auto match(std::string_view sv, const match_type mtype = full_match) noexcept { + return match(sv.begin(), sv.end(), mtype); } - static constexpr CTRE_FORCE_INLINE auto match(std::wstring_view sv) noexcept { - return match(sv.begin(), sv.end()); + static constexpr CTRE_FORCE_INLINE auto match(std::wstring_view sv, const match_type mtype = full_match) noexcept { + return match(sv.begin(), sv.end(), mtype); } - static constexpr CTRE_FORCE_INLINE auto match(std::u16string_view sv) noexcept { - return match(sv.begin(), sv.end()); + static constexpr CTRE_FORCE_INLINE auto match(std::u16string_view sv, const match_type mtype = full_match) noexcept { + return match(sv.begin(), sv.end(), mtype); } - static constexpr CTRE_FORCE_INLINE auto match(std::u32string_view sv) noexcept { - return match(sv.begin(), sv.end()); + static constexpr CTRE_FORCE_INLINE auto match(std::u32string_view sv, const match_type mtype = full_match) noexcept { + return match(sv.begin(), sv.end(), mtype); } template ::value>::type> static constexpr CTRE_FORCE_INLINE auto match(Range && range) noexcept { return match(std::begin(range), std::end(range)); diff --git a/tests/partial_match.cpp b/tests/partial_match.cpp new file mode 100644 index 00000000..b82de09a --- /dev/null +++ b/tests/partial_match.cpp @@ -0,0 +1,13 @@ +#include +#include + +static constexpr inline auto pattern = +ctll::basic_fixed_string{ "[-+]?([0-9]{1,19}([.][0-9]{0,2})?|[.][0-9]{1,2})" }; + +static_assert(ctre::re().match("-", ctre::partial_match)); +static_assert(ctre::re().match(".", ctre::partial_match)); +static_assert(!ctre::re().match("a", ctre::partial_match)); +static_assert(ctre::re().match("-1", ctre::partial_match)); +static_assert(ctre::re().match(".12", ctre::partial_match)); +static_assert(ctre::re().match("+12.34", ctre::partial_match)); +static_assert(!ctre::re().match("12.34duh", ctre::partial_match));