Ch9.10: span and index_span

Overview

::fast_io::span<T> and ::fast_io::index_span<T, N> are non-owning views over contiguous memory. They do not allocate or free memory — they just point to data owned by something else.

1. span<T>

A span is a pointer and a size. Use it as a function parameter type to accept any contiguous container without copying:


#include <fast_io_dsal/span.h>
#include <fast_io_dsal/vector.h>
#include <fast_io_dsal/array.h>
#include <fast_io.h>

// Accepts vector, array, span, C-array - anything contiguous
void print_all(::fast_io::span<::std::size_t const> data) {
    for (auto const& e : data) {
        ::fast_io::io::println(e);
    }
}

int main() {
    ::fast_io::vector<::std::size_t> v{1zu, 2zu, 3zu};
    ::fast_io::array<::std::size_t, 3zu> a{4zu, 5zu, 6zu};

    print_all(::fast_io::span(v.data(), v.size()));
    print_all(::fast_io::span(a.data(), a.size()));
}

Sub-span operations


::fast_io::span<::std::size_t> sp(vec.data(), vec.size());

auto first_half = sp.subspan_front(sp.size() / 2);
auto last_quarter = sp.subspan_back(sp.size() / 4);
auto middle = sp.subspan(1zu, 3zu); // 3 elements starting at index 1

// Unchecked variants for performance-critical code
auto fast_sub = sp.subspan_front_unchecked(5zu);

2. index_span<T, N>

An index_span is a span with a compile-time fixed size. The size N is part of the type, so the compiler can verify it:


#include <fast_io_dsal/index_span.h>
#include <fast_io.h>

// Requires exactly 4 elements
void process_quad(::fast_io::index_span<double, 4zu> quad) {
    for (::std::size_t i{}; i != quad.size(); ++i) {
        ::fast_io::io::println(quad[i]);
    }
}

int main() {
    double coords[]{1.0, 2.0, 3.0, 4.0};
    ::fast_io::index_span<double, 4zu> ispan(
        ::fast_io::containers::index_unchecked,
        coords
    );
    process_quad(ispan);
}

Key takeaways