ericniebler / range-v3

Range library for C++14/17/20, basis for C++20's std::ranges
Other
4.05k stars 437 forks source link

ranges::views::chunk_by and std::views::chunk_by return different results #1821

Closed Arsennnic closed 2 weeks ago

Arsennnic commented 2 weeks ago

I notice that ranges::views::chunk_by and std::views::chunk_by may return different results with a mutable lambda function.

#include <iostream>
#include <vector>
#include <ranges>
#include <range/v3/view/chunk_by.hpp>
#include <fmt/ranges.h>

int main() {
    const auto fun = [i = 0, s = 1](int, int) mutable
    {
        if ( ++i == s)
        {
            i = 0, ++s;
            return false;
        }
        else
        {
            return true;
        }
    };

    std::vector<int> a = {1, 2, 3, 4, 5, 6};
    std::cout << fmt::format("{}\n", a | std::views::chunk_by(fun));    // [[1], [2, 3], [4, 5, 6]]
    std::cout << fmt::format("{}\n", a | ranges::views::chunk_by(fun)); // [[1], [2], [3, 4], [5, 6]]

    return 0;
}

gcc version: 14.1 range-v3 version: 0.12.0

brevzin commented 2 weeks ago

The predicate that you pass to chunk_by has to be equality-preserving - it always has to provide the same output for the same inputs. A mutating function that changes answers like this violates the semantic constraints chunk_by.