Library / SDK
ericniebler/range-v3 avatar
ericniebler/range-v3

range-v3: the C++ range library that became std::ranges

Range library for C++14/17/20, basis for C++20's std::ranges

4,377 stars468 forksC++NOASSERTION

At a glance

What is it?
range-v3 gives C++14, C++17 and C++20 code lazy views and eager actions on top of iterators. It is the codebase behind P0896R4, and its cpp20 namespace is the part that is meant to stay still.
Who is it for?
Adopt range-v3 if you are on a compiler it lists as supported, you want lazy view pipelines today, and you need the eager actions that std::ranges does not offer. Do not adopt it as a general-purpose library for a codebase that cannot absorb API churn: the README says the code will evolve without regard to backwards compatibility, and only ranges::cpp20 carries a stability promise.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 171 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What range-v3 adds to the STL you already have

The library is an extension of the STL, not a replacement for it. Its stated design keeps iterators and puts a range abstraction layer on top, which separates it from range-like solutions that try to remove iterators altogether. That choice matters for adoption: existing iterator-based code and range-v3 pipelines can coexist in the same translation unit.

The people who get the most from it are writing C++14 or C++17 and cannot use std::ranges yet, or are on C++20 and want pieces the standard library did not take. The README frames the project as the basis of a formal proposal that went through a Technical Specification and became P0896R4, merged into the C++20 working drafts in November 2018. So if you already use std::ranges, you are using a descendant of this code, and the differences are mostly about what stayed behind.

Views, actions and algorithms: the three pillars

The README names three pillars. Algorithms are the STL algorithms you know, except that range-v3 adds overloads taking ranges alongside the iterator overloads. Views are composable adaptations where the adaptation happens lazily as the view is iterated. Actions apply an algorithm eagerly to a container, mutate it in place, and return it for further processing.

That split is the real architecture. A view pipeline does no work until something iterates it, so chaining filters and transforms costs you a type, not a pass over the data. An action is the opposite trade: it commits the work immediately so the container itself changes. Lazy views and eager actions are different tools with different failure modes, and the pipe syntax (the README gives rng | adapt1 | adapt2 | ...) is shared between them so the two read consistently from left to right.

The documentation is described in the README itself as woefully incomplete, and the linked resources are dated with a warning that the library probably has changed since. Practically, that means the headers under include/ and the example/ directory are more reliable than the prose. The example directory contains files such as filter_transform.cpp, sort_unique.cpp, accumulate_ints.cpp and a view/ subdirectory, which is where a new user should look first.

Installing range-v3 with vcpkg or Conan and writing a first pipeline

The README gives two package-manager routes. With vcpkg, the documented sequence clones the vcpkg repository, bootstraps it, integrates it and installs the port:

bash
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install range-v3

The README notes that the vcpkg port is kept up to date by Microsoft team members and community contributors, and points at the vcpkg repository if the version is out of date. Note the release history: the newest release listed is 0.12.0 from 2022-06-21, so a package manager resolving range-v3/[*] may pull a tag that predates the current master branch by several years.

With Conan, the documented CMakeLists.txt links the imported target, and a conanfile.txt declares the dependency with CMakeDeps and CMakeToolchain generators:

cmake
project(myproject CXX)

add_executable(${PROJECT_NAME} main.cpp)
find_package(range-v3 REQUIRED)
target_link_libraries(${PROJECT_NAME} range-v3::range-v3)
code
[requires]
range-v3/[*]

[generators]
CMakeDeps
CMakeToolchain

The README then gives the install and build commands, which place the toolchain file in the build directory:

bash
conan install . --build=missing --output-folder=build
cmake . -B build -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake
cmake --build build

For a first real use, the repository ships example/filter_transform.cpp, which is the smallest thing that shows the pipe syntax doing something you cannot write as concisely with plain STL algorithms. Read that file before writing your own pipeline, then check example/sort_unique.cpp for the action side, where a container is mutated in place rather than lazily adapted.

Compiler requirements and the /permissive- constraint on MSVC

The README lists clang 5.0 or later, GCC 6.5 or later, Clang/LLVM 6 or later on Windows, and Visual Studio 2019 or later. The MSVC entry comes with a caveat: range-v3 needs /permissive- plus one of /std:c++latest, /std:c++20 or /std:c++17. The README attributes this to the library's strict conformance requirements.

That is not a formality. /permissive- changes how the compiler treats a range of non-conforming constructs, and a large existing codebase may not build cleanly with it enabled. If you are adding range-v3 to a mature MSVC project, the conformance flag is the first thing to test, before you write a single pipeline.

The compiler list is also a floor, not a guarantee. The README says the code is known to work on those compilers, which is a statement about what has been exercised rather than a support contract.

The stability promise is narrow, and that is the main risk

The README's development status paragraph is unusually direct. It calls the code fairly stable and well-tested and suitable for casual use, notes that documentation is lacking, and then says that in general no promise is made about support or long-term stability, and that the code will evolve without regard to backwards compatibility.

