From Jason Turner

[range.dangling]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpkqe7wrqj/{from.md → to.md} +18 -11
tmp/tmpkqe7wrqj/{from.md → to.md} RENAMED
@@ -1,21 +1,20 @@
1
  ### Dangling iterator handling <a id="range.dangling">[[range.dangling]]</a>
2
 
3
- The tag type `dangling` is used together with the template aliases
4
- `borrowed_iterator_t` and `borrowed_subrange_t` to indicate that an
5
- algorithm that typically returns an iterator into or subrange of a
6
- `range` argument does not return an iterator or subrange which could
7
- potentially reference a range whose lifetime has ended for a particular
8
- rvalue `range` argument which does not model `borrowed_range`
9
- [[range.range]].
10
 
11
  ``` cpp
12
  namespace std::ranges {
13
  struct dangling {
14
  constexpr dangling() noexcept = default;
15
- template<class... Args>
16
- constexpr dangling(Args&&...) noexcept { }
17
  };
18
  }
19
  ```
20
 
21
  [*Example 1*:
@@ -25,17 +24,25 @@ vector<int> f();
25
  auto result1 = ranges::find(f(), 42); // #1
26
  static_assert(same_as<decltype(result1), ranges::dangling>);
27
  auto vec = f();
28
  auto result2 = ranges::find(vec, 42); // #2
29
  static_assert(same_as<decltype(result2), vector<int>::iterator>);
30
- auto result3 = ranges::find(subrange{vec}, 42); // #3
31
  static_assert(same_as<decltype(result3), vector<int>::iterator>);
32
  ```
33
 
34
  The call to `ranges::find` at \#1 returns `ranges::dangling` since `f()`
35
- is an rvalue `vector`; the `vector` could potentially be destroyed
36
  before a returned iterator is dereferenced. However, the calls at \#2
37
  and \#3 both return iterators since the lvalue `vec` and specializations
38
  of `subrange` model `borrowed_range`.
39
 
40
  — *end example*]
41
 
 
 
 
 
 
 
 
 
 
1
  ### Dangling iterator handling <a id="range.dangling">[[range.dangling]]</a>
2
 
3
+ The type `dangling` is used together with the template aliases
4
+ `borrowed_iterator_t` and `borrowed_subrange_t`. When an algorithm that
5
+ typically returns an iterator into, or a subrange of, a range argument
6
+ is called with an rvalue range argument that does not model
7
+ `borrowed_range` [[range.range]], the return value possibly refers to a
8
+ range whose lifetime has ended. In such cases, the type `dangling` is
9
+ returned instead of an iterator or subrange.
10
 
11
  ``` cpp
12
  namespace std::ranges {
13
  struct dangling {
14
  constexpr dangling() noexcept = default;
15
+ constexpr dangling(auto&&...) noexcept {}
 
16
  };
17
  }
18
  ```
19
 
20
  [*Example 1*:
 
24
  auto result1 = ranges::find(f(), 42); // #1
25
  static_assert(same_as<decltype(result1), ranges::dangling>);
26
  auto vec = f();
27
  auto result2 = ranges::find(vec, 42); // #2
28
  static_assert(same_as<decltype(result2), vector<int>::iterator>);
29
+ auto result3 = ranges::find(ranges::subrange{vec}, 42); // #3
30
  static_assert(same_as<decltype(result3), vector<int>::iterator>);
31
  ```
32
 
33
  The call to `ranges::find` at \#1 returns `ranges::dangling` since `f()`
34
+ is an rvalue `vector`; it is possible for the `vector` to be destroyed
35
  before a returned iterator is dereferenced. However, the calls at \#2
36
  and \#3 both return iterators since the lvalue `vec` and specializations
37
  of `subrange` model `borrowed_range`.
38
 
39
  — *end example*]
40
 
41
+ For a type `R` that models `range`:
42
+
43
+ - if `R` models `borrowed_range`, then `borrowed_iterator_t<R>` denotes
44
+ `iterator_t<R>`, and `borrowed_subrange_t<R>` denotes
45
+ `subrange<iterator_t<R>>`;
46
+ - otherwise, both `borrowed_iterator_t<R>` and `borrowed_subrange_t<R>`
47
+ denote `dangling`.
48
+