Skip to content

Commit ba6b148

Browse files
TylerMSFTTylerMSFT
authored andcommitted
tech review
1 parent 151d323 commit ba6b148

File tree

1 file changed

+11
-11
lines changed

1 file changed

+11
-11
lines changed

docs/standard-library/ranges.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: "<ranges>"
33
description: "Overview of the Standard Template Library (STL) ranges library"
4-
ms.date: "04/13/2021"
4+
ms.date: "04/14/2021"
55
f1_keywords: ["<ranges>"]
66
helpviewer_keywords: ["ranges"]
77
---
@@ -16,8 +16,6 @@ With ranges, you can simply call `std::ranges::sort(myVector);` which is treated
1616

1717
Code that is easier to write and more readable is great, but the benefits of ranges go further than that. They also make it easier to filter and transform collections of data in part by allowing you to compose STL algorithms more easily.
1818

19-
Because ranges don't own elements like a container does, they're lightweight. The time it takes to copy, move, or assign a range is constant no matter how many elements it points to.
20-
2119
## A ranges example
2220

2321
Before ranges, if you wanted to transform only the elements of a collection that meet a certain criteria, you'd need to introduce an intermediate step to hold the results between operations. For example, let's say you want to build a vector of squares from only the elements in another vector that are divisible by 3. You'd write something like:
@@ -50,9 +48,7 @@ The result, `output`, is itself a type of range called a view, which is discusse
5048
5149
## Views
5250

53-
A view is essentially a range that takes another range and transforms how its elements are accessed. How the elements appear depends on the algorithm or operation that you specify. The underlying range is unchanged. In the earlier example, one view took a range and returned a view of only the elements that were divisible by three.
54-
55-
A view is lightweight. Like a range, it doesn't own the elements. The time it takes to copy, move, or assign a view is constant, no matter the number of elements it points to.
51+
A view is a range which can be default constructed, moved, and possibly copied, with the added requirement that all view operations (default construction, move construction/assignment, copy construction/assignment (if present), destruction, begin and end) happen in constant time regardless of the number of elements in the view. How the elements appear depends on the algorithm or operation that you specify for the view. The underlying range is unchanged. In the earlier example, one view took a range and returned a view of only the elements that were divisible by three.
5652

5753
Views are composable. In the example above, the view of vector elements that are divisible by three is combined with the view that squares those elements.
5854

@@ -85,13 +81,13 @@ int main()
8581

8682
A view adaptor produces a view over a range. The range being viewed remains unchanged. A view doesn't own any elements. It allows you to iterate over the underlying range using customized behavior that you specify.
8783

88-
In the example above, the first view acts like an iterator that only provides the elements of `input` that are divisible by three. The other view acts like an iterator that takes the elements divisible by three, and provides the element's square.
84+
In the example above, the first view provides the elements of `input` that are divisible by three. The other view takes the elements divisible by three, and provides the element's square.
8985

9086
The `<ranges>` library provides many kinds of view adaptors. Besides the filter and transform views, there are views that take or skip the first N elements of a range, reverse the order of a range, join ranges, skip elements of a range until a condition is met, transform the elements of a range, and more.
9187

9288
## Range adaptors
9389

94-
A range adaptor produces a new range from an existing range. The new range uses customized behavior specified by the range adaptor to provide the elements. For example, a range adaptor might take a range and produce a new one that presents the elements from the original range in reverse order. Views, discussed earlier, are a common kind of range adaptor.
90+
A range adaptor produces a new range from an existing range and transforms how its elements are accessed. For example, a range adaptor might take a range and produce a new one that presents the elements from the original range in reverse order. Views, discussed earlier, are a common kind of range adaptor.
9591

9692
Range adaptors produce lazily evaluated ranges. That is, you don't incur the cost of transforming every element in the range--only the ones that you access, and at the time that you access them.
9793

@@ -103,13 +99,15 @@ Range adaptors can be chained or composed--which is where the power and flexibil
10399

104100
Range algorithms have been created that take a range argument. For example, `std::ranges::sort(myVector);`
105101

106-
The range algorithms are lazy, meaning that they operate on the range only when an element is accessed. They can work directly on a container, and can be easily chained together.
102+
The range algorithms are almost identical to the corresponding iterator-pair algorithms in the `std` namespace, except that they have concept-enforced constraints and accept range arguments or more general iterator-sentinel argument pairs. They can work directly on a container, and can be easily chained together.
107103

108104
## Types of ranges
109105

110-
What you can do with a range depends on the underlying iterator type of the range. There are different kinds of ranges, called refinements. The different kinds of ranges are codified as C++ 20 concepts. This table lists various range concepts, along with the type of container they can be applied to:
106+
What you can do with a range depends on the underlying iterator type of the range. Range concepts are refinements of the `range` concept. In C++ 20, to say that concept X refines concept Y means that everything that satisfies Y also satisfies X--though not necessarily the other way around. For example, car, bus, and truck all refine vehicle.
107+
108+
The range concepts mirror the hierarchy of iterator categories. This table lists various range concepts, along with the type of container they can be applied to:
111109

112-
| Range refinement | Description | Supported containers |
110+
| Range concept | Description | Supported containers |
113111
|--|--|--|
114112
| `std::ranges::input_range` | Can iterate from beginning to end at least once |
115113
| `std::forward_list`<br>`std::unordered_map`<br>`std::unordered_multimap`<br>`std::unordered_set`<br>`std::unordered_multiset`<br>`basic_istream_view` |
@@ -118,6 +116,8 @@ What you can do with a range depends on the underlying iterator type of the rang
118116
| `std::ranges::random_access_range` | Can access an arbitrary element (in constant time) using the `[]` operator) | `std::deque` |
119117
| `std::ranges::contiguous_range` | The elements are stored in memory consecutively | `std::array`<br>`std::string`<br>`std::vector` |
120118

119+
120+
121121
## See also
122122

123123
[Header Files Reference](../standard-library/cpp-standard-library-header-files.md)

0 commit comments

Comments
 (0)