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]