C++ Ranges

starting from c++ std 20 you can ranges STL library is coming up

first example


    #include "ranges"

    auto const ints =std::vector<int>{0,1,2,3,4,5};
    auto even = [](int i) { return 0 == i % 2; };
    auto square = [](int i) { return i * i; };

    auto res=ints | std::views::filter(even) | std::views::transform(square);
    for(const int& v : res){
        qDebug()<<v;
    }

the ranges it executed once start iterate it this in c++ std but in ranges-v3 you have to use ranges::views::indirect

auto vec=v::iota(-100,100)|v::take(10)|v::filter([](int val)->bool{return true;})|v::transform([](int val)->int{qDebug()<<val;return abs(val);});
    for (int i : vec) {
        qDebug()<< i ;
    }

-100 100
-99 99
-98 98
-97 97
-96 96
-95 95
-94 94
-93 93
-92 92
-91 91

zip ranges

    std::vector<int> vals{1,2,3,4,5,6};
    std::vector<int> vals2{11,22,33};
    auto res2=ranges::views::zip(vals,vals2);
    for(auto [val1,val2] : res2)
        std::cout<<val1<<":"<<val2<<std::endl;
//1:11   2:22   3:33

convert the output to vector

auto res=vals|ranges::views::take(5)|ranges::to<std::vector<int>>();

cycle the ranges

    std::vector<int> values{343,35,45,324,5,4};
    ranges::sort(values);//4 5 35 45 324 343
    auto res=values|ranges::views::take(100)|ranges::views::all|ranges::views::transform([](int v){ return v+45; })|ranges::to<std::vector<int>>();
    auto res2=res|ranges::views::cycle|ranges::views::take(10); //49 50 80 90 369 388 49 50 80 90 

Generate and accumilate

auto vi = views::for_each(views::ints(1, 6), [](int i) { return yield_from(views::repeat_n(i, i)); }) |to<std::vector>();
    // prints: [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5]
int sum = accumulate(views::ints(1, unreachable) | views::transform([](int i) {
                             return i * i;
                         }) | views::take(10),
                         0);
    // prints: 385

Actions

std::vector<int> vi{9, 4, 5, 2, 9, 1, 0, 2, 6, 7, 4, 5, 6, 5, 9, 2, 7,
                        1, 4, 5, 3, 8, 5, 0, 2, 9, 3, 7, 5, 7, 5, 5, 6, 1,
                        4, 3, 1, 8, 4, 0, 7, 8, 8, 2, 6, 5, 3, 4, 5};
    using namespace ranges;
    vi |= actions::sort | actions::unique;
    // prints: [0,1,2,3,4,5,6,7,8,9]