auto subsequence_boundary(auto start, auto end,auto pred) { using live_iterator = decltype(start); using distance_t = std::invoke_result_t), live_iterator, decltype(end)>; distance_t distance = std::distance(start, end); if(distance < 1) { return start; } if(distance == 1) { return ++start; } live_iterator next = start; ++next; while(not pred(*start, *next)) { ++start; ++next; if(next == end) return next; } return next; } auto longest_matching_subsequence(auto start, auto end, auto pred) { using live_iterator = decltype(start); using distance_t = std::invoke_result_t), live_iterator, decltype(end)>; live_iterator current = start; struct { live_iterator best_s; live_iterator best_e; } results; results.best_s = start; results.best_e = start; distance_t best_length = 0; while(current != end) { live_iterator next = subsequence_boundary(current, end, pred); distance_t subsequence_length = std::distance(current, next); if(subsequence_length > best_length) { results.best_s = current; results.best_e = next; best_length = subsequence_length; } current = next; } return results; } TEST_CASE("Subsequence") { std::vector list = {0,1,2,3,4,5,0,1,0,2,5,8,7}; auto [s,e] = longest_matching_subsequence(list.begin(), list.end(), std::greater{}); REQUIRE(std::distance(s,e) == 6); }