Range-v3

Language: CPP

CLI/Utils

Range-v3 was created by Eric Niebler to explore and implement ideas for ranges in C++, many of which were later adopted into C++20. It provides a rich set of algorithms, views, and actions that make working with sequences cleaner and more intuitive compared to traditional iterator-based loops.

Range-v3 is a C++ library that extends the standard library with a powerful range-based API. It provides composable, lazy-evaluated views and actions on sequences, enabling expressive and functional-style operations on containers and iterators.

Installation

linux: sudo apt install range-v3-dev
mac: brew install range-v3
windows: Download from https://github.com/ericniebler/range-v3 and include headers in your project

Usage

Range-v3 allows you to create pipelines of range-based operations such as filtering, transforming, and combining sequences. It supports lazy evaluation, composability, and integrates seamlessly with STL containers.

Filtering a range

#include <range/v3/all.hpp>
#include <vector>
#include <iostream>

int main() {
    std::vector<int> numbers{1,2,3,4,5,6};
    for(int i : numbers | ranges::views::filter([](int n){ return n % 2 == 0; }))
        std::cout << i << ' ';
    return 0;
}

Filters a vector to include only even numbers using a range-based view.

Transforming a range

#include <range/v3/all.hpp>
#include <vector>
#include <iostream>

int main() {
    std::vector<int> numbers{1,2,3,4};
    for(int i : numbers | ranges::views::transform([](int n){ return n * n; }))
        std::cout << i << ' ';
    return 0;
}

Transforms a vector by squaring each element using a lazy-evaluated range view.

Chaining multiple views

#include <range/v3/all.hpp>
#include <vector>
#include <iostream>

int main() {
    std::vector<int> numbers{1,2,3,4,5,6,7,8,9,10};
    auto result = numbers
                  | ranges::views::filter([](int n){ return n % 2 == 0; })
                  | ranges::views::transform([](int n){ return n * 10; });
    for(int i : result) std::cout << i << ' ';
    return 0;
}

Demonstrates chaining multiple range operations (filter + transform) in a clean and readable pipeline.

Slicing and dropping elements

#include <range/v3/all.hpp>
#include <vector>
#include <iostream>

int main() {
    std::vector<int> numbers{0,1,2,3,4,5,6,7,8,9};
    auto result = numbers
                  | ranges::views::drop(3)
                  | ranges::views::take(4);
    for(int i : result) std::cout << i << ' ';
    return 0;
}

Skips the first 3 elements and takes the next 4 elements using `drop` and `take` views.

Combining ranges

#include <range/v3/all.hpp>
#include <vector>
#include <iostream>

int main() {
    std::vector<int> a{1,2,3}, b{4,5,6};
    auto combined = ranges::views::concat(a, b);
    for(int i : combined) std::cout << i << ' ';
    return 0;
}

Concatenates two vectors into a single range without creating a new container.

Using action to modify containers

#include <range/v3/all.hpp>
#include <vector>
#include <iostream>

int main() {
    std::vector<int> numbers{1,2,3,4,5};
    numbers |= ranges::actions::reverse;
    for(int i : numbers) std::cout << i << ' ';
    return 0;
}

Reverses a vector in-place using Range-v3 actions.

Error Handling

Compilation errors with iterators: Ensure your container supports the required iterator category for the view or algorithm used.
Concept check failed: Check that types satisfy the range concepts required by the operations (e.g., input_range, forward_range).

Best Practices

Prefer lazy views over creating new containers for performance.

Chain views for readable and expressive pipelines.

Use actions when modifying containers in-place.

Combine with STL algorithms where applicable.

Include only the headers you need to reduce compile times.