Range library for C++14/17/20, basis for C++20's std::ranges
Released: June 21, 2022
IMPORTANT: This release deprecates
views::group_by
which was an endless source of confusion.group_by
is replaced withviews::chunk_by
(which, beware, has subtly different semantics, see below.)
Changes:
views::chunk_by
which, like the old views::group_by
it replaces,
splits a range into a range-of-ranges, where adjacent elements satisfy a binary
predicate (#1648). [Note: Whereas views::group_by
evaluated the predicate
between the current element and the first element in the chunk, views::chunk_by
evaluates the predicate between adjacent elements. -- end note]constexpr
all the algorithms that are constexpr
in C++20's std::ranges
(#1683).ranges::unformatted_ostream_iterator
(#1586).build2
build system (#1562).ranges::join_view
to support joining ranges of prvalue non-view
ranges (#1655).ranges::linear_distribute
(#1679).safe_subrange_t
to borrowed_subrange_t
(#1542).ranges::to
to support conversion to container-of-containers (#1553).views::enumerate
can be a borrowed_view
(#1571).ranges::upper_bound
works in the presence of overloaded operator&
(#1632).Bugs fixed:
ranges::to<std::map>(v)
does not work (#1700)ranges::reverse_iterator
has the wrong value_type
when reversing a proxy
range (#1670).ranges::counted_iterator
wrapping an input iterator with
a void
-returning post-increment operator isn't incrementing the count (#1664).views::drop_last
(#1599).bool
in views::cache1
(#1610).ranges::unstable_remove_if
calls predicate on same element twice (#1629).ranges::on(f,g)(x...)
should be f(g(x)...)
instead of f(g(x...))
(#1661).Credits: I would like to thank the following people who contributed to this release (in no particular order): Barry Revzin, @dvirtz, Gonzalo Brito, Johel Ernesto Guerrero Peña, Joël Lamotte, Doug Roeper, Facundo Tuesca, Vitaly Zaitsev, @23rd, @furkanusta, Jonathan Haigh, @SmorkalovG, @marehr, Matt Beardsley, Chris Glover, Louis Dionne, Jin Shang (@js8544), Hui Xie, @huixie90, Robert Maynard, Silver Zachara, @sergegers, Théo DELRIEU, @LesnyRumcajs, Yehezkel Bernat, Maciej Patro, Klemens Nanni, Thomas Madlener, and Jason Merrill.
:tada: Special thanks to Barry Revzin for stepping up to be part-time co-maintainer of range-v3. :tada:
Released: August 6, 2020
IMPORTANT: This release removes the heuristic that tries to guess whether a range type is a "view" (lightweight, non-owning range), in accordance with the C++20. This is a potentially source-breaking change. Code that previously used an rvalue range as the start of a pipeline could stop compiling if the range library is not explicitly told that that range type is a view. To override the new default, please specialize the
ranges::enable_view<R>
Boolean variable template.
IMPORTANT: This release removes the implicit conversion from views to containers. To construct a container from an arbitrary range, you must now explicitly use
ranges::to
. For example, the following code no longer works:std::vector<int> is = ranges::views::ints(0, 10); // ERROR: no conversion
Instead, please write this as:
auto is = ranges::views::ints(0, 10) | ranges::to<std::vector>; // OK
ranges::to
lives in header<range/v3/range/conversion.hpp>
IMPORTANT: This release drops support for llvm-3.9.
Changes:
requires
clauses for better compile times when emulating concepts./std:c++17
mode, and for MSVC's default preprocessor.std::ranges
support:
safe_range<R>
-> borrowed_range<R>
enable_safe_range<R>
-> enable_borrowed_range<R>
safe_iterator_t<R>
-> borrowed_iterator_t<R>
safe_subrange_t<R>
-> borrowed_subrange_t<R>
readable_traits<I>
-> indirectly_readable_traits<I>
readable<I>
-> indirectly_readable<I>
writable<I>
-> indirectly_writable<I>
ranges::cpp20
namespace:
for_each_n
sample
view_base
views::all_t
__int128
is recognized as "integer-like".three_way_comparable[_with]
when <=>
is supported.partially_ordered[_with]
.boolean-testable
concept.CMAKE_CXX_STANDARD
variable.views::zip[_with]
(#1486).view_interface::data()
member function.std::basic_common_reference
and
std::common_type
.drop_while_view
is not a sized_range
.views::group_by
(#1393).common_[reference|type]
of common_[tuple|pair]
now yields a common_[tuple|pair]
instead of a std::[tuple|pair]
(#1422).Credits: I would like to thank the following people who contributed to this release (in no particular order): Christopher Di Bella, @marehr, Casey Carter, Dvir Yitzchaki, Justin Riddell, Johel Ernesto Guerrero Peña, Barry Revzin, Kamlesh Kumar, and Vincas Dargis.
Released: Dec 6, 2019.
IMPORTANT: Before upgrading, please note that several older compiler versions
and build configurations are no longer supported! In particular, MSVC now needs
/std:c++latest
.
ALSO: When taking a dependency on the range-v3
, meta
, or concepts
libraries via CMake, please now use the namespace qualified target names:
range-v3::range-v3
range-v3::meta
range-v3::concepts
Changes:
views::cache1
view caches the most recent value in the
range. This can help avoid reevaluation of transformations in complex view
pipelines.ranges::contains
algorithm.enable_safe_range
trait for opting in to the forwarding-range
concept. These are ranges whose iterators remain valid even after the
range itself has been destroyed; e.g., std::string_view
and
ranges::subrange
.readable
concept has changed such that types that are not indirectly
readable with operator*
(_e.g., std::optional
) no longer satisfy that
concept.views::join
to join a range of xvalue ranges works again.range::front
range::back
range::at
range::index
views::concat
with a single argument now simply returns its argument.ranges::ostream_iterator<T>
now coerces arguments to T
before inserting
them into the wrapped ostream.views::transform
and views::take_while
.actions::split
and actions::split_when
now support partial application and
pipelining (#1085).views::group_by
and its iterator both get a .base()
member to access the
underlying range and iterator, respectively.Many thanks to GitHub users @CaseyCarter, @morinmorin, @h-2, @MichaelWJung, @johelegp, @marehr, @alkino, @xuning97, @BRevzin, and @mpusz for their contributions.
Released: Aug 26, 2019.
Bring many interfaces into sync with the C++20 draft.
NEW: An improved concepts portability layer with macros that use C++20 concepts when the compiler supports them.
NEW: An improved directory structure that keeps disjoint parts of the library -- iterators, ranges, algorithms, actions, views, functional programming support, and general utilities -- physically separate.
NEW: A RANGES_DEEP_STL_INTEGRATION
configuration option that makes your
STL implementation default to structural conformance to infer iterator
category, as in C++20. Applies to libc++, libstdc++, and MSVC's Standard
Library.
NEW: A ranges::cpp20
namespace that contains all the functionality of
C++20's std::ranges
namespace.
All concept names have been given standard_case (renamed from PascalCase) and have been harmonized with the C++20 draft.
The following range access customization points no longer accept rvalue ranges by default:
ranges::begin
ranges::end
ranges::rbegin
ranges::rend
ranges::cbegin
ranges::cend
ranges::crbegin
ranges::crend
ranges::data
ranges::cdata
Iterators may specify an iterator_concept
type alias in addition to
iterator_category
-- either as a nested type or as a member of a
std::iterator_traits
specialization -- to denote conformance to the C++20
iterator concepts as distinct from the C++98 iterator requirements.
(See P1037 "Deep Integration of the Ranges TS"
for more information.)
The ranges::value_type
trait has been renamed to readable_traits
.
The ranges::difference_type
trait has been renamed to incrementable_traits
.
The ranges::iterator_category
trait has been deprecated. Specialize
std::iterator_traits
to non-intrusively specify an iterator's category
and (optionally) concept.
Rename the ranges::view
namespace to ranges::views
and ranges::action
to
ranges::actions
(with deprecated namespace aliases for migration).
Rename view::bounded
to views::common
.
Rename unreachable
to unreachable_sentinel_t
.
Change dangling
from a class template that wraps an iterator to a class that
acts as a placeholder for an iterator that would otherwise dangle.
Implement C++20's subrange
as a view that wraps an iterator/sentinel pair;
deprecate iterator_range
.
Deprecate implicit conversion from view types to containers; rename
ranges::to_
to ranges::to
and extend it to support converting a
range-of-ranges to a container-of-containers.
Deprecate the ranges::v3
inline versioning namespace.
The following views have had minor changes to bring them into conformance with the C++20 working draft:
join_view
single_view
empty_view
split_view
reverse_view
all_view
take_view
iota_view
New names for the iterator and range type aliases:
Old Name | New Name |
---|---|
value_type_t |
iter_value_t |
reference_t |
iter_reference_t |
difference_type_t |
iter_difference_t |
size_type_t |
deprecated |
rvalue_reference_t |
iter_rvalue_reference_t |
range_value_type_t |
range_value_t |
range_difference_type_t |
range_difference_t |
range_size_type_t |
range_size_t |
view::enumerate
, from @MikeGitbview::addressof
, from @tower120unstable_remove_if
algorithm and action, from @tower120adjacent_remove_if
algorithm and action, from @tower120ostream_joiner
, from @sv1990view::drop_while
and view::take_while
get projection support, from @mrpiview::filter
and view::remove_if
get projection support, from @mrpiview::unique
accepts optional comparison operator, from @tete17action::slice
supports sliding from the end, from @tete17view::generate_n
, from GitHub user @tower120view_adaptor
supports basic_iterator
-style mixins, from @tower120ranges::advance
for random-access iterators for n==0
, from @tower1200.4.0 Oct 18, 2018
single_view
returns by const &
(see #817).reverse_view
of a non-Sized, non-Bounded RandomAccess range (eg., a null-terminated string) no longer satisfies SizedRange.generate
and generate_n
views now return the generated values by xvalue reference (T &&
) to the value cached within the view (see #905).single
, empty
, and reverse
views are much closer to the versions as specified in P0896.0.3.7 Sept 19, 2018
any_view<T, category::sized | category::input>
(see #869).iter_move
of a ranges::reverse_iterator
(see #888).move_sentinel
comparisons (see #889).boost::advance
and std::advance
(see #893).view::exclusive_scan
(thanks to GitHub user @mitsutaka-takeda).const
overloads of .empty()
and .size()
(see ericniebler/stl2#793).subspan
interface tweaks.view::split
(see this stackoverflow question).view::stride
(see ericniebler/stl2#805).const
-correctness problem in view::chunk
(see this stackoverflow question).ranges::result_of
with ranges::invoke_result
.view::drop
over RandomAccessRanges.view::cartesian_product
fixes (see ericniebler/stl2#820, ericniebler/stl2#823).volatile
std::initializer_list
s (see ericniebler/stl2#826).const
-correctness problem of view::take
.0.3.5 February 17, 2018
Writable
(see ericniebler/stl2#387).view_interface
gets a bounds-checking at
method.chunk_view
works on Input ranges.group_by_view
.partial_sum
numeric algorithm.ContiguousIterator
concept and contiguous_iterator_tag
iterator
category tag.span
fixes.action::insert
avoids interfering with vector
's exponentional growth
strategy.shared
view for views that need container-like scratch
space to do their work.reverse_view
.ranges::reference_wrapper
to avoid LWG#2993.any_view
, the type-erased view wrapper.equal
algorithm is constexpr
in C++14.stride_view
no longer needs an atomic
data member.const
-correct drop_view
.adjacent_filter_view
supports bidirectional iteration.view_adaptor
cleanup to remove the need for a mutable
data
member holding the adapted view.counting_iterator
post-increment bug.tail_view
of an empty range is an empty range, not undefined behavior.0.3.0 June 30, 2017
any_view
s are now much more efficient (from @CaseyCarter)<thread>
header (from @CaseyCarter)