CodeNebula
C++20stladvanced

std::views::counted (C++20 Addition)

C++20 · The Big Four · Compiler flag: -std=c++20

Explanation

Creates a view of exactly N elements starting from an iterator. Unlike `take`, it works with raw iterators rather than ranges, producing a `std::span` or `subrange`.

Real-World Scenario

Process a fixed-size chunk from a raw data buffer obtained from a C API.

Quick Snippet

snippet.cpp
#include <ranges>
#include <vector>

std::vector<int> data = {10, 20, 30, 40, 50};
auto chunk = std::views::counted(data.begin() + 1, 3);
// Yields: 20, 30, 40

Full Example

ranges_counted_view.cpp
// CodeNebula - C++20 Example: std::views::counted
// Compile: g++ -std=c++20 -Wall -Wextra -o example ranges_counted_view.cpp

#include <ranges>
#include <vector>
#include <list>
#include <iterator>
#include <algorithm>
#include <iostream>

// std::views::counted creates a view from an iterator and a count,
// producing a span-like subrange of exactly N elements starting
// from the given position.

int main() {
    std::vector<int> vec = {10, 20, 30, 40, 50, 60, 70, 80};

    // Create a counted view: 4 elements starting at index 2
    auto sub = std::views::counted(vec.begin() + 2, 4);
    std::cout << "Counted(begin+2, 4): ";
    for (int n : sub) std::cout << n << " ";
    std::cout << "\n";  // Output: 30 40 50 60

    // Counted from beginning
    auto first3 = std::views::counted(vec.begin(), 3);
    std::cout << "First 3: ";
    for (int n : first3) std::cout << n << " ";
    std::cout << "\n";

    // Works with raw pointers
    int arr[] = {1, 2, 3, 4, 5, 6};
    auto from_ptr = std::views::counted(arr + 1, 3);
    std::cout << "From pointer: ";
    for (int n : from_ptr) std::cout << n << " ";
    std::cout << "\n";  // Output: 2 3 4

    // Works with non-random-access iterators (e.g., list)
    std::list<int> lst = {100, 200, 300, 400, 500};
    auto lst_sub = std::views::counted(std::next(lst.begin()), 3);
    std::cout << "List counted: ";
    for (int n : lst_sub) std::cout << n << " ";
    std::cout << "\n";  // Output: 200 300 400

    // Counted view is sized
    std::cout << "Counted size: " << std::ranges::size(sub) << "\n";

    // Use with algorithms
    auto counted = std::views::counted(vec.begin(), 5);
    auto sum = std::ranges::fold_left(counted, 0, std::plus<>{});
    std::cout << "Sum of first 5: " << sum << "\n";

    // Combine with other views
    auto filtered = std::views::counted(vec.begin(), 6)
        | std::views::filter([](int n) { return n > 30; });
    std::cout << "Counted+filtered: ";
    for (int n : filtered) std::cout << n << " ";
    std::cout << "\n";

    // Useful for processing chunks of raw data
    std::vector<double> data = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6};
    for (std::size_t i = 0; i + 2 <= data.size(); i += 2) {
        auto chunk = std::views::counted(data.begin() + i, 2);
        std::cout << "Chunk: ";
        for (double d : chunk) std::cout << d << " ";
        std::cout << "\n";
    }

    return 0;
}
Run command
g++ -std=c++20 -Wall -Wextra -o example ranges_counted_view.cpp