mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 19:22:45 +00:00 
			
		
		
		
	LibRegex: Add RegexStringView wrapper to support utf8 and utf32 views
This commit is contained in:
		
							parent
							
								
									12dd40a2a5
								
							
						
					
					
						commit
						4a630d4b63
					
				
					 11 changed files with 596 additions and 304 deletions
				
			
		|  | @ -79,7 +79,7 @@ int regcomp(regex_t* reg, const char* pattern, int cflags) | ||||||
|     preg->cflags = cflags; |     preg->cflags = cflags; | ||||||
| 
 | 
 | ||||||
|     String pattern_str(pattern); |     String pattern_str(pattern); | ||||||
|     preg->re = make<Regex<PosixExtended>>(pattern_str, PosixOptions {} | (PosixFlags)cflags); |     preg->re = make<Regex<PosixExtended>>(pattern_str, PosixOptions {} | (PosixFlags)cflags | PosixFlags::SkipTrimEmptyMatches); | ||||||
| 
 | 
 | ||||||
|     auto parser_result = preg->re->parser_result; |     auto parser_result = preg->re->parser_result; | ||||||
|     if (parser_result.error != regex::Error::NoError) { |     if (parser_result.error != regex::Error::NoError) { | ||||||
|  | @ -109,9 +109,9 @@ int regexec(const regex_t* reg, const char* string, size_t nmatch, regmatch_t pm | ||||||
| 
 | 
 | ||||||
|     RegexResult result; |     RegexResult result; | ||||||
|     if (eflags & REG_SEARCH) |     if (eflags & REG_SEARCH) | ||||||
|         result = preg->re->search({ string }, PosixOptions {} | (PosixFlags)eflags); |         result = preg->re->search(string, PosixOptions {} | (PosixFlags)eflags); | ||||||
|     else |     else | ||||||
|         result = preg->re->match({ string }, PosixOptions {} | (PosixFlags)eflags); |         result = preg->re->match(string, PosixOptions {} | (PosixFlags)eflags); | ||||||
| 
 | 
 | ||||||
|     if (result.success) { |     if (result.success) { | ||||||
|         auto size = result.matches.size(); |         auto size = result.matches.size(); | ||||||
|  |  | ||||||
|  | @ -47,8 +47,10 @@ class OpCode_SaveLeftNamedCaptureGroup; | ||||||
| class OpCode_SaveNamedLeftCaptureGroup; | class OpCode_SaveNamedLeftCaptureGroup; | ||||||
| class OpCode_SaveRightNamedCaptureGroup; | class OpCode_SaveRightNamedCaptureGroup; | ||||||
| class OpCode_Compare; | class OpCode_Compare; | ||||||
|  | class RegexStringView; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| using regex::Error; | using regex::Error; | ||||||
| using regex::Lexer; | using regex::Lexer; | ||||||
| using regex::PosixExtendedParser; | using regex::PosixExtendedParser; | ||||||
|  | using regex::RegexStringView; | ||||||
|  |  | ||||||
|  | @ -346,7 +346,7 @@ ALWAYS_INLINE ExecutionResult OpCode_Compare::execute(const MatchInput& input, M | ||||||
|                 return ExecutionResult::Failed_ExecuteLowPrioForks; |                 return ExecutionResult::Failed_ExecuteLowPrioForks; | ||||||
| 
 | 
 | ||||||
|             auto character_class = (CharClass)m_bytecode->at(offset++); |             auto character_class = (CharClass)m_bytecode->at(offset++); | ||||||
|             auto& ch = input.view[state.string_position]; |             auto ch = input.view[state.string_position]; | ||||||
| 
 | 
 | ||||||
|             compare_character_class(input, state, character_class, ch, inverse, inverse_matched); |             compare_character_class(input, state, character_class, ch, inverse, inverse_matched); | ||||||
| 
 | 
 | ||||||
|  | @ -375,10 +375,9 @@ ALWAYS_INLINE ExecutionResult OpCode_Compare::execute(const MatchInput& input, M | ||||||
|     return ExecutionResult::Continue; |     return ExecutionResult::Continue; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ALWAYS_INLINE void OpCode_Compare::compare_char(const MatchInput& input, MatchState& state, char& ch, bool inverse, bool& inverse_matched) const | ALWAYS_INLINE void OpCode_Compare::compare_char(const MatchInput& input, MatchState& state, u32 ch1, bool inverse, bool& inverse_matched) | ||||||
| { | { | ||||||
|     auto ch1 = ch; |     u32 ch2 = input.view[state.string_position]; | ||||||
|     auto ch2 = input.view[state.string_position]; |  | ||||||
| 
 | 
 | ||||||
|     if (input.regex_options & AllFlags::Insensitive) { |     if (input.regex_options & AllFlags::Insensitive) { | ||||||
|         ch1 = tolower(ch1); |         ch1 = tolower(ch1); | ||||||
|  | @ -393,10 +392,12 @@ ALWAYS_INLINE void OpCode_Compare::compare_char(const MatchInput& input, MatchSt | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ALWAYS_INLINE bool OpCode_Compare::compare_string(const MatchInput& input, MatchState& state, const char* str, size_t length) const | ALWAYS_INLINE bool OpCode_Compare::compare_string(const MatchInput& input, MatchState& state, const char* str, size_t length) | ||||||
| { | { | ||||||
|  |     if (input.view.is_u8_view()) { | ||||||
|         auto str_view1 = StringView(str, length); |         auto str_view1 = StringView(str, length); | ||||||
|     auto str_view2 = StringView(&input.view[state.string_position], length); |         auto str_view2 = StringView(&input.view.u8view()[state.string_position], length); | ||||||
|  | 
 | ||||||
|         String str1, str2; |         String str1, str2; | ||||||
|         if (input.regex_options & AllFlags::Insensitive) { |         if (input.regex_options & AllFlags::Insensitive) { | ||||||
|             str1 = str_view1.to_string().to_lowercase(); |             str1 = str_view1.to_string().to_lowercase(); | ||||||
|  | @ -408,11 +409,13 @@ ALWAYS_INLINE bool OpCode_Compare::compare_string(const MatchInput& input, Match | ||||||
|         if (str_view1 == str_view2) { |         if (str_view1 == str_view2) { | ||||||
|             state.string_position += length; |             state.string_position += length; | ||||||
|             return true; |             return true; | ||||||
|     } else |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     return false; |     return false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ALWAYS_INLINE void OpCode_Compare::compare_character_class(const MatchInput& input, MatchState& state, CharClass character_class, char ch, bool inverse, bool& inverse_matched) const | ALWAYS_INLINE void OpCode_Compare::compare_character_class(const MatchInput& input, MatchState& state, CharClass character_class, char ch, bool inverse, bool& inverse_matched) | ||||||
| { | { | ||||||
|     switch (character_class) { |     switch (character_class) { | ||||||
|     case CharClass::Alnum: |     case CharClass::Alnum: | ||||||
|  | @ -510,7 +513,7 @@ ALWAYS_INLINE void OpCode_Compare::compare_character_class(const MatchInput& inp | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ALWAYS_INLINE void OpCode_Compare::compare_character_range(const MatchInput& input, MatchState& state, char from, char to, char ch, bool inverse, bool& inverse_matched) const | ALWAYS_INLINE void OpCode_Compare::compare_character_range(const MatchInput& input, MatchState& state, char from, char to, char ch, bool inverse, bool& inverse_matched) | ||||||
| { | { | ||||||
|     if (input.regex_options & AllFlags::Insensitive) { |     if (input.regex_options & AllFlags::Insensitive) { | ||||||
|         from = tolower(from); |         from = tolower(from); | ||||||
|  | @ -536,9 +539,7 @@ const Vector<String> OpCode_Compare::variable_arguments_to_string(Optional<Match | ||||||
|     Vector<String> result; |     Vector<String> result; | ||||||
| 
 | 
 | ||||||
|     size_t offset { state().instruction_position + 3 }; |     size_t offset { state().instruction_position + 3 }; | ||||||
|     StringView view; |     RegexStringView view = ((input.has_value()) ? input.value().view : nullptr); | ||||||
|     if (input.has_value()) |  | ||||||
|         view = input.value().view; |  | ||||||
| 
 | 
 | ||||||
|     for (size_t i = 0; i < arguments_count(); ++i) { |     for (size_t i = 0; i < arguments_count(); ++i) { | ||||||
|         auto compare_type = (CharacterCompareType)m_bytecode->at(offset++); |         auto compare_type = (CharacterCompareType)m_bytecode->at(offset++); | ||||||
|  | @ -548,23 +549,23 @@ const Vector<String> OpCode_Compare::variable_arguments_to_string(Optional<Match | ||||||
|             char ch = m_bytecode->at(offset++); |             char ch = m_bytecode->at(offset++); | ||||||
|             result.empend(String::format("value='%c'", ch)); |             result.empend(String::format("value='%c'", ch)); | ||||||
|             if (!view.is_null()) |             if (!view.is_null()) | ||||||
|                 result.empend(String::format("compare against: '%s'", String { view.substring_view(state().string_position, state().string_position + 1 > view.length() ? 0 : 1) }.characters())); |                 result.empend(String::format("compare against: '%s'", view.substring_view(state().string_position, state().string_position + 1 > view.length() ? 0 : 1).to_string().characters())); | ||||||
|         } else if (compare_type == CharacterCompareType::String) { |         } else if (compare_type == CharacterCompareType::String) { | ||||||
|             char* str = reinterpret_cast<char*>(m_bytecode->at(offset++)); |             char* str = reinterpret_cast<char*>(m_bytecode->at(offset++)); | ||||||
|             auto& length = m_bytecode->at(offset++); |             auto& length = m_bytecode->at(offset++); | ||||||
|             result.empend(String::format("value=\"%s\"", String { str, length }.characters())); |             result.empend(String::format("value=\"%s\"", String { str, length }.characters())); | ||||||
|             if (!view.is_null()) |             if (!view.is_null()) | ||||||
|                 result.empend(String::format("compare against: \"%s\"", String { input.value().view.substring_view(state().string_position, state().string_position + length > view.length() ? 0 : length) }.characters())); |                 result.empend(String::format("compare against: \"%s\"", input.value().view.substring_view(state().string_position, state().string_position + length > view.length() ? 0 : length).to_string().characters())); | ||||||
|         } else if (compare_type == CharacterCompareType::CharClass) { |         } else if (compare_type == CharacterCompareType::CharClass) { | ||||||
|             auto character_class = (CharClass)m_bytecode->at(offset++); |             auto character_class = (CharClass)m_bytecode->at(offset++); | ||||||
|             result.empend(String::format("ch_class=%lu [%s]", (size_t)character_class, character_class_name(character_class))); |             result.empend(String::format("ch_class=%lu [%s]", (size_t)character_class, character_class_name(character_class))); | ||||||
|             if (!view.is_null()) |             if (!view.is_null()) | ||||||
|                 result.empend(String::format("compare against: '%s'", String { input.value().view.substring_view(state().string_position, state().string_position + 1 > view.length() ? 0 : 1) }.characters())); |                 result.empend(String::format("compare against: '%s'", input.value().view.substring_view(state().string_position, state().string_position + 1 > view.length() ? 0 : 1).to_string().characters())); | ||||||
|         } else if (compare_type == CharacterCompareType::CharRange) { |         } else if (compare_type == CharacterCompareType::CharRange) { | ||||||
|             auto value = (CharRange)m_bytecode->at(offset++); |             auto value = (CharRange)m_bytecode->at(offset++); | ||||||
|             result.empend(String::format("ch_range='%c'-'%c'", value.from, value.to)); |             result.empend(String::format("ch_range='%c'-'%c'", value.from, value.to)); | ||||||
|             if (!view.is_null()) |             if (!view.is_null()) | ||||||
|                 result.empend(String::format("compare against: '%s'", String { input.value().view.substring_view(state().string_position, state().string_position + 1 > view.length() ? 0 : 1) }.characters())); |                 result.empend(String::format("compare against: '%s'",  input.value().view.substring_view(state().string_position, state().string_position + 1 > view.length() ? 0 : 1).to_string().characters())); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     return result; |     return result; | ||||||
|  |  | ||||||
|  | @ -407,7 +407,6 @@ protected: | ||||||
|     Optional<MatchState*> m_state; |     Optional<MatchState*> m_state; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| class OpCode_Exit final : public OpCode { | class OpCode_Exit final : public OpCode { | ||||||
| public: | public: | ||||||
|     OpCode_Exit(ByteCode& bytecode) |     OpCode_Exit(ByteCode& bytecode) | ||||||
|  | @ -567,10 +566,10 @@ public: | ||||||
|     const Vector<String> variable_arguments_to_string(Optional<MatchInput> input = {}) const; |     const Vector<String> variable_arguments_to_string(Optional<MatchInput> input = {}) const; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     ALWAYS_INLINE void compare_char(const MatchInput& input, MatchState& state, char& ch, bool inverse, bool& inverse_matched) const; |     ALWAYS_INLINE static void compare_char(const MatchInput& input, MatchState& state, u32 ch1, bool inverse, bool& inverse_matched); | ||||||
|     ALWAYS_INLINE bool compare_string(const MatchInput& input, MatchState& state, const char* str, size_t length) const; |     ALWAYS_INLINE static bool compare_string(const MatchInput& input, MatchState& state, const char* str, size_t length); | ||||||
|     ALWAYS_INLINE void compare_character_class(const MatchInput& input, MatchState& state, CharClass character_class, char ch, bool inverse, bool& inverse_matched) const; |     ALWAYS_INLINE static void compare_character_class(const MatchInput& input, MatchState& state, CharClass character_class, char ch, bool inverse, bool& inverse_matched); | ||||||
|     ALWAYS_INLINE void compare_character_range(const MatchInput& input, MatchState& state, char from, char to, char ch, bool inverse, bool& inverse_matched) const; |     ALWAYS_INLINE static void compare_character_range(const MatchInput& input, MatchState& state, char from, char to, char ch, bool inverse, bool& inverse_matched); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<typename T> | template<typename T> | ||||||
|  |  | ||||||
|  | @ -31,11 +31,196 @@ | ||||||
| #include "AK/FlyString.h" | #include "AK/FlyString.h" | ||||||
| #include "AK/HashMap.h" | #include "AK/HashMap.h" | ||||||
| #include "AK/String.h" | #include "AK/String.h" | ||||||
|  | #include "AK/StringBuilder.h" | ||||||
| #include "AK/StringView.h" | #include "AK/StringView.h" | ||||||
|  | #include "AK/Utf32View.h" | ||||||
| #include "AK/Vector.h" | #include "AK/Vector.h" | ||||||
| 
 | 
 | ||||||
| namespace regex { | namespace regex { | ||||||
| 
 | 
 | ||||||
|  | class RegexStringView { | ||||||
|  | public: | ||||||
|  |     RegexStringView(const char* chars) | ||||||
|  |         : m_u8view(chars) | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     RegexStringView(const String& string) | ||||||
|  |         : m_u8view(string) | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     RegexStringView(const StringView view) | ||||||
|  |         : m_u8view(view) | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  |     RegexStringView(const Utf32View view) | ||||||
|  |         : m_u32view(view) | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     bool is_u8_view() const { return m_u8view.has_value(); } | ||||||
|  |     bool is_u32_view() const { return m_u32view.has_value(); } | ||||||
|  | 
 | ||||||
|  |     const StringView& u8view() const | ||||||
|  |     { | ||||||
|  |         ASSERT(m_u8view.has_value()); | ||||||
|  |         return m_u8view.value(); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     const Utf32View& u32view() const | ||||||
|  |     { | ||||||
|  |         ASSERT(m_u32view.has_value()); | ||||||
|  |         return m_u32view.value(); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     bool is_empty() const | ||||||
|  |     { | ||||||
|  |         if (is_u8_view()) | ||||||
|  |             return m_u8view.value().is_empty(); | ||||||
|  |         else | ||||||
|  |             return m_u32view.value().is_empty(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     bool is_null() const | ||||||
|  |     { | ||||||
|  |         if (is_u8_view()) | ||||||
|  |             return m_u8view.value().is_null(); | ||||||
|  |         else | ||||||
|  |             return m_u32view.value().code_points() == nullptr; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     size_t length() const | ||||||
|  |     { | ||||||
|  |         if (is_u8_view()) | ||||||
|  |             return m_u8view.value().length(); | ||||||
|  |         else | ||||||
|  |             return m_u32view.value().length(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     Vector<RegexStringView> lines() const | ||||||
|  |     { | ||||||
|  |         if (is_u8_view()) { | ||||||
|  |             auto views = u8view().lines(false); | ||||||
|  |             Vector<RegexStringView> new_views; | ||||||
|  |             for (auto& view : views) | ||||||
|  |                 new_views.append(move(view)); | ||||||
|  |             return new_views; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // FIXME: line splitting for Utf32View needed
 | ||||||
|  |         Vector<RegexStringView> views; | ||||||
|  |         views.append(m_u32view.value()); | ||||||
|  |         return views; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     RegexStringView substring_view(size_t offset, size_t length) const | ||||||
|  |     { | ||||||
|  |         if (is_u8_view()) { | ||||||
|  |             return u8view().substring_view(offset, length); | ||||||
|  |         } | ||||||
|  |         return u32view().substring_view(offset, length); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     String to_string() const | ||||||
|  |     { | ||||||
|  |         if (is_u8_view()) { | ||||||
|  |             return u8view().to_string(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         StringBuilder builder; | ||||||
|  |         builder.append(u32view()); | ||||||
|  |         return builder.to_string(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     u32 operator[](size_t index) const | ||||||
|  |     { | ||||||
|  |         if (is_u8_view()) { | ||||||
|  |             return u8view()[index]; | ||||||
|  |         } | ||||||
|  |         return u32view().code_points()[index]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     bool operator==(const char* cstring) const | ||||||
|  |     { | ||||||
|  |         if (is_u8_view()) | ||||||
|  |             return u8view() == cstring; | ||||||
|  | 
 | ||||||
|  |         return to_string() == cstring; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     bool operator!=(const char* cstring) const | ||||||
|  |     { | ||||||
|  |         return !(*this == cstring); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     bool operator==(const String& string) const | ||||||
|  |     { | ||||||
|  |         if (is_u8_view()) | ||||||
|  |             return u8view() == string; | ||||||
|  | 
 | ||||||
|  |         return to_string() == string; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     bool operator==(const StringView& other) const | ||||||
|  |     { | ||||||
|  |         if (is_u8_view()) | ||||||
|  |             return u8view() == other; | ||||||
|  | 
 | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     bool operator!=(const StringView& other) const | ||||||
|  |     { | ||||||
|  |         return !(*this == other); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     bool operator==(const Utf32View& other) const | ||||||
|  |     { | ||||||
|  |         if (is_u32_view()) { | ||||||
|  |             StringBuilder builder; | ||||||
|  |             builder.append(other); | ||||||
|  |             return to_string() == builder.to_string(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     bool operator!=(const Utf32View& other) const | ||||||
|  |     { | ||||||
|  |         return !(*this == other); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     const char* characters_without_null_termination() const | ||||||
|  |     { | ||||||
|  |         if(is_u8_view()) | ||||||
|  |             return u8view().characters_without_null_termination(); | ||||||
|  | 
 | ||||||
|  |         return to_string().characters(); // FIXME: it contains the null termination, does that actually matter?
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     bool starts_with(const StringView& str) const | ||||||
|  |     { | ||||||
|  |         if(is_u32_view()) | ||||||
|  |             return false; | ||||||
|  |         return u8view().starts_with(str); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     bool starts_with(const Utf32View& str) const | ||||||
|  |     { | ||||||
|  |         if(is_u8_view()) | ||||||
|  |             return false; | ||||||
|  | 
 | ||||||
|  |         StringBuilder builder; | ||||||
|  |         builder.append(str); | ||||||
|  |         return to_string().starts_with(builder.to_string()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     Optional<StringView> m_u8view; | ||||||
|  |     Optional<Utf32View> m_u32view; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| class Match final { | class Match final { | ||||||
| private: | private: | ||||||
|     Optional<FlyString> string; |     Optional<FlyString> string; | ||||||
|  | @ -44,7 +229,7 @@ public: | ||||||
|     Match() = default; |     Match() = default; | ||||||
|     ~Match() = default; |     ~Match() = default; | ||||||
| 
 | 
 | ||||||
|     Match(const StringView view_, const size_t line_, const size_t column_, const size_t global_offset_) |     Match(const RegexStringView view_, const size_t line_, const size_t column_, const size_t global_offset_) | ||||||
|         : view(view_) |         : view(view_) | ||||||
|         , line(line_) |         , line(line_) | ||||||
|         , column(column_) |         , column(column_) | ||||||
|  | @ -63,7 +248,7 @@ public: | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     StringView view { nullptr }; |     RegexStringView view { nullptr }; | ||||||
|     size_t line { 0 }; |     size_t line { 0 }; | ||||||
|     size_t column { 0 }; |     size_t column { 0 }; | ||||||
|     size_t global_offset { 0 }; |     size_t global_offset { 0 }; | ||||||
|  | @ -74,14 +259,14 @@ public: | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct MatchInput { | struct MatchInput { | ||||||
|     StringView view { nullptr }; |     RegexStringView view { nullptr }; | ||||||
|     AllOptions regex_options {}; |     AllOptions regex_options {}; | ||||||
| 
 | 
 | ||||||
|     size_t match_index { 0 }; |     size_t match_index { 0 }; | ||||||
|     size_t line { 0 }; |     size_t line { 0 }; | ||||||
|     size_t column { 0 }; |     size_t column { 0 }; | ||||||
| 
 | 
 | ||||||
|     size_t global_offset { 0 }; // For multiline matching, knowning the offset from start could be important
 |     size_t global_offset { 0 }; // For multiline matching, knowing the offset from start could be important
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct MatchState { | struct MatchState { | ||||||
|  | @ -98,3 +283,5 @@ struct MatchOutput { | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | using regex::RegexStringView; | ||||||
|  |  | ||||||
|  | @ -66,10 +66,22 @@ String Regex<Parser>::error_string(Optional<String> message) const | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template<typename Parser> | template<typename Parser> | ||||||
| RegexResult Matcher<Parser>::match(const StringView& view, Optional<typename ParserTraits<Parser>::OptionsType> regex_options) const | RegexResult Matcher<Parser>::match(const RegexStringView& view, Optional<typename ParserTraits<Parser>::OptionsType> regex_options) const | ||||||
|  | { | ||||||
|  |     AllOptions options = m_regex_options | regex_options.value_or({}).value(); | ||||||
|  | 
 | ||||||
|  |     if (options.has_flag_set(AllFlags::Multiline)) | ||||||
|  |         return match(view.lines(), regex_options); // FIXME: how do we know, which line ending a line has (1char or 2char)? This is needed to get the correct match offsets from start of string...
 | ||||||
|  | 
 | ||||||
|  |     Vector<RegexStringView> views; | ||||||
|  |     views.append(view); | ||||||
|  |     return match(views, regex_options); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template<typename Parser> | ||||||
|  | RegexResult Matcher<Parser>::match(const Vector<RegexStringView> views, Optional<typename ParserTraits<Parser>::OptionsType> regex_options) const | ||||||
| { | { | ||||||
|     size_t match_count { 0 }; |     size_t match_count { 0 }; | ||||||
|     Vector<StringView> views { view }; |  | ||||||
| 
 | 
 | ||||||
|     MatchInput input; |     MatchInput input; | ||||||
|     MatchState state; |     MatchState state; | ||||||
|  | @ -78,9 +90,6 @@ RegexResult Matcher<Parser>::match(const StringView& view, Optional<typename Par | ||||||
|     input.regex_options = m_regex_options | regex_options.value_or({}).value(); |     input.regex_options = m_regex_options | regex_options.value_or({}).value(); | ||||||
|     output.operations = 0; |     output.operations = 0; | ||||||
| 
 | 
 | ||||||
|     if (input.regex_options & AllFlags::Multiline) |  | ||||||
|         views = view.lines(false); // FIXME: how do we know, which line ending a line has (1char or 2char)? This is needed to get the correct match offsets from start of string...
 |  | ||||||
| 
 |  | ||||||
|     if (c_match_preallocation_count) { |     if (c_match_preallocation_count) { | ||||||
|         output.matches.ensure_capacity(c_match_preallocation_count); |         output.matches.ensure_capacity(c_match_preallocation_count); | ||||||
|         output.capture_group_matches.ensure_capacity(c_match_preallocation_count); |         output.capture_group_matches.ensure_capacity(c_match_preallocation_count); | ||||||
|  | @ -192,7 +201,16 @@ RegexResult Matcher<Parser>::match(const StringView& view, Optional<typename Par | ||||||
|     if (match_count) { |     if (match_count) { | ||||||
|         auto capture_groups_count = min(output.capture_group_matches.size(), output.matches.size()); |         auto capture_groups_count = min(output.capture_group_matches.size(), output.matches.size()); | ||||||
|         for (size_t i = 0; i < capture_groups_count; ++i) { |         for (size_t i = 0; i < capture_groups_count; ++i) { | ||||||
|  |             if(input.regex_options & AllFlags::SkipTrimEmptyMatches) { | ||||||
|                 output_copy.capture_group_matches.append(output.capture_group_matches.at(i)); |                 output_copy.capture_group_matches.append(output.capture_group_matches.at(i)); | ||||||
|  |             } else { | ||||||
|  |                 Vector<Match> capture_group_matches; | ||||||
|  |                 for (size_t j = 0; j < output.capture_group_matches.at(i).size(); ++j) { | ||||||
|  |                     if (!output.capture_group_matches.at(i).at(j).view.is_null()) | ||||||
|  |                         capture_group_matches.append(output.capture_group_matches.at(i).at(j)); | ||||||
|  |                 } | ||||||
|  |                 output_copy.capture_group_matches.append(capture_group_matches); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         auto named_capture_groups_count = min(output.named_capture_group_matches.size(), output.matches.size()); |         auto named_capture_groups_count = min(output.named_capture_group_matches.size(), output.matches.size()); | ||||||
|  | @ -216,6 +234,8 @@ RegexResult Matcher<Parser>::match(const StringView& view, Optional<typename Par | ||||||
|         move(output_copy.capture_group_matches), |         move(output_copy.capture_group_matches), | ||||||
|         move(output_copy.named_capture_group_matches), |         move(output_copy.named_capture_group_matches), | ||||||
|         output.operations, |         output.operations, | ||||||
|  |         m_pattern.parser_result.capture_groups_count, | ||||||
|  |         m_pattern.parser_result.named_capture_groups_count, | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -306,7 +326,7 @@ ALWAYS_INLINE Optional<bool> Matcher<Parser>::execute_low_prio_forks(const Match | ||||||
| 
 | 
 | ||||||
|     original_state.string_position = 0; |     original_state.string_position = 0; | ||||||
|     return false; |     return false; | ||||||
| }; | } | ||||||
| 
 | 
 | ||||||
| template class Matcher<PosixExtendedParser>; | template class Matcher<PosixExtendedParser>; | ||||||
| template class Regex<PosixExtendedParser>; | template class Regex<PosixExtendedParser>; | ||||||
|  |  | ||||||
|  | @ -35,6 +35,7 @@ | ||||||
| #include <AK/HashMap.h> | #include <AK/HashMap.h> | ||||||
| #include <AK/NonnullOwnPtrVector.h> | #include <AK/NonnullOwnPtrVector.h> | ||||||
| #include <AK/Types.h> | #include <AK/Types.h> | ||||||
|  | #include <AK/Utf32View.h> | ||||||
| #include <AK/Vector.h> | #include <AK/Vector.h> | ||||||
| 
 | 
 | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
|  | @ -50,7 +51,9 @@ struct RegexResult final { | ||||||
|     Vector<Match> matches; |     Vector<Match> matches; | ||||||
|     Vector<Vector<Match>> capture_group_matches; |     Vector<Vector<Match>> capture_group_matches; | ||||||
|     Vector<HashMap<String, Match>> named_capture_group_matches; |     Vector<HashMap<String, Match>> named_capture_group_matches; | ||||||
|     size_t operations { 0 }; |     size_t n_operations { 0 }; | ||||||
|  |     size_t n_capture_groups { 0 }; | ||||||
|  |     size_t n_named_capture_groups { 0 }; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<class Parser> | template<class Parser> | ||||||
|  | @ -67,7 +70,8 @@ public: | ||||||
|     } |     } | ||||||
|     ~Matcher() = default; |     ~Matcher() = default; | ||||||
| 
 | 
 | ||||||
|     RegexResult match(const StringView&, Optional<typename ParserTraits<Parser>::OptionsType> = {}) const; |     RegexResult match(const RegexStringView&, Optional<typename ParserTraits<Parser>::OptionsType> = {}) const; | ||||||
|  |     RegexResult match(const Vector<RegexStringView>, Optional<typename ParserTraits<Parser>::OptionsType> = {}) const; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     Optional<bool> execute(const MatchInput& input, MatchState& state, MatchOutput& output, size_t recursion_level) const; |     Optional<bool> execute(const MatchInput& input, MatchState& state, MatchOutput& output, size_t recursion_level) const; | ||||||
|  | @ -84,20 +88,27 @@ public: | ||||||
|     regex::Parser::Result parser_result; |     regex::Parser::Result parser_result; | ||||||
|     OwnPtr<Matcher<Parser>> matcher { nullptr }; |     OwnPtr<Matcher<Parser>> matcher { nullptr }; | ||||||
| 
 | 
 | ||||||
|     Regex(StringView pattern, typename ParserTraits<Parser>::OptionsType regex_options = {}); |     explicit Regex(StringView pattern, typename ParserTraits<Parser>::OptionsType regex_options = {}); | ||||||
|     ~Regex() = default; |     ~Regex() = default; | ||||||
| 
 | 
 | ||||||
|     void print_bytecode(FILE* f = stdout) const; |     void print_bytecode(FILE* f = stdout) const; | ||||||
|     String error_string(Optional<String> message = {}) const; |     String error_string(Optional<String> message = {}) const; | ||||||
| 
 | 
 | ||||||
|     RegexResult match(StringView view, Optional<typename ParserTraits<Parser>::OptionsType> regex_options = {}) const |     RegexResult match(const RegexStringView view, Optional<typename ParserTraits<Parser>::OptionsType> regex_options = {}) const | ||||||
|     { |     { | ||||||
|         if (!matcher || parser_result.error != Error::NoError) |         if (!matcher || parser_result.error != Error::NoError) | ||||||
|             return {}; |             return {}; | ||||||
|         return matcher->match(view, regex_options); |         return matcher->match(view, regex_options); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     RegexResult search(StringView view, Optional<typename ParserTraits<Parser>::OptionsType> regex_options = {}) const |     RegexResult match(const Vector<RegexStringView> views, Optional<typename ParserTraits<Parser>::OptionsType> regex_options = {}) const | ||||||
|  |     { | ||||||
|  |         if (!matcher || parser_result.error != Error::NoError) | ||||||
|  |             return {}; | ||||||
|  |         return matcher->match(views, regex_options); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     RegexResult search(const RegexStringView view, Optional<typename ParserTraits<Parser>::OptionsType> regex_options = {}) const | ||||||
|     { |     { | ||||||
|         if (!matcher || parser_result.error != Error::NoError) |         if (!matcher || parser_result.error != Error::NoError) | ||||||
|             return {}; |             return {}; | ||||||
|  | @ -112,72 +123,123 @@ public: | ||||||
|         return matcher->match(view, options); |         return matcher->match(view, options); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     bool match(StringView view, RegexResult& m, Optional<typename ParserTraits<Parser>::OptionsType> regex_options = {}) const |     RegexResult search(const Vector<RegexStringView> views, Optional<typename ParserTraits<Parser>::OptionsType> regex_options = {}) const | ||||||
|     { |     { | ||||||
|         if (!matcher || parser_result.error != Error::NoError) |         if (!matcher || parser_result.error != Error::NoError) | ||||||
|             return {}; |             return {}; | ||||||
|         m = matcher->match(view, regex_options); | 
 | ||||||
|  |         AllOptions options = (AllOptions)regex_options.value_or({}); | ||||||
|  |         if ((options & AllFlags::MatchNotBeginOfLine) && (options & AllFlags::MatchNotEndOfLine)) { | ||||||
|  |             options.reset_flag(AllFlags::MatchNotEndOfLine); | ||||||
|  |             options.reset_flag(AllFlags::MatchNotBeginOfLine); | ||||||
|  |         } | ||||||
|  |         options |= AllFlags::Global; | ||||||
|  | 
 | ||||||
|  |         return matcher->match(views, options); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     bool match(const RegexStringView view, RegexResult& m, Optional<typename ParserTraits<Parser>::OptionsType> regex_options = {}) const | ||||||
|  |     { | ||||||
|  |         m = match(view, regex_options); | ||||||
|         return m.success; |         return m.success; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     bool search(StringView view, RegexResult& m, Optional<typename ParserTraits<Parser>::OptionsType> regex_options = {}) const |     bool match(const Vector<RegexStringView> views, RegexResult& m, Optional<typename ParserTraits<Parser>::OptionsType> regex_options = {}) const | ||||||
|  |     { | ||||||
|  |         m = match(views, regex_options); | ||||||
|  |         return m.success; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     bool search(const RegexStringView view, RegexResult& m, Optional<typename ParserTraits<Parser>::OptionsType> regex_options = {}) const | ||||||
|     { |     { | ||||||
|         m = search(view, regex_options); |         m = search(view, regex_options); | ||||||
|         return m.success; |         return m.success; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     bool has_match(const StringView view, Optional<typename ParserTraits<Parser>::OptionsType> regex_options = {}) const |     bool search(const Vector<RegexStringView> views, RegexResult& m, Optional<typename ParserTraits<Parser>::OptionsType> regex_options = {}) const | ||||||
|  |     { | ||||||
|  |         m = search(views, regex_options); | ||||||
|  |         return m.success; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     bool has_match(const RegexStringView view, Optional<typename ParserTraits<Parser>::OptionsType> regex_options = {}) const | ||||||
|     { |     { | ||||||
|         if (!matcher || parser_result.error != Error::NoError) |         if (!matcher || parser_result.error != Error::NoError) | ||||||
|             return false; |             return false; | ||||||
|         RegexResult result = matcher->match(view, AllOptions { regex_options.value_or({}) } | AllFlags::SkipSubExprResults); |         RegexResult result = matcher->match(view, AllOptions { regex_options.value_or({}) } | AllFlags::SkipSubExprResults); | ||||||
|         return result.success; |         return result.success; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     bool has_match(const Vector<RegexStringView> views, Optional<typename ParserTraits<Parser>::OptionsType> regex_options = {}) const | ||||||
|  |     { | ||||||
|  |         if (!matcher || parser_result.error != Error::NoError) | ||||||
|  |             return false; | ||||||
|  |         RegexResult result = matcher->match(views, AllOptions { regex_options.value_or({}) } | AllFlags::SkipSubExprResults); | ||||||
|  |         return result.success; | ||||||
|  |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | // free standing functions for match, search and has_match
 | ||||||
| template<class Parser> | template<class Parser> | ||||||
| RegexResult match(const StringView view, Regex<Parser>& pattern, Optional<typename ParserTraits<Parser>::OptionsType> regex_options = {}) | RegexResult match(const RegexStringView view, Regex<Parser>& pattern, Optional<typename ParserTraits<Parser>::OptionsType> regex_options = {}) | ||||||
| { | { | ||||||
|     if (!pattern.matcher || pattern.parser_result.error != Error::NoError) |     return pattern.match(view, regex_options); | ||||||
|         return {}; |  | ||||||
|     return pattern.matcher->match(view, regex_options); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template<class Parser> | template<class Parser> | ||||||
| bool match(const StringView view, Regex<Parser>& pattern, RegexResult& res, Optional<typename ParserTraits<Parser>::OptionsType> regex_options = {}) | RegexResult match(const Vector<RegexStringView> view, Regex<Parser>& pattern, Optional<typename ParserTraits<Parser>::OptionsType> regex_options = {}) | ||||||
| { | { | ||||||
|     if (!pattern.matcher || pattern.parser_result.error != Error::NoError) |     return pattern.match(view, regex_options); | ||||||
|         return {}; |  | ||||||
|     res = pattern.matcher->match(view, regex_options); |  | ||||||
|     return res.success; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template<class Parser> | template<class Parser> | ||||||
| RegexResult search(const StringView view, Regex<Parser>& pattern, Optional<typename ParserTraits<Parser>::OptionsType> regex_options = {}) | bool match(const RegexStringView view, Regex<Parser>& pattern, RegexResult& res, Optional<typename ParserTraits<Parser>::OptionsType> regex_options = {}) | ||||||
| { | { | ||||||
|     if (!pattern.matcher || pattern.parser_result.error != Error::NoError) |     return pattern.match(view, regex_options); | ||||||
|         return {}; |  | ||||||
|     return pattern.matcher->search(view, regex_options); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template<class Parser> | template<class Parser> | ||||||
| bool search(const StringView view, Regex<Parser>& pattern, RegexResult& res, Optional<typename ParserTraits<Parser>::OptionsType> regex_options = {}) | bool match(const Vector<RegexStringView> view, Regex<Parser>& pattern, RegexResult& res, Optional<typename ParserTraits<Parser>::OptionsType> regex_options = {}) | ||||||
| { | { | ||||||
|     if (!pattern.matcher || pattern.parser_result.error != Error::NoError) |     return pattern.match(view, regex_options); | ||||||
|         return {}; |  | ||||||
|     res = pattern.matcher->search(view, regex_options); |  | ||||||
|     return res.success; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template<class Parser> | template<class Parser> | ||||||
| bool has_match(const StringView view, Regex<Parser>& pattern, Optional<typename ParserTraits<Parser>::OptionsType> regex_options = {}) | RegexResult search(const RegexStringView view, Regex<Parser>& pattern, Optional<typename ParserTraits<Parser>::OptionsType> regex_options = {}) | ||||||
| { | { | ||||||
|     if (pattern.matcher == nullptr) |     return pattern.search(view, regex_options); | ||||||
|         return {}; |  | ||||||
|     RegexResult result = pattern.matcher->match(view, AllOptions { regex_options.value_or({}) } | AllFlags::SkipSubExprResults); |  | ||||||
|     return result.success; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | template<class Parser> | ||||||
|  | RegexResult search(const Vector<RegexStringView> views, Regex<Parser>& pattern, Optional<typename ParserTraits<Parser>::OptionsType> regex_options = {}) | ||||||
|  | { | ||||||
|  |     return pattern.search(views, regex_options); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | template<class Parser> | ||||||
|  | bool search(const RegexStringView view, Regex<Parser>& pattern, RegexResult& res, Optional<typename ParserTraits<Parser>::OptionsType> regex_options = {}) | ||||||
|  | { | ||||||
|  |     return pattern.search(view, regex_options); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template<class Parser> | ||||||
|  | bool search(const Vector<RegexStringView> views, Regex<Parser>& pattern, RegexResult& res, Optional<typename ParserTraits<Parser>::OptionsType> regex_options = {}) | ||||||
|  | { | ||||||
|  |     return pattern.search(views, regex_options); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template<class Parser> | ||||||
|  | bool has_match(const RegexStringView view, Regex<Parser>& pattern, Optional<typename ParserTraits<Parser>::OptionsType> regex_options = {}) | ||||||
|  | { | ||||||
|  |     return pattern.has_match(view, regex_options); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template<class Parser> | ||||||
|  | bool has_match(const Vector<RegexStringView> views, Regex<Parser>& pattern, Optional<typename ParserTraits<Parser>::OptionsType> regex_options = {}) | ||||||
|  | { | ||||||
|  |     return pattern.has_match(views, regex_options); | ||||||
|  | } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| using regex::has_match; | using regex::has_match; | ||||||
|  |  | ||||||
|  | @ -66,6 +66,7 @@ enum class PosixFlags : FlagsUnderlyingType { | ||||||
|     MatchNotBeginOfLine = (FlagsUnderlyingType)AllFlags::MatchNotBeginOfLine, |     MatchNotBeginOfLine = (FlagsUnderlyingType)AllFlags::MatchNotBeginOfLine, | ||||||
|     MatchNotEndOfLine = (FlagsUnderlyingType)AllFlags::MatchNotEndOfLine, |     MatchNotEndOfLine = (FlagsUnderlyingType)AllFlags::MatchNotEndOfLine, | ||||||
|     SkipSubExprResults = (FlagsUnderlyingType)AllFlags::SkipSubExprResults, |     SkipSubExprResults = (FlagsUnderlyingType)AllFlags::SkipSubExprResults, | ||||||
|  |     SkipTrimEmptyMatches = (FlagsUnderlyingType)AllFlags::SkipTrimEmptyMatches, | ||||||
|     Multiline = (FlagsUnderlyingType)AllFlags::Multiline, |     Multiline = (FlagsUnderlyingType)AllFlags::Multiline, | ||||||
|     StringCopyMatches = (FlagsUnderlyingType)AllFlags::StringCopyMatches, |     StringCopyMatches = (FlagsUnderlyingType)AllFlags::StringCopyMatches, | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -42,6 +42,12 @@ | ||||||
| #        include <regex> | #        include <regex> | ||||||
| #    endif | #    endif | ||||||
| 
 | 
 | ||||||
|  | #    if not(defined(REGEX_BENCHMARK_OUR) && defined(REGEX_BENCHMARK_OUR)) | ||||||
|  | BENCHMARK_CASE(dummy_benchmark) | ||||||
|  | { | ||||||
|  | } | ||||||
|  | #    endif | ||||||
|  | 
 | ||||||
| #    if defined(REGEX_BENCHMARK_OUR) | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
| BENCHMARK_CASE(catch_all_benchmark) | BENCHMARK_CASE(catch_all_benchmark) | ||||||
| { | { | ||||||
|  | @ -51,10 +57,10 @@ BENCHMARK_CASE(catch_all_benchmark) | ||||||
|         EXPECT(re.match("Hello World", m)); |         EXPECT(re.match("Hello World", m)); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OTHER) | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
| BENCHMARK_CASE(catch_all_benchmark_reference_stdcpp_regex_match) | BENCHMARK_CASE(catch_all_benchmark_reference_stdcpp) | ||||||
| { | { | ||||||
|     std::regex re("^.*$"); |     std::regex re("^.*$"); | ||||||
|     std::cmatch m; |     std::cmatch m; | ||||||
|  | @ -62,9 +68,9 @@ BENCHMARK_CASE(catch_all_benchmark_reference_stdcpp_regex_match) | ||||||
|         EXPECT_EQ(std::regex_match("Hello World", m, re), true); |         EXPECT_EQ(std::regex_match("Hello World", m, re), true); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OUR) | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
| BENCHMARK_CASE(simple_start_benchmark) | BENCHMARK_CASE(simple_start_benchmark) | ||||||
| { | { | ||||||
|     Regex<PosixExtended> re("^hello friends"); |     Regex<PosixExtended> re("^hello friends"); | ||||||
|  | @ -75,10 +81,10 @@ BENCHMARK_CASE(simple_start_benchmark) | ||||||
|         EXPECT_EQ(re.match("Well, hello friends", m), false); |         EXPECT_EQ(re.match("Well, hello friends", m), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OTHER) | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
| BENCHMARK_CASE(simple_start_benchmark_reference_stdcpp_regex_match) | BENCHMARK_CASE(simple_start_benchmark_reference_stdcpp) | ||||||
| { | { | ||||||
|     std::regex re("^hello friends"); |     std::regex re("^hello friends"); | ||||||
|     std::cmatch m; |     std::cmatch m; | ||||||
|  | @ -88,9 +94,9 @@ BENCHMARK_CASE(simple_start_benchmark_reference_stdcpp_regex_match) | ||||||
|         EXPECT_EQ(std::regex_match("Well, hello friends", m, re), false); |         EXPECT_EQ(std::regex_match("Well, hello friends", m, re), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OUR) | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
| BENCHMARK_CASE(simple_end_benchmark) | BENCHMARK_CASE(simple_end_benchmark) | ||||||
| { | { | ||||||
|     Regex<PosixExtended> re(".*hello\\.\\.\\. there$"); |     Regex<PosixExtended> re(".*hello\\.\\.\\. there$"); | ||||||
|  | @ -102,10 +108,10 @@ BENCHMARK_CASE(simple_end_benchmark) | ||||||
|         EXPECT_EQ(re.match("hello.. there", m), false); |         EXPECT_EQ(re.match("hello.. there", m), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OTHER) | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
| BENCHMARK_CASE(simple_end_benchmark_reference_stdcpp_regex_search) | BENCHMARK_CASE(simple_end_benchmark_reference_stdcpp) | ||||||
| { | { | ||||||
|     std::regex re(".*hello\\.\\.\\. there$"); |     std::regex re(".*hello\\.\\.\\. there$"); | ||||||
|     std::cmatch m; |     std::cmatch m; | ||||||
|  | @ -116,9 +122,9 @@ BENCHMARK_CASE(simple_end_benchmark_reference_stdcpp_regex_search) | ||||||
|         EXPECT_EQ(std::regex_search("hello.. there", m, re), false); |         EXPECT_EQ(std::regex_search("hello.. there", m, re), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OUR) | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
| BENCHMARK_CASE(simple_period_benchmark) | BENCHMARK_CASE(simple_period_benchmark) | ||||||
| { | { | ||||||
|     Regex<PosixExtended> re("hello."); |     Regex<PosixExtended> re("hello."); | ||||||
|  | @ -130,10 +136,10 @@ BENCHMARK_CASE(simple_period_benchmark) | ||||||
|         EXPECT_EQ(re.match("hello?", m), true); |         EXPECT_EQ(re.match("hello?", m), true); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OTHER) | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
| BENCHMARK_CASE(simple_period_benchmark_reference_stdcpp_regex_match) | BENCHMARK_CASE(simple_period_benchmark_reference_stdcpp) | ||||||
| { | { | ||||||
|     std::regex re("hello."); |     std::regex re("hello."); | ||||||
|     std::cmatch m; |     std::cmatch m; | ||||||
|  | @ -144,9 +150,9 @@ BENCHMARK_CASE(simple_period_benchmark_reference_stdcpp_regex_match) | ||||||
|         EXPECT_EQ(std::regex_match("hello?", m, re), true); |         EXPECT_EQ(std::regex_match("hello?", m, re), true); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OUR) | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
| BENCHMARK_CASE(simple_period_end_benchmark) | BENCHMARK_CASE(simple_period_end_benchmark) | ||||||
| { | { | ||||||
|     Regex<PosixExtended> re("hello.$"); |     Regex<PosixExtended> re("hello.$"); | ||||||
|  | @ -158,10 +164,10 @@ BENCHMARK_CASE(simple_period_end_benchmark) | ||||||
|         EXPECT_EQ(re.search("hello?", m), true); |         EXPECT_EQ(re.search("hello?", m), true); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OTHER) | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
| BENCHMARK_CASE(simple_period_end_benchmark_reference_stdcpp_regex_search) | BENCHMARK_CASE(simple_period_end_benchmark_reference_stdcpp) | ||||||
| { | { | ||||||
|     std::regex re("hello.$"); |     std::regex re("hello.$"); | ||||||
|     std::cmatch m; |     std::cmatch m; | ||||||
|  | @ -172,9 +178,9 @@ BENCHMARK_CASE(simple_period_end_benchmark_reference_stdcpp_regex_search) | ||||||
|         EXPECT_EQ(std::regex_search("hello?", m, re), true); |         EXPECT_EQ(std::regex_search("hello?", m, re), true); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OUR) | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
| BENCHMARK_CASE(simple_escaped_benchmark) | BENCHMARK_CASE(simple_escaped_benchmark) | ||||||
| { | { | ||||||
|     Regex<PosixExtended> re("hello\\."); |     Regex<PosixExtended> re("hello\\."); | ||||||
|  | @ -184,10 +190,10 @@ BENCHMARK_CASE(simple_escaped_benchmark) | ||||||
|         EXPECT_EQ(re.match("hello.", m), true); |         EXPECT_EQ(re.match("hello.", m), true); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OTHER) | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
| BENCHMARK_CASE(simple_escaped_benchmark_reference_stdcpp_regex_match) | BENCHMARK_CASE(simple_escaped_benchmark_reference_stdcpp) | ||||||
| { | { | ||||||
|     std::regex re("hello\\."); |     std::regex re("hello\\."); | ||||||
|     std::cmatch m; |     std::cmatch m; | ||||||
|  | @ -196,9 +202,9 @@ BENCHMARK_CASE(simple_escaped_benchmark_reference_stdcpp_regex_match) | ||||||
|         EXPECT_EQ(std::regex_match("hello.", m, re), true); |         EXPECT_EQ(std::regex_match("hello.", m, re), true); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OUR) | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
| BENCHMARK_CASE(simple_period2_end_benchmark) | BENCHMARK_CASE(simple_period2_end_benchmark) | ||||||
| { | { | ||||||
|     Regex<PosixExtended> re(".*hi... there$"); |     Regex<PosixExtended> re(".*hi... there$"); | ||||||
|  | @ -211,10 +217,10 @@ BENCHMARK_CASE(simple_period2_end_benchmark) | ||||||
|         EXPECT_EQ(re.search("I said fyhihi there", m), false); |         EXPECT_EQ(re.search("I said fyhihi there", m), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OTHER) | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
| BENCHMARK_CASE(simple_period2_end_benchmark_reference_stdcpp_regex_search) | BENCHMARK_CASE(simple_period2_end_benchmark_reference_stdcpp) | ||||||
| { | { | ||||||
|     std::regex re(".*hi... there$"); |     std::regex re(".*hi... there$"); | ||||||
|     std::cmatch m; |     std::cmatch m; | ||||||
|  | @ -226,9 +232,9 @@ BENCHMARK_CASE(simple_period2_end_benchmark_reference_stdcpp_regex_search) | ||||||
|         EXPECT_EQ(std::regex_search("I said fyhihi there", m, re), false); |         EXPECT_EQ(std::regex_search("I said fyhihi there", m, re), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OUR) | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
| BENCHMARK_CASE(simple_plus_benchmark) | BENCHMARK_CASE(simple_plus_benchmark) | ||||||
| { | { | ||||||
|     Regex<PosixExtended> re("a+"); |     Regex<PosixExtended> re("a+"); | ||||||
|  | @ -240,10 +246,10 @@ BENCHMARK_CASE(simple_plus_benchmark) | ||||||
|         EXPECT_EQ(re.search("aaaaaaaaaaa", m), true); |         EXPECT_EQ(re.search("aaaaaaaaaaa", m), true); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OTHER) | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
| BENCHMARK_CASE(simple_plus_benchmark_reference_stdcpp_regex_search) | BENCHMARK_CASE(simple_plus_benchmark_reference_stdcpp) | ||||||
| { | { | ||||||
|     std::regex re("a+"); |     std::regex re("a+"); | ||||||
|     std::cmatch m; |     std::cmatch m; | ||||||
|  | @ -254,9 +260,9 @@ BENCHMARK_CASE(simple_plus_benchmark_reference_stdcpp_regex_search) | ||||||
|         EXPECT_EQ(std::regex_search("aaaaaaaaaaa", m, re), true); |         EXPECT_EQ(std::regex_search("aaaaaaaaaaa", m, re), true); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OUR) | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
| BENCHMARK_CASE(simple_questionmark_benchmark) | BENCHMARK_CASE(simple_questionmark_benchmark) | ||||||
| { | { | ||||||
|     Regex<PosixExtended> re("da?d"); |     Regex<PosixExtended> re("da?d"); | ||||||
|  | @ -271,10 +277,10 @@ BENCHMARK_CASE(simple_questionmark_benchmark) | ||||||
|         EXPECT_EQ(re.search("adadaa", m), true); |         EXPECT_EQ(re.search("adadaa", m), true); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OTHER) | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
| BENCHMARK_CASE(simple_questionmark_benchmark_reference_stdcpp_regex_search) | BENCHMARK_CASE(simple_questionmark_benchmark_reference_stdcpp) | ||||||
| { | { | ||||||
|     std::regex re("da?d"); |     std::regex re("da?d"); | ||||||
|     std::cmatch m; |     std::cmatch m; | ||||||
|  | @ -288,9 +294,9 @@ BENCHMARK_CASE(simple_questionmark_benchmark_reference_stdcpp_regex_search) | ||||||
|         EXPECT_EQ(std::regex_search("adadaa", m, re), true); |         EXPECT_EQ(std::regex_search("adadaa", m, re), true); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OUR) | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
| BENCHMARK_CASE(character_class_benchmark) | BENCHMARK_CASE(character_class_benchmark) | ||||||
| { | { | ||||||
|     Regex<PosixExtended> re("[[:alpha:]]"); |     Regex<PosixExtended> re("[[:alpha:]]"); | ||||||
|  | @ -302,10 +308,10 @@ BENCHMARK_CASE(character_class_benchmark) | ||||||
|         EXPECT_EQ(re.search(haystack.characters(), m), true); |         EXPECT_EQ(re.search(haystack.characters(), m), true); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OTHER) | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
| BENCHMARK_CASE(character_class_benchmark_reference_stdcpp_regex_search) | BENCHMARK_CASE(character_class_benchmark_reference_stdcpp) | ||||||
| { | { | ||||||
|     std::regex re("[[:alpha:]]"); |     std::regex re("[[:alpha:]]"); | ||||||
|     std::cmatch m; |     std::cmatch m; | ||||||
|  | @ -316,9 +322,9 @@ BENCHMARK_CASE(character_class_benchmark_reference_stdcpp_regex_search) | ||||||
|         EXPECT_EQ(std::regex_search(haystack.characters(), m, re), true); |         EXPECT_EQ(std::regex_search(haystack.characters(), m, re), true); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OUR) | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
| BENCHMARK_CASE(escaped_char_questionmark_benchmark) | BENCHMARK_CASE(escaped_char_questionmark_benchmark) | ||||||
| { | { | ||||||
|     Regex<PosixExtended> re("This\\.?And\\.?That"); |     Regex<PosixExtended> re("This\\.?And\\.?That"); | ||||||
|  | @ -330,10 +336,10 @@ BENCHMARK_CASE(escaped_char_questionmark_benchmark) | ||||||
|         EXPECT_EQ(re.match("This..And..That", m), false); |         EXPECT_EQ(re.match("This..And..That", m), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OTHER) | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
| BENCHMARK_CASE(escaped_char_questionmark_benchmark_reference_stdcpp_regex_match) | BENCHMARK_CASE(escaped_char_questionmark_benchmark_reference_stdcpp) | ||||||
| { | { | ||||||
|     std::regex re("This\\.?And\\.?That"); |     std::regex re("This\\.?And\\.?That"); | ||||||
|     std::cmatch m; |     std::cmatch m; | ||||||
|  | @ -344,9 +350,9 @@ BENCHMARK_CASE(escaped_char_questionmark_benchmark_reference_stdcpp_regex_match) | ||||||
|         EXPECT_EQ(std::regex_match("This..And..That", m, re), false); |         EXPECT_EQ(std::regex_match("This..And..That", m, re), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OUR) | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
| BENCHMARK_CASE(char_qualifier_asterisk_benchmark) | BENCHMARK_CASE(char_qualifier_asterisk_benchmark) | ||||||
| { | { | ||||||
|     Regex<PosixExtended> re("regex*"); |     Regex<PosixExtended> re("regex*"); | ||||||
|  | @ -356,10 +362,10 @@ BENCHMARK_CASE(char_qualifier_asterisk_benchmark) | ||||||
|         EXPECT_EQ(re.search("#include <stdio.h>", m), false); |         EXPECT_EQ(re.search("#include <stdio.h>", m), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OTHER) | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
| BENCHMARK_CASE(char_qualifier_asterisk_benchmark_reference_stdcpp_regex_match) | BENCHMARK_CASE(char_qualifier_asterisk_benchmark_reference_stdcpp) | ||||||
| { | { | ||||||
|     std::regex re("regex*"); |     std::regex re("regex*"); | ||||||
|     std::cmatch m; |     std::cmatch m; | ||||||
|  | @ -368,9 +374,9 @@ BENCHMARK_CASE(char_qualifier_asterisk_benchmark_reference_stdcpp_regex_match) | ||||||
|         EXPECT_EQ(std::regex_search("#include <stdio.h>", m, re), false); |         EXPECT_EQ(std::regex_search("#include <stdio.h>", m, re), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OUR) | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
| BENCHMARK_CASE(parens_qualifier_questionmark_benchmark) | BENCHMARK_CASE(parens_qualifier_questionmark_benchmark) | ||||||
| { | { | ||||||
|     Regex<PosixExtended> re("test(hello)?test"); |     Regex<PosixExtended> re("test(hello)?test"); | ||||||
|  | @ -381,10 +387,10 @@ BENCHMARK_CASE(parens_qualifier_questionmark_benchmark) | ||||||
|         EXPECT_EQ(re.match("testasfdtest", m), false); |         EXPECT_EQ(re.match("testasfdtest", m), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OTHER) | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
| BENCHMARK_CASE(parens_qualifier_questionmark_benchmark_reference_stdcpp_regex_match) | BENCHMARK_CASE(parens_qualifier_questionmark_benchmark_reference_stdcpp) | ||||||
| { | { | ||||||
|     std::regex re("test(hello)?test"); |     std::regex re("test(hello)?test"); | ||||||
|     std::cmatch m; |     std::cmatch m; | ||||||
|  | @ -394,9 +400,9 @@ BENCHMARK_CASE(parens_qualifier_questionmark_benchmark_reference_stdcpp_regex_ma | ||||||
|         EXPECT_EQ(std::regex_match("testasfdtest", m, re), false); |         EXPECT_EQ(std::regex_match("testasfdtest", m, re), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OUR) | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
| BENCHMARK_CASE(parens_qualifier_asterisk_benchmark) | BENCHMARK_CASE(parens_qualifier_asterisk_benchmark) | ||||||
| { | { | ||||||
|     Regex<PosixExtended> re("test(hello)*test"); |     Regex<PosixExtended> re("test(hello)*test"); | ||||||
|  | @ -408,10 +414,10 @@ BENCHMARK_CASE(parens_qualifier_asterisk_benchmark) | ||||||
|         EXPECT_EQ(re.match("aaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbb", m), false); |         EXPECT_EQ(re.match("aaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbb", m), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OTHER) | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
| BENCHMARK_CASE(parens_qualifier_asterisk_benchmark_reference_stdcpp_regex_match) | BENCHMARK_CASE(parens_qualifier_asterisk_benchmark_reference_stdcpp) | ||||||
| { | { | ||||||
|     std::regex re("test(hello)*test"); |     std::regex re("test(hello)*test"); | ||||||
|     std::cmatch m; |     std::cmatch m; | ||||||
|  | @ -422,9 +428,9 @@ BENCHMARK_CASE(parens_qualifier_asterisk_benchmark_reference_stdcpp_regex_match) | ||||||
|         EXPECT_EQ(std::regex_match("aaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbb", m, re), false); |         EXPECT_EQ(std::regex_match("aaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbb", m, re), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OUR) | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
| BENCHMARK_CASE(parens_qualifier_asterisk_2_benchmark) | BENCHMARK_CASE(parens_qualifier_asterisk_2_benchmark) | ||||||
| { | { | ||||||
|     Regex<PosixExtended> re("test(.*)test"); |     Regex<PosixExtended> re("test(.*)test"); | ||||||
|  | @ -436,10 +442,10 @@ BENCHMARK_CASE(parens_qualifier_asterisk_2_benchmark) | ||||||
|         EXPECT_EQ(re.match("aaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbb", m), false); |         EXPECT_EQ(re.match("aaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbb", m), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OTHER) | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
| BENCHMARK_CASE(parens_qualifier_asterisk_2_benchmark_reference_stdcpp_regex_match) | BENCHMARK_CASE(parens_qualifier_asterisk_2_benchmark_reference_stdcpp) | ||||||
| { | { | ||||||
|     std::regex re("test(.*)test"); |     std::regex re("test(.*)test"); | ||||||
|     std::cmatch m; |     std::cmatch m; | ||||||
|  | @ -450,9 +456,9 @@ BENCHMARK_CASE(parens_qualifier_asterisk_2_benchmark_reference_stdcpp_regex_matc | ||||||
|         EXPECT_EQ(std::regex_match("aaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbb", m, re), false); |         EXPECT_EQ(std::regex_match("aaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbb", m, re), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OUR) | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
| BENCHMARK_CASE(multi_parens_qualifier_questionmark_benchmark) | BENCHMARK_CASE(multi_parens_qualifier_questionmark_benchmark) | ||||||
| { | { | ||||||
|     Regex<PosixExtended> re("test(a)?(b)?(c)?test"); |     Regex<PosixExtended> re("test(a)?(b)?(c)?test"); | ||||||
|  | @ -466,10 +472,10 @@ BENCHMARK_CASE(multi_parens_qualifier_questionmark_benchmark) | ||||||
|         EXPECT_EQ(re.match("whaaaaat", m), false); |         EXPECT_EQ(re.match("whaaaaat", m), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OTHER) | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
| BENCHMARK_CASE(multi_parens_qualifier_questionmark_benchmark_reference_stdcpp_regex_match) | BENCHMARK_CASE(multi_parens_qualifier_questionmark_benchmark_reference_stdcpp) | ||||||
| { | { | ||||||
|     std::regex re("test(a)?(b)?(c)?test"); |     std::regex re("test(a)?(b)?(c)?test"); | ||||||
|     std::cmatch m; |     std::cmatch m; | ||||||
|  | @ -482,9 +488,9 @@ BENCHMARK_CASE(multi_parens_qualifier_questionmark_benchmark_reference_stdcpp_re | ||||||
|         EXPECT_EQ(std::regex_match("whaaaaat", m, re), false); |         EXPECT_EQ(std::regex_match("whaaaaat", m, re), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OUR) | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
| BENCHMARK_CASE(simple_alternative_benchmark) | BENCHMARK_CASE(simple_alternative_benchmark) | ||||||
| { | { | ||||||
|     Regex<PosixExtended> re("test|hello|friends"); |     Regex<PosixExtended> re("test|hello|friends"); | ||||||
|  | @ -496,10 +502,10 @@ BENCHMARK_CASE(simple_alternative_benchmark) | ||||||
|         EXPECT_EQ(re.match("whaaaaat", m), false); |         EXPECT_EQ(re.match("whaaaaat", m), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OTHER) | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
| BENCHMARK_CASE(simple_alternative_benchmark_reference_stdcpp_regex_match) | BENCHMARK_CASE(simple_alternative_benchmark_reference_stdcpp) | ||||||
| { | { | ||||||
|     std::regex re("test|hello|friends"); |     std::regex re("test|hello|friends"); | ||||||
|     std::cmatch m; |     std::cmatch m; | ||||||
|  | @ -510,9 +516,9 @@ BENCHMARK_CASE(simple_alternative_benchmark_reference_stdcpp_regex_match) | ||||||
|         EXPECT_EQ(std::regex_match("whaaaaat", m, re), false); |         EXPECT_EQ(std::regex_match("whaaaaat", m, re), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OUR) | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
| BENCHMARK_CASE(alternative_match_groups_benchmark) | BENCHMARK_CASE(alternative_match_groups_benchmark) | ||||||
| { | { | ||||||
|     Regex<PosixExtended> re("test(a)?(b)?|hello ?(dear|my)? friends"); |     Regex<PosixExtended> re("test(a)?(b)?|hello ?(dear|my)? friends"); | ||||||
|  | @ -528,10 +534,10 @@ BENCHMARK_CASE(alternative_match_groups_benchmark) | ||||||
|         EXPECT_EQ(re.match("hello test friends", m), false); |         EXPECT_EQ(re.match("hello test friends", m), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OTHER) | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
| BENCHMARK_CASE(alternative_match_groups_benchmark_reference_stdcpp_regex_match) | BENCHMARK_CASE(alternative_match_groups_benchmark_reference_stdcpp) | ||||||
| { | { | ||||||
|     std::regex re("test(a)?(b)?|hello ?(dear|my)? friends"); |     std::regex re("test(a)?(b)?|hello ?(dear|my)? friends"); | ||||||
|     std::cmatch m; |     std::cmatch m; | ||||||
|  | @ -546,9 +552,9 @@ BENCHMARK_CASE(alternative_match_groups_benchmark_reference_stdcpp_regex_match) | ||||||
|         EXPECT_EQ(std::regex_match("hello test friends", m, re), false); |         EXPECT_EQ(std::regex_match("hello test friends", m, re), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OUR) | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
| BENCHMARK_CASE(parens_qualifier_exact_benchmark) | BENCHMARK_CASE(parens_qualifier_exact_benchmark) | ||||||
| { | { | ||||||
|     Regex<PosixExtended> re("(hello){3}"); |     Regex<PosixExtended> re("(hello){3}"); | ||||||
|  | @ -560,10 +566,10 @@ BENCHMARK_CASE(parens_qualifier_exact_benchmark) | ||||||
|         EXPECT_EQ(re.search("test hellohellohello", m), true); |         EXPECT_EQ(re.search("test hellohellohello", m), true); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OTHER) | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
| BENCHMARK_CASE(parens_qualifier_exact_benchmark_reference_stdcpp_regex_match) | BENCHMARK_CASE(parens_qualifier_exact_benchmark_reference_stdcpp) | ||||||
| { | { | ||||||
|     std::regex re("(hello){3}"); |     std::regex re("(hello){3}"); | ||||||
|     std::cmatch m; |     std::cmatch m; | ||||||
|  | @ -574,9 +580,9 @@ BENCHMARK_CASE(parens_qualifier_exact_benchmark_reference_stdcpp_regex_match) | ||||||
|         EXPECT_EQ(std::regex_search("test hellohellohello", m, re), true); |         EXPECT_EQ(std::regex_search("test hellohellohello", m, re), true); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OUR) | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
| BENCHMARK_CASE(parens_qualifier_minimum_benchmark) | BENCHMARK_CASE(parens_qualifier_minimum_benchmark) | ||||||
| { | { | ||||||
|     Regex<PosixExtended> re("(hello){3,}"); |     Regex<PosixExtended> re("(hello){3,}"); | ||||||
|  | @ -589,10 +595,10 @@ BENCHMARK_CASE(parens_qualifier_minimum_benchmark) | ||||||
|         EXPECT_EQ(re.search("test hellohellohellohello", m), true); |         EXPECT_EQ(re.search("test hellohellohellohello", m), true); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OTHER) | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
| BENCHMARK_CASE(parens_qualifier_minimum_benchmark_reference_stdcpp_regex_match) | BENCHMARK_CASE(parens_qualifier_minimum_benchmark_reference_stdcpp) | ||||||
| { | { | ||||||
|     std::regex re("(hello){3,}"); |     std::regex re("(hello){3,}"); | ||||||
|     std::cmatch m; |     std::cmatch m; | ||||||
|  | @ -604,9 +610,9 @@ BENCHMARK_CASE(parens_qualifier_minimum_benchmark_reference_stdcpp_regex_match) | ||||||
|         EXPECT_EQ(std::regex_search("test hellohellohellohello", m, re), true); |         EXPECT_EQ(std::regex_search("test hellohellohellohello", m, re), true); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OUR) | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
| BENCHMARK_CASE(parens_qualifier_maximum_benchmark) | BENCHMARK_CASE(parens_qualifier_maximum_benchmark) | ||||||
| { | { | ||||||
|     Regex<PosixExtended> re("(hello){2,3}"); |     Regex<PosixExtended> re("(hello){2,3}"); | ||||||
|  | @ -621,10 +627,10 @@ BENCHMARK_CASE(parens_qualifier_maximum_benchmark) | ||||||
|         EXPECT_EQ(re.search("test hellohellohellohello", m), true); |         EXPECT_EQ(re.search("test hellohellohellohello", m), true); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OTHER) | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
| BENCHMARK_CASE(parens_qualifier_maximum_benchmark_reference_stdcpp_regex_match) | BENCHMARK_CASE(parens_qualifier_maximum_benchmark_reference_stdcpp) | ||||||
| { | { | ||||||
|     std::regex re("(hello){2,3}"); |     std::regex re("(hello){2,3}"); | ||||||
|     std::cmatch m; |     std::cmatch m; | ||||||
|  | @ -638,9 +644,9 @@ BENCHMARK_CASE(parens_qualifier_maximum_benchmark_reference_stdcpp_regex_match) | ||||||
|         EXPECT_EQ(std::regex_search("test hellohellohellohello", m, re), true); |         EXPECT_EQ(std::regex_search("test hellohellohellohello", m, re), true); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OUR) | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
| BENCHMARK_CASE(char_qualifier_min_max_benchmark) | BENCHMARK_CASE(char_qualifier_min_max_benchmark) | ||||||
| { | { | ||||||
|     Regex<PosixExtended> re("c{3,30}"); |     Regex<PosixExtended> re("c{3,30}"); | ||||||
|  | @ -654,10 +660,10 @@ BENCHMARK_CASE(char_qualifier_min_max_benchmark) | ||||||
|         EXPECT_EQ(re.match("cccccccccccccccccccccccccccccccc", m), false); |         EXPECT_EQ(re.match("cccccccccccccccccccccccccccccccc", m), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OTHER) | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
| BENCHMARK_CASE(char_qualifier_min_max_benchmark_reference_stdcpp_regex_match) | BENCHMARK_CASE(char_qualifier_min_max_benchmark_reference_stdcpp) | ||||||
| { | { | ||||||
|     std::regex re("c{3,30}"); |     std::regex re("c{3,30}"); | ||||||
|     std::cmatch m; |     std::cmatch m; | ||||||
|  | @ -670,9 +676,9 @@ BENCHMARK_CASE(char_qualifier_min_max_benchmark_reference_stdcpp_regex_match) | ||||||
|         EXPECT_EQ(std::regex_match("cccccccccccccccccccccccccccccccc", m, re), false); |         EXPECT_EQ(std::regex_match("cccccccccccccccccccccccccccccccc", m, re), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OUR) | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
| BENCHMARK_CASE(simple_bracket_chars_benchmark) | BENCHMARK_CASE(simple_bracket_chars_benchmark) | ||||||
| { | { | ||||||
|     Regex<PosixExtended> re("[abc]"); |     Regex<PosixExtended> re("[abc]"); | ||||||
|  | @ -685,10 +691,10 @@ BENCHMARK_CASE(simple_bracket_chars_benchmark) | ||||||
|         EXPECT_EQ(re.match("e", m), false); |         EXPECT_EQ(re.match("e", m), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OTHER) | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
| BENCHMARK_CASE(simple_bracket_chars_benchmark_reference_stdcpp_regex_match) | BENCHMARK_CASE(simple_bracket_chars_benchmark_reference_stdcpp) | ||||||
| { | { | ||||||
|     std::regex re("[abc]"); |     std::regex re("[abc]"); | ||||||
|     std::cmatch m; |     std::cmatch m; | ||||||
|  | @ -700,9 +706,9 @@ BENCHMARK_CASE(simple_bracket_chars_benchmark_reference_stdcpp_regex_match) | ||||||
|         EXPECT_EQ(std::regex_match("e", m, re), false); |         EXPECT_EQ(std::regex_match("e", m, re), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OUR) | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
| BENCHMARK_CASE(simple_bracket_chars_inverse_benchmark) | BENCHMARK_CASE(simple_bracket_chars_inverse_benchmark) | ||||||
| { | { | ||||||
|     Regex<PosixExtended> re("[^abc]"); |     Regex<PosixExtended> re("[^abc]"); | ||||||
|  | @ -715,10 +721,10 @@ BENCHMARK_CASE(simple_bracket_chars_inverse_benchmark) | ||||||
|         EXPECT_EQ(re.match("e", m), true); |         EXPECT_EQ(re.match("e", m), true); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OTHER) | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
| BENCHMARK_CASE(simple_bracket_chars_inverse_benchmark_reference_stdcpp_regex_match) | BENCHMARK_CASE(simple_bracket_chars_inverse_benchmark_reference_stdcpp) | ||||||
| { | { | ||||||
|     std::regex re("[^abc]"); |     std::regex re("[^abc]"); | ||||||
|     std::cmatch m; |     std::cmatch m; | ||||||
|  | @ -730,9 +736,9 @@ BENCHMARK_CASE(simple_bracket_chars_inverse_benchmark_reference_stdcpp_regex_mat | ||||||
|         EXPECT_EQ(std::regex_match("e", m, re), true); |         EXPECT_EQ(std::regex_match("e", m, re), true); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OUR) | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
| BENCHMARK_CASE(simple_bracket_chars_range_benchmark) | BENCHMARK_CASE(simple_bracket_chars_range_benchmark) | ||||||
| { | { | ||||||
|     Regex<PosixExtended> re("[a-d]"); |     Regex<PosixExtended> re("[a-d]"); | ||||||
|  | @ -745,10 +751,10 @@ BENCHMARK_CASE(simple_bracket_chars_range_benchmark) | ||||||
|         EXPECT_EQ(re.match("e", m), false); |         EXPECT_EQ(re.match("e", m), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OTHER) | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
| BENCHMARK_CASE(simple_bracket_chars_range_benchmark_reference_stdcpp_regex_match) | BENCHMARK_CASE(simple_bracket_chars_range_benchmark_reference_stdcpp) | ||||||
| { | { | ||||||
|     std::regex re("[a-d]"); |     std::regex re("[a-d]"); | ||||||
|     std::cmatch m; |     std::cmatch m; | ||||||
|  | @ -760,9 +766,9 @@ BENCHMARK_CASE(simple_bracket_chars_range_benchmark_reference_stdcpp_regex_match | ||||||
|         EXPECT_EQ(std::regex_match("e", m, re), false); |         EXPECT_EQ(std::regex_match("e", m, re), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OUR) | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
| BENCHMARK_CASE(simple_bracket_chars_range_inverse_benchmark) | BENCHMARK_CASE(simple_bracket_chars_range_inverse_benchmark) | ||||||
| { | { | ||||||
|     Regex<PosixExtended> re("[^a-df-z]"); |     Regex<PosixExtended> re("[^a-df-z]"); | ||||||
|  | @ -777,10 +783,10 @@ BENCHMARK_CASE(simple_bracket_chars_range_inverse_benchmark) | ||||||
|         EXPECT_EQ(re.match("z", m), false); |         EXPECT_EQ(re.match("z", m), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OTHER) | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
| BENCHMARK_CASE(simple_bracket_chars_range_inverse_benchmark_reference_stdcpp_regex_match) | BENCHMARK_CASE(simple_bracket_chars_range_inverse_benchmark_reference_stdcpp) | ||||||
| { | { | ||||||
|     std::regex re("[^a-df-z]"); |     std::regex re("[^a-df-z]"); | ||||||
|     std::cmatch m; |     std::cmatch m; | ||||||
|  | @ -794,9 +800,9 @@ BENCHMARK_CASE(simple_bracket_chars_range_inverse_benchmark_reference_stdcpp_reg | ||||||
|         EXPECT_EQ(std::regex_match("z", m, re), false); |         EXPECT_EQ(std::regex_match("z", m, re), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OUR) | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
| BENCHMARK_CASE(bracket_character_class_uuid_benchmark) | BENCHMARK_CASE(bracket_character_class_uuid_benchmark) | ||||||
| { | { | ||||||
|     Regex<PosixExtended> re("^([[:xdigit:]]{8})-([[:xdigit:]]{4})-([[:xdigit:]]{4})-([[:xdigit:]]{4})-([[:xdigit:]]{12})$"); |     Regex<PosixExtended> re("^([[:xdigit:]]{8})-([[:xdigit:]]{4})-([[:xdigit:]]{4})-([[:xdigit:]]{4})-([[:xdigit:]]{12})$"); | ||||||
|  | @ -806,10 +812,10 @@ BENCHMARK_CASE(bracket_character_class_uuid_benchmark) | ||||||
|         EXPECT_EQ(re.match("fb9b62a2", m), false); |         EXPECT_EQ(re.match("fb9b62a2", m), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OTHER) | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
| BENCHMARK_CASE(bracket_character_class_uuid_benchmark_reference_stdcpp_regex_match) | BENCHMARK_CASE(bracket_character_class_uuid_benchmark_reference_stdcpp) | ||||||
| { | { | ||||||
|     std::regex re("^([[:xdigit:]]{8})-([[:xdigit:]]{4})-([[:xdigit:]]{4})-([[:xdigit:]]{4})-([[:xdigit:]]{12})$"); |     std::regex re("^([[:xdigit:]]{8})-([[:xdigit:]]{4})-([[:xdigit:]]{4})-([[:xdigit:]]{4})-([[:xdigit:]]{12})$"); | ||||||
|     std::cmatch m; |     std::cmatch m; | ||||||
|  | @ -818,9 +824,9 @@ BENCHMARK_CASE(bracket_character_class_uuid_benchmark_reference_stdcpp_regex_mat | ||||||
|         EXPECT_EQ(std::regex_match("fb9b62a2", m, re), false); |         EXPECT_EQ(std::regex_match("fb9b62a2", m, re), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OUR) | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
| BENCHMARK_CASE(simple_bracket_character_class_inverse_benchmark) | BENCHMARK_CASE(simple_bracket_character_class_inverse_benchmark) | ||||||
| { | { | ||||||
|     Regex<PosixExtended> re("[^[:digit:]]"); |     Regex<PosixExtended> re("[^[:digit:]]"); | ||||||
|  | @ -833,10 +839,10 @@ BENCHMARK_CASE(simple_bracket_character_class_inverse_benchmark) | ||||||
|         EXPECT_EQ(re.match("e", m), true); |         EXPECT_EQ(re.match("e", m), true); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OTHER) | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
| BENCHMARK_CASE(simple_bracket_character_class_inverse_benchmark_reference_stdcpp_regex_match) | BENCHMARK_CASE(simple_bracket_character_class_inverse_benchmark_reference_stdcpp) | ||||||
| { | { | ||||||
|     std::regex re("[^[:digit:]]"); |     std::regex re("[^[:digit:]]"); | ||||||
|     std::cmatch m; |     std::cmatch m; | ||||||
|  | @ -848,9 +854,9 @@ BENCHMARK_CASE(simple_bracket_character_class_inverse_benchmark_reference_stdcpp | ||||||
|         EXPECT_EQ(std::regex_match("e", m, re), true); |         EXPECT_EQ(std::regex_match("e", m, re), true); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OUR) | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
| BENCHMARK_CASE(email_address_benchmark) | BENCHMARK_CASE(email_address_benchmark) | ||||||
| { | { | ||||||
|     Regex<PosixExtended> re("^[A-Z0-9a-z._%+-]{1,64}@(?:[A-Za-z0-9-]{1,63}\\.){1,125}[A-Za-z]{2,63}$"); |     Regex<PosixExtended> re("^[A-Z0-9a-z._%+-]{1,64}@(?:[A-Za-z0-9-]{1,63}\\.){1,125}[A-Za-z]{2,63}$"); | ||||||
|  | @ -860,10 +866,10 @@ BENCHMARK_CASE(email_address_benchmark) | ||||||
|         EXPECT_EQ(re.match("this.is.a.very_long_email_address@world.wide.web", m), true); |         EXPECT_EQ(re.match("this.is.a.very_long_email_address@world.wide.web", m), true); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OTHER) | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
| BENCHMARK_CASE(email_address_benchmark_reference_stdcpp_regex_match) | BENCHMARK_CASE(email_address_benchmark_reference_stdcpp) | ||||||
| { | { | ||||||
|     std::regex re("^[A-Z0-9a-z._%+-]{1,64}@(?:[A-Za-z0-9-]{1,63}\\.){1,125}[A-Za-z]{2,63}$"); |     std::regex re("^[A-Z0-9a-z._%+-]{1,64}@(?:[A-Za-z0-9-]{1,63}\\.){1,125}[A-Za-z]{2,63}$"); | ||||||
|     std::cmatch m; |     std::cmatch m; | ||||||
|  | @ -872,9 +878,9 @@ BENCHMARK_CASE(email_address_benchmark_reference_stdcpp_regex_match) | ||||||
|         EXPECT_EQ(std::regex_match("this.is.a.very_long_email_address@world.wide.web", m, re), true); |         EXPECT_EQ(std::regex_match("this.is.a.very_long_email_address@world.wide.web", m, re), true); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OUR) | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
| BENCHMARK_CASE(simple_ignorecase_benchmark) | BENCHMARK_CASE(simple_ignorecase_benchmark) | ||||||
| { | { | ||||||
|     Regex<PosixExtended> re("^hello friends", PosixFlags::Insensitive); |     Regex<PosixExtended> re("^hello friends", PosixFlags::Insensitive); | ||||||
|  | @ -890,10 +896,10 @@ BENCHMARK_CASE(simple_ignorecase_benchmark) | ||||||
|         EXPECT_EQ(re.search("hell Friends", m), false); |         EXPECT_EQ(re.search("hell Friends", m), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
| 
 | 
 | ||||||
| #if defined(REGEX_BENCHMARK_OTHER) | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
| BENCHMARK_CASE(simple_ignorecase_benchmark_reference_stdcpp_regex_match) | BENCHMARK_CASE(simple_ignorecase_benchmark_reference_stdcpp) | ||||||
| { | { | ||||||
|     std::regex re("^hello friends", std::regex_constants::icase); |     std::regex re("^hello friends", std::regex_constants::icase); | ||||||
|     std::cmatch m; |     std::cmatch m; | ||||||
|  | @ -908,7 +914,78 @@ BENCHMARK_CASE(simple_ignorecase_benchmark_reference_stdcpp_regex_match) | ||||||
|         EXPECT_EQ(std::regex_search("hell Friends", m, re), false); |         EXPECT_EQ(std::regex_search("hell Friends", m, re), false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| #endif | #    endif | ||||||
|  | 
 | ||||||
|  | #    if defined(REGEX_BENCHMARK_OUR) | ||||||
|  | BENCHMARK_CASE(simple_notbol_noteol_benchmark) | ||||||
|  | { | ||||||
|  |     String pattern = "^hello friends$"; | ||||||
|  |     String pattern2 = "hello friends"; | ||||||
|  |     regex_t regex, regex2; | ||||||
|  | 
 | ||||||
|  |     EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED | REG_NOSUB | REG_ICASE), REG_NOERR); | ||||||
|  |     EXPECT_EQ(regcomp(®ex2, pattern2.characters(), REG_EXTENDED | REG_NOSUB | REG_ICASE), REG_NOERR); | ||||||
|  | 
 | ||||||
|  |     for (size_t i = 0; i < BENCHMARK_LOOP_ITERATIONS; ++i) { | ||||||
|  | 
 | ||||||
|  |         EXPECT_EQ(regexec(®ex, "hello friends", 0, NULL, REG_NOTBOL), REG_NOMATCH); | ||||||
|  |         EXPECT_EQ(regexec(®ex, "hello friends", 0, NULL, REG_NOTEOL), REG_NOMATCH); | ||||||
|  |         EXPECT_EQ(regexec(®ex, "hello friends", 0, NULL, REG_NOTBOL | REG_NOTEOL), REG_NOMATCH); | ||||||
|  | 
 | ||||||
|  |         EXPECT_EQ(regexec(®ex, "a hello friends b", 0, NULL, REG_NOTBOL), REG_NOMATCH); | ||||||
|  |         EXPECT_EQ(regexec(®ex, "a hello friends", 0, NULL, REG_NOTBOL), REG_NOMATCH); | ||||||
|  |         EXPECT_EQ(regexec(®ex, "a hello friends", 0, NULL, REG_NOTBOL | REG_SEARCH), REG_NOERR); | ||||||
|  |         EXPECT_EQ(regexec(®ex, "a hello friends b", 0, NULL, REG_NOTBOL | REG_SEARCH), REG_NOERR); | ||||||
|  | 
 | ||||||
|  |         EXPECT_EQ(regexec(®ex, "a hello friends b", 0, NULL, REG_NOTEOL), REG_NOMATCH); | ||||||
|  |         EXPECT_EQ(regexec(®ex, "hello friends b", 0, NULL, REG_NOTEOL), REG_NOMATCH); | ||||||
|  |         EXPECT_EQ(regexec(®ex, "hello friends b", 0, NULL, REG_NOTEOL | REG_SEARCH), REG_NOERR); | ||||||
|  |         EXPECT_EQ(regexec(®ex, "a hello friends b", 0, NULL, REG_NOTEOL | REG_SEARCH), REG_NOMATCH); | ||||||
|  | 
 | ||||||
|  |         EXPECT_EQ(regexec(®ex, "a hello friends b", 0, NULL, REG_NOTBOL | REG_NOTEOL), REG_NOMATCH); | ||||||
|  |         EXPECT_EQ(regexec(®ex, "a hello friends b", 0, NULL, REG_NOTBOL | REG_NOTEOL | REG_SEARCH), REG_NOMATCH); | ||||||
|  | 
 | ||||||
|  |         EXPECT_EQ(regexec(®ex2, "hello friends", 0, NULL, REG_NOTBOL), REG_NOMATCH); | ||||||
|  |         EXPECT_EQ(regexec(®ex2, "hello friends", 0, NULL, REG_NOTEOL), REG_NOMATCH); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     regfree(®ex); | ||||||
|  | } | ||||||
|  | #    endif | ||||||
|  | 
 | ||||||
|  | #    if defined(REGEX_BENCHMARK_OTHER) | ||||||
|  | BENCHMARK_CASE(simple_notbol_noteol_benchmark_reference_stdcpp) | ||||||
|  | { | ||||||
|  |     std::regex re1("^hello friends$", std::regex_constants::match_not_bol); | ||||||
|  |     std::regex re2("^hello friends$", std::regex_constants::match_not_eol); | ||||||
|  |     std::regex re3("^hello friends$", std::regex_constants::match_not_bol | std::regex_constants::match_not_eol); | ||||||
|  |     std::regex re4("hello friends", std::regex_constants::match_not_bol); | ||||||
|  |     std::regex re5("hello friends", std::regex_constants::match_not_eol); | ||||||
|  |     std::cmatch m; | ||||||
|  |     for (size_t i = 0; i < BENCHMARK_LOOP_ITERATIONS; ++i) { | ||||||
|  |         EXPECT_EQ(std::regex_match("hello friends", m, re1), false); | ||||||
|  |         EXPECT_EQ(std::regex_match("hello friends", m, re2), false); | ||||||
|  |         EXPECT_EQ(std::regex_match("hello friends", m, re3), false); | ||||||
|  | 
 | ||||||
|  |         EXPECT_EQ(std::regex_match("a hello friends b", m, re1), false); | ||||||
|  |         EXPECT_EQ(std::regex_match("a hello friends", m, re1), false); | ||||||
|  |         EXPECT_EQ(std::regex_search("a hello friends", m, re1), true); | ||||||
|  |         EXPECT_EQ(std::regex_search("a hello friends b", m, re1), true); | ||||||
|  | 
 | ||||||
|  |         EXPECT_EQ(std::regex_match("a hello friends b", m, re2), false); | ||||||
|  |         EXPECT_EQ(std::regex_match("hello friends b", m, re2), false); | ||||||
|  |         EXPECT_EQ(std::regex_search("hello friends b", m, re2), true); | ||||||
|  |         EXPECT_EQ(std::regex_search("a hello friends b", m, re2), false); | ||||||
|  | 
 | ||||||
|  |         EXPECT_EQ(std::regex_match("a hello friends b", m, re3), false); | ||||||
|  |         EXPECT_EQ(std::regex_search("a hello friends b", m, re3), false); | ||||||
|  | 
 | ||||||
|  |         EXPECT_EQ(std::regex_match("hello friends", m, re4), false); | ||||||
|  |         EXPECT_EQ(std::regex_match("hello friends", m, re5), false); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | #    endif | ||||||
|  | 
 | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| TEST_MAIN(Regex) | TEST_MAIN(Regex) | ||||||
|  |  | ||||||
|  | @ -383,7 +383,7 @@ TEST_CASE(ini_file_entries) | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|     EXPECT_EQ(result.matches.at(0).view, "[Window]"); |     EXPECT_EQ(result.matches.at(0).view, "[Window]"); | ||||||
|     EXPECT_EQ(result.capture_group_matches.at(0).at(1).view, "Window"); |     EXPECT_EQ(result.capture_group_matches.at(0).at(0).view, "Window"); | ||||||
|     EXPECT_EQ(result.matches.at(1).view, "Opacity=255"); |     EXPECT_EQ(result.matches.at(1).view, "Opacity=255"); | ||||||
|     EXPECT_EQ(result.matches.at(1).line, 1u); |     EXPECT_EQ(result.matches.at(1).line, 1u); | ||||||
|     EXPECT_EQ(result.matches.at(1).column, 0u); |     EXPECT_EQ(result.matches.at(1).column, 0u); | ||||||
|  | @ -396,6 +396,20 @@ TEST_CASE(ini_file_entries) | ||||||
|     EXPECT_EQ(result.capture_group_matches.at(2).at(0).column, 12u); |     EXPECT_EQ(result.capture_group_matches.at(2).at(0).column, 12u); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | TEST_CASE(ini_file_entries2) | ||||||
|  | { | ||||||
|  |     Regex<PosixExtended> re("[[:alpha:]]*=([[:digit:]]*)"); | ||||||
|  |     RegexResult result; | ||||||
|  | 
 | ||||||
|  |     String haystack = "ViewMode=Icon"; | ||||||
|  | 
 | ||||||
|  |     EXPECT_EQ(re.match(haystack.view(), result), false); | ||||||
|  |     EXPECT_EQ(result.count, 0u); | ||||||
|  | 
 | ||||||
|  |     EXPECT_EQ(re.search(haystack.view(), result), true); | ||||||
|  |     EXPECT_EQ(result.count, 1u); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| TEST_CASE(named_capture_group) | TEST_CASE(named_capture_group) | ||||||
| { | { | ||||||
|     Regex<PosixExtended> re("[[:alpha:]]*=(?<Test>[[:digit:]]*)"); |     Regex<PosixExtended> re("[[:alpha:]]*=(?<Test>[[:digit:]]*)"); | ||||||
|  |  | ||||||
|  | @ -30,13 +30,6 @@ | ||||||
| #include <LibC/regex.h> | #include <LibC/regex.h> | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| 
 | 
 | ||||||
| #define BENCHMARK_LOOP_ITERATIONS 100000 |  | ||||||
| #define DISABLE_REGEX_BENCHMARK |  | ||||||
| 
 |  | ||||||
| //#if not(defined(REGEX_DEBUG) || defined(REGEX_MATCH_STATUS) || defined(DISABLE_REGEX_BENCHMARK))
 |  | ||||||
| #    include <regex> |  | ||||||
| //#endif
 |  | ||||||
| 
 |  | ||||||
| TEST_CASE(catch_all) | TEST_CASE(catch_all) | ||||||
| { | { | ||||||
|     String pattern = "^.*$"; |     String pattern = "^.*$"; | ||||||
|  | @ -1115,9 +1108,11 @@ TEST_CASE(simple_ignorecase) | ||||||
| TEST_CASE(simple_notbol_noteol) | TEST_CASE(simple_notbol_noteol) | ||||||
| { | { | ||||||
|     String pattern = "^hello friends$"; |     String pattern = "^hello friends$"; | ||||||
|     regex_t regex; |     String pattern2 = "hello friends"; | ||||||
|  |     regex_t regex, regex2; | ||||||
| 
 | 
 | ||||||
|     EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED | REG_NOSUB | REG_ICASE), REG_NOERR); |     EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED | REG_NOSUB | REG_ICASE), REG_NOERR); | ||||||
|  |     EXPECT_EQ(regcomp(®ex2, pattern2.characters(), REG_EXTENDED | REG_NOSUB | REG_ICASE), REG_NOERR); | ||||||
| 
 | 
 | ||||||
|     EXPECT_EQ(regexec(®ex, "hello friends", 0, NULL, REG_NOTBOL), REG_NOMATCH); |     EXPECT_EQ(regexec(®ex, "hello friends", 0, NULL, REG_NOTBOL), REG_NOMATCH); | ||||||
|     EXPECT_EQ(regexec(®ex, "hello friends", 0, NULL, REG_NOTEOL), REG_NOMATCH); |     EXPECT_EQ(regexec(®ex, "hello friends", 0, NULL, REG_NOTEOL), REG_NOMATCH); | ||||||
|  | @ -1136,76 +1131,10 @@ TEST_CASE(simple_notbol_noteol) | ||||||
|     EXPECT_EQ(regexec(®ex, "a hello friends b", 0, NULL, REG_NOTBOL | REG_NOTEOL), REG_NOMATCH); |     EXPECT_EQ(regexec(®ex, "a hello friends b", 0, NULL, REG_NOTBOL | REG_NOTEOL), REG_NOMATCH); | ||||||
|     EXPECT_EQ(regexec(®ex, "a hello friends b", 0, NULL, REG_NOTBOL | REG_NOTEOL | REG_SEARCH), REG_NOMATCH); |     EXPECT_EQ(regexec(®ex, "a hello friends b", 0, NULL, REG_NOTBOL | REG_NOTEOL | REG_SEARCH), REG_NOMATCH); | ||||||
| 
 | 
 | ||||||
|     pattern = "hello friends"; |     EXPECT_EQ(regexec(®ex2, "hello friends", 0, NULL, REG_NOTBOL), REG_NOMATCH); | ||||||
|     EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED | REG_NOSUB | REG_ICASE), REG_NOERR); |     EXPECT_EQ(regexec(®ex2, "hello friends", 0, NULL, REG_NOTEOL), REG_NOMATCH); | ||||||
| 
 |  | ||||||
|     EXPECT_EQ(regexec(®ex, "hello friends", 0, NULL, REG_NOTBOL), REG_NOMATCH); |  | ||||||
|     EXPECT_EQ(regexec(®ex, "hello friends", 0, NULL, REG_NOTEOL), REG_NOMATCH); |  | ||||||
| 
 | 
 | ||||||
|     regfree(®ex); |     regfree(®ex); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| //#if not(defined(REGEX_DEBUG) || defined(REGEX_MATCH_STATUS) || defined(DISABLE_REGEX_BENCHMARK))
 |  | ||||||
| //BENCHMARK_CASE(simple_notbol_noteol_benchmark)
 |  | ||||||
| //{
 |  | ||||||
| //    String pattern = "^hello friends$";
 |  | ||||||
| //    regex_t regex;
 |  | ||||||
| 
 |  | ||||||
| //    EXPECT_EQ(regcomp(®ex, pattern.characters(), REG_EXTENDED | REG_NOSUB | REG_ICASE), REG_NOERR);
 |  | ||||||
| 
 |  | ||||||
| //    for (size_t i = 0; i < BENCHMARK_LOOP_ITERATIONS; ++i) {
 |  | ||||||
| 
 |  | ||||||
| //        EXPECT_EQ(regexec(®ex, "hello friends", 0, NULL, REG_NOTBOL), REG_NOMATCH);
 |  | ||||||
| //        EXPECT_EQ(regexec(®ex, "hello friends", 0, NULL, REG_NOTEOL), REG_NOMATCH);
 |  | ||||||
| //        EXPECT_EQ(regexec(®ex, "hello friends", 0, NULL, REG_NOTBOL | REG_NOTEOL), REG_NOMATCH);
 |  | ||||||
| 
 |  | ||||||
| //        EXPECT_EQ(regexec(®ex, "a hello friends b", 0, NULL, REG_NOTBOL), REG_NOMATCH);
 |  | ||||||
| //        EXPECT_EQ(regexec(®ex, "a hello friends", 0, NULL, REG_NOTBOL), REG_NOMATCH);
 |  | ||||||
| //        EXPECT_EQ(regexec(®ex, "a hello friends", 0, NULL, REG_NOTBOL | REG_SEARCH), REG_NOERR);
 |  | ||||||
| //        EXPECT_EQ(regexec(®ex, "a hello friends b", 0, NULL, REG_NOTBOL | REG_SEARCH), REG_NOMATCH);
 |  | ||||||
| 
 |  | ||||||
| //        EXPECT_EQ(regexec(®ex, "a hello friends b", 0, NULL, REG_NOTEOL), REG_NOMATCH);
 |  | ||||||
| //        EXPECT_EQ(regexec(®ex, "hello friends b", 0, NULL, REG_NOTEOL), REG_NOMATCH);
 |  | ||||||
| //        EXPECT_EQ(regexec(®ex, "hello friends b", 0, NULL, REG_NOTEOL | REG_SEARCH), REG_NOERR);
 |  | ||||||
| //        EXPECT_EQ(regexec(®ex, "a hello friends b", 0, NULL, REG_NOTEOL | REG_SEARCH), REG_NOMATCH);
 |  | ||||||
| 
 |  | ||||||
| //        EXPECT_EQ(regexec(®ex, "a hello friends b", 0, NULL, REG_NOTBOL | REG_NOTEOL), REG_NOMATCH);
 |  | ||||||
| //        EXPECT_EQ(regexec(®ex, "a hello friends b", 0, NULL, REG_NOTBOL | REG_NOTEOL | REG_SEARCH), REG_NOERR);
 |  | ||||||
| //    }
 |  | ||||||
| 
 |  | ||||||
| //    regfree(®ex);
 |  | ||||||
| //}
 |  | ||||||
| 
 |  | ||||||
| BENCHMARK_CASE(simple_notbol_noteol_benchmark_reference_stdcpp_regex_match) |  | ||||||
| { |  | ||||||
|     std::regex re1("^hello friends$", std::regex_constants::match_not_bol); |  | ||||||
|     std::regex re2("^hello friends$", std::regex_constants::match_not_eol); |  | ||||||
|     std::regex re3("^hello friends$", std::regex_constants::match_not_bol | std::regex_constants::match_not_eol); |  | ||||||
|     std::regex re4("hello friends", std::regex_constants::match_not_bol); |  | ||||||
|     std::regex re5("hello friends", std::regex_constants::match_not_eol); |  | ||||||
|     std::cmatch m; |  | ||||||
|     //for (size_t i = 0; i < BENCHMARK_LOOP_ITERATIONS; ++i) {
 |  | ||||||
|     EXPECT_EQ(std::regex_match("hello friends", m, re1), false); |  | ||||||
|     EXPECT_EQ(std::regex_match("hello friends", m, re2), false); |  | ||||||
|     EXPECT_EQ(std::regex_match("hello friends", m, re3), false); |  | ||||||
| 
 |  | ||||||
|     EXPECT_EQ(std::regex_match("a hello friends b", m, re1), false); |  | ||||||
|     EXPECT_EQ(std::regex_match("a hello friends", m, re1), false); |  | ||||||
|     EXPECT_EQ(std::regex_search("a hello friends", m, re1), true); |  | ||||||
|     EXPECT_EQ(std::regex_search("a hello friends b", m, re1), true); |  | ||||||
| 
 |  | ||||||
|     EXPECT_EQ(std::regex_match("a hello friends b", m, re2), false); |  | ||||||
|     EXPECT_EQ(std::regex_match("hello friends b", m, re2), false); |  | ||||||
|     EXPECT_EQ(std::regex_search("hello friends b", m, re2), true); |  | ||||||
|     EXPECT_EQ(std::regex_search("a hello friends b", m, re2), false); |  | ||||||
| 
 |  | ||||||
|     EXPECT_EQ(std::regex_match("a hello friends b", m, re3), false); |  | ||||||
|     EXPECT_EQ(std::regex_search("a hello friends b", m, re3), false); |  | ||||||
| 
 |  | ||||||
|     EXPECT_EQ(std::regex_match("hello friends", m, re4), false); |  | ||||||
|     EXPECT_EQ(std::regex_match("hello friends", m, re5), false); |  | ||||||
|     //}
 |  | ||||||
| } |  | ||||||
| //#endif
 |  | ||||||
| 
 |  | ||||||
| TEST_MAIN(Regex) | TEST_MAIN(Regex) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Emanuel Sprung
						Emanuel Sprung