Skip to content

Commit 71772e7

Browse files
authored
Merge pull request MicrosoftDocs#3502 from TylerMSFT/twhitney-ranges
incorp tech review
2 parents 79fde2a + 429db4c commit 71772e7

File tree

1 file changed

+12
-10
lines changed

1 file changed

+12
-10
lines changed

docs/standard-library/ranges.md

Lines changed: 12 additions & 10 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,9 @@ 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.
51+
A view is a range 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.
5452

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.
53+
How the elements in the view appear depends on the algorithm or operation that you specify for the view. In the example above, a view takes a range and returns a view of only those elements that are divisible by three. The underlying range is unchanged.
5654

5755
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.
5856

@@ -85,13 +83,13 @@ int main()
8583

8684
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.
8785

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.
86+
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.
8987

9088
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.
9189

9290
## Range adaptors
9391

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.
92+
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.
9593

9694
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.
9795

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

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

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.
104+
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.
107105

108106
## Types of ranges
109107

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:
108+
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.
109+
110+
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:
111111

112-
| Range refinement | Description | Supported containers |
112+
| Range concept | Description | Supported containers |
113113
|--|--|--|
114114
| `std::ranges::input_range` | Can iterate from beginning to end at least once |
115115
| `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 +118,8 @@ What you can do with a range depends on the underlying iterator type of the rang
118118
| `std::ranges::random_access_range` | Can access an arbitrary element (in constant time) using the `[]` operator) | `std::deque` |
119119
| `std::ranges::contiguous_range` | The elements are stored in memory consecutively | `std::array`<br>`std::string`<br>`std::vector` |
120120

121+
122+
121123
## See also
122124

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

0 commit comments

Comments
 (0)