#include <iostream> #include <ranges> #include <vector> #include <list> #include <set> #include <deque> namespace views = std::views; // ::std::ranges::views // namespace std { namespace views = ranges::views } auto even = [](auto&& x) { return x & 1; }; auto square = [](auto&& x) { return x * x; }; void test1() { // std::views::filter / transform std::vector arr{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; for (auto&& i : arr | views::filter(even) | views::transform(square)) { std::cout << i << ' '; } // we have filtered even in arr and make rest squared std::endl(std::cout); // output: // 1 9 25 49 81 } void test2() { std::vector arr{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; for (auto&& i : views::all(arr) | views::filter(even) | views::take(5)) { std::cout << i << ' '; } // output: 1, 3, 5, 7, 9 std::endl(std::cout); for (auto&& i : views::all(arr) | views::take(5) | views::filter(even)) { std::cout << i << ' '; } // output: 1, 3, 5 std::endl(std::cout); for (auto&& i : views::reverse(arr)) { std::cout << i << ' '; } // output: 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 std::endl(std::cout); } void test3() { auto zero_to_nine = views::iota(0, 10); // [0, 10) auto nine_to_zero = views::reverse(zero_to_nine); for (auto&& i : zero_to_nine) { std::cout << i << ' '; } // output: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 std::endl(std::cout); for (auto&& i : nine_to_zero) { std::cout << i << ' '; } // 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 std::endl(std::cout); auto to_even = views::transform([](auto&& e){ return 2 * e; }); auto to_odd = views::transform([](auto&& e){ return 2 * e + 1; }); for (auto&& i : zero_to_nine | to_even) { std::cout << i << ' '; } // 0, 2, 4, 6, ..., 16, 18 std::endl(std::cout); for (auto&& i : nine_to_zero | to_odd) { std::cout << i << ' '; } // 19, 17, 15, ..., 5, 3, 1 std::endl(std::cout); } void test4() { using vector_t = std::vector<int>; using list_t = std::list<int>; using set_t = std::set<int>; using deque_t = std::deque<int>; std::cout.setf(std::ios::boolalpha); std::cout << "is vector_t a range? " << std::ranges::range<vector_t> << std::endl; // true std::cout << "is list_t a range? " << std::ranges::range<list_t> << std::endl; // true std::cout << "is set_t a range? " << std::ranges::range<set_t> << std::endl; // true // an array without elements count is an implement type std::cout << "is int[] a range ? " << std::ranges::range<int[]> << std::endl; // false std::cout << "is int[10] a range ? " << std::ranges::range<int[10]> << std::endl; // true std::cout << "is vector_t a random_access_rang? " << std::ranges::random_access_range<vector_t> << std::endl; // true std::cout << "is list_t a random_access_rang? " << std::ranges::random_access_range<list_t> << std::endl; // false std::cout << "is set_t a random_access_rang? " << std::ranges::random_access_range<set_t> << std::endl; // false std::cout << "is deque_t a random_access_rang? " << std::ranges::random_access_range<deque_t> << std::endl; // true std::cout << "is vector_t a contiguous? " << std::ranges::contiguous_range<vector_t> << std::endl; // true std::cout << "is list_t a contiguous? " << std::ranges::contiguous_range<list_t> << std::endl; // false std::cout << "is set_t a contiguous? " << std::ranges::contiguous_range<set_t> << std::endl; // false std::cout << "is deque_t a contiguous? " << std::ranges::contiguous_range<deque_t> << std::endl; // false // contiguous_range requires contiguous memory } int main() { // test1(); // test2(); // test3(); test4(); }