diff --git a/include/omath/utility/pattern_scan.hpp b/include/omath/utility/pattern_scan.hpp index c24e778..781c344 100644 --- a/include/omath/utility/pattern_scan.hpp +++ b/include/omath/utility/pattern_scan.hpp @@ -5,9 +5,9 @@ #pragma once #include #include +#include #include #include -#include // ReSharper disable once CppInconsistentNaming class unit_test_pattern_scan_read_test_Test; @@ -20,7 +20,6 @@ class unit_test_pattern_scan_corner_case_3_Test; // ReSharper disable once CppInconsistentNaming class unit_test_pattern_scan_corner_case_4_Test; - namespace omath { enum class PatternScanError @@ -34,10 +33,42 @@ namespace omath friend unit_test_pattern_scan_corner_case_2_Test; friend unit_test_pattern_scan_corner_case_3_Test; friend unit_test_pattern_scan_corner_case_4_Test; + public: [[nodiscard]] - static std::optional::const_iterator> - scan_for_pattern(const std::string_view& pattern, const std::span& range); + static std::optional::const_iterator> scan_for_pattern(const std::span& range, + const std::string_view& pattern); + + template + static IteratorType scan_for_pattern(const IteratorType& begin, const IteratorType& end, + const std::string_view& pattern) + { + const auto parsed_pattern = parse_pattern(pattern); + + if (!parsed_pattern) [[unlikely]] + return end; + + const auto whole_range_size = static_cast(std::distance(begin, end)); + + const std::ptrdiff_t scan_size = whole_range_size - static_cast(pattern.size()); + + for (std::ptrdiff_t i = 0; i < scan_size; i++) + { + bool found = true; + + for (std::ptrdiff_t j = 0; j < static_cast(parsed_pattern->size()); j++) + { + found = parsed_pattern->at(j) == std::nullopt || parsed_pattern->at(j) == *(begin + i + j); + + if (!found) + break; + } + if (found) + return begin + i; + } + return end; + } + private: [[nodiscard]] static std::expected>, PatternScanError> diff --git a/source/utility/pattern_scan.cpp b/source/utility/pattern_scan.cpp index 15ca8a2..cf19cc3 100644 --- a/source/utility/pattern_scan.cpp +++ b/source/utility/pattern_scan.cpp @@ -8,31 +8,14 @@ namespace omath { std::optional::const_iterator> - PatternScanner::scan_for_pattern(const std::string_view& pattern, const std::span& range) + PatternScanner::scan_for_pattern(const std::span& range, const std::string_view& pattern) { - const auto parsed_pattern = parse_pattern(pattern); + auto result = scan_for_pattern(range.begin(), range.end(), pattern); - if (!parsed_pattern) [[unlikely]] + if (result == range.end()) return std::nullopt; - const std::ptrdiff_t scan_size = - static_cast(range.size()) - static_cast(pattern.size()); - - for (std::ptrdiff_t i = 0; i < scan_size; i++) - { - bool found = true; - - for (std::ptrdiff_t j = 0; j < static_cast(parsed_pattern->size()); j++) - { - found = parsed_pattern->at(j) == std::nullopt || parsed_pattern->at(j) == *(range.data() + i + j); - - if (!found) - break; - } - if (found) - return range.begin() + i; - } - return std::nullopt; + return result; } std::expected>, PatternScanError> PatternScanner::parse_pattern(const std::string_view& pattern_string)