The exception is anything in the ranges::cpp20 namespace, which the README says will change rarely or preferably never. This is the single most important line for anyone evaluating the project. If you confine yourself to ranges::cpp20, you are effectively using the standardized subset and can expect it to hold still. If you use views and actions from elsewhere in the library, you are accepting that a future revision may break your build, and the release cadence gives you no schedule to plan around: the listed releases are 0.12.0 in June 2022, 0.11.0 in August 2020 and 0.10.0 in December 2019.

A second, quieter risk is the documentation gap. The README calls the docs woefully incomplete and warns that the linked talks and blog posts are dated and that the library probably has changed since they were written. Error messages from deeply nested view pipelines are a known cost of this style of library, and without current documentation the examples directory becomes your reference.

How range-v3 differs from std::ranges and from Boost.Range

The closest alternative is the standard library itself. If your toolchain implements C++20 ranges, std::ranges gives you range-taking algorithms and std::views without a third-party dependency, and the README states plainly that range-v3 is where that work came from. The practical difference is that std::ranges has no equivalent of range-v3's actions: there is no eager, in-place, pipeable mutation step in the standard. If your code wants to sort and deduplicate a container in a pipeline, that is a reason to keep range-v3 in the build even on C++20.

The other comparison people reach for is Boost.Range. The README's own framing is the useful one here: range-v3 is an abstraction layer on top of iterators, and the README contrasts this with other range-like solutions that seek to do away with iterators. Boost.Range predates the C++20 ranges work and does not carry the same lazy view composition model or the action concept. If you already depend on Boost, Boost.Range may cover simple cases without a new dependency, but it will not give you the pipeline composition that range-v3 was built around.

Licence, maintenance and what an upgrade actually costs

The README says most of the source is under the Boost Software License, with parts taken from Alex Stepanov's Elements of Programming, Howard Hinnant's libc++, and the SGI STL, and directs readers to the LICENSE and CREDITS files for the full picture. The repository metadata reports the licence as NOASSERTION, which means no single SPDX identifier was detected for the project as a whole. That is consistent with a mixed-provenance source tree. Read LICENSE.txt and CREDITS.md yourself and route them to whoever handles licensing in your organisation; this is a description of what the files say, not legal advice.

The last push to the default branch was on 2026-04-12, so the repository is not archived and has seen activity within the last six months. That is not the same as a release: the newest listed release is 0.12.0 from 2022-06-21. A project can be pushed to regularly while its tagged releases lag, and that gap is what you should price into an upgrade plan. If you pin to a released tag, you are pinning to code from 2022. If you track master, you inherit the README's warning that the code will evolve without regard to backwards compatibility.

The repository also carries build files for Buck (BUCK, .buckconfig) and Bazel (BUILD.bazel, WORKSPACE, MODULE.bazel, WORKSPACE.bzlmod) alongside CMakeLists.txt and a conanfile.py, so there is more than one way to wire it into a monorepo build. There is a TODO.md at the top level, which is worth reading before you file an issue about something that looks unfinished.

Editorial conclusion

Adopt range-v3 if you are on a compiler it lists as supported, you want lazy view pipelines today, and you need the eager actions that std::ranges does not offer. Do not adopt it as a general-purpose library for a codebase that cannot absorb API churn: the README says the code will evolve without regard to backwards compatibility, and only ranges::cpp20 carries a stability promise. Before committing, verify that your compiler meets the listed minimums, decide explicitly whether you will touch anything outside ranges::cpp20, and check the LICENSE and CREDITS files because the repository is reported as NOASSERTION rather than a single clean identifier.

Frequently asked questions

What are ranges in C++?

In range-v3, ranges are an extension of the STL that makes iterators and algorithms composable by adding an abstraction layer on top of iterators rather than replacing them. The library builds on views, actions and algorithms, and the README notes this design became the basis of the C++20 ranges proposal.

What is the difference between std::ranges and std::views in C++?

The README does not draw that distinction, so it cannot be answered from this project's documentation. What the README does say is that range-v3 was the basis for the C++20 ranges work and that its own ranges::cpp20 namespace is the part promised to change rarely or never.

How do I install range-v3?

The README documents two package managers: vcpkg, via ./vcpkg install range-v3, and Conan, via a conanfile.txt requiring range-v3/[*] with the CMakeDeps and CMakeToolchain generators. It also gives the CMake target name range-v3::range-v3 for linking.

Is range-v3 stable enough for production use?

The README calls the code fairly stable, well-tested and suitable for casual use, but states that no promise is made about support or long-term stability and that the code will evolve without regard to backwards compatibility. The exception is anything in the ranges::cpp20 namespace, which the README says will change rarely or preferably never.

Which compilers does range-v3 support?

The README lists clang 5.0 or later, GCC 6.5 or later, Clang/LLVM 6 or later on Windows, and Visual Studio 2019 or later. On MSVC it requires /permissive- together with /std:c++latest, /std:c++20 or /std:c++17.

Official sources

  1. ericniebler/range-v3 on GitHub
  2. Issues
  3. README
  4. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/ericniebler-range-v3.svg)](https://hysenlabs.com/projects/ericniebler-range-v3)