From Jason Turner

[common.iterator]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpx7d8eef7/{from.md → to.md} +96 -0
tmp/tmpx7d8eef7/{from.md → to.md} RENAMED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #### Class template `common_iterator` <a id="common.iterator">[[common.iterator]]</a>
2
+
3
+ Class template `common_iterator` is an iterator/sentinel adaptor that is
4
+ capable of representing a non-common range of elements (where the types
5
+ of the iterator and sentinel differ) as a common range (where they are
6
+ the same). It does this by holding either an iterator or a sentinel, and
7
+ implementing the equality comparison operators appropriately.
8
+
9
+ [*Note 1*: The `common_iterator` type is useful for interfacing with
10
+ legacy code that expects the begin and end of a range to have the same
11
+ type. — *end note*]
12
+
13
+ [*Example 1*:
14
+
15
+ ``` cpp
16
+ template<class ForwardIterator>
17
+ void fun(ForwardIterator begin, ForwardIterator end);
18
+
19
+ list<int> s;
20
+ // populate the list s
21
+ using CI = common_iterator<counted_iterator<list<int>::iterator>, default_sentinel_t>;
22
+ // call fun on a range of 10 ints
23
+ fun(CI(counted_iterator(s.begin(), 10)), CI(default_sentinel));
24
+ ```
25
+
26
+ — *end example*]
27
+
28
+ ``` cpp
29
+ namespace std {
30
+ template<input_or_output_iterator I, sentinel_for<I> S>
31
+ requires (!same_as<I, S> && copyable<I>)
32
+ class common_iterator {
33
+ public:
34
+ constexpr common_iterator() = default;
35
+ constexpr common_iterator(I i);
36
+ constexpr common_iterator(S s);
37
+ template<class I2, class S2>
38
+ requires convertible_to<const I2&, I> && convertible_to<const S2&, S>
39
+ constexpr common_iterator(const common_iterator<I2, S2>& x);
40
+
41
+ template<class I2, class S2>
42
+ requires convertible_to<const I2&, I> && convertible_to<const S2&, S> &&
43
+ assignable_from<I&, const I2&> && assignable_from<S&, const S2&>
44
+ common_iterator& operator=(const common_iterator<I2, S2>& x);
45
+
46
+ decltype(auto) operator*();
47
+ decltype(auto) operator*() const
48
+ requires dereferenceable<const I>;
49
+ decltype(auto) operator->() const
50
+ requires see below;
51
+
52
+ common_iterator& operator++();
53
+ decltype(auto) operator++(int);
54
+
55
+ template<class I2, sentinel_for<I> S2>
56
+ requires sentinel_for<S, I2>
57
+ friend bool operator==(
58
+ const common_iterator& x, const common_iterator<I2, S2>& y);
59
+ template<class I2, sentinel_for<I> S2>
60
+ requires sentinel_for<S, I2> && equality_comparable_with<I, I2>
61
+ friend bool operator==(
62
+ const common_iterator& x, const common_iterator<I2, S2>& y);
63
+
64
+ template<sized_sentinel_for<I> I2, sized_sentinel_for<I> S2>
65
+ requires sized_sentinel_for<S, I2>
66
+ friend iter_difference_t<I2> operator-(
67
+ const common_iterator& x, const common_iterator<I2, S2>& y);
68
+
69
+ friend iter_rvalue_reference_t<I> iter_move(const common_iterator& i)
70
+ noexcept(noexcept(ranges::iter_move(declval<const I&>())))
71
+ requires input_iterator<I>;
72
+ template<indirectly_swappable<I> I2, class S2>
73
+ friend void iter_swap(const common_iterator& x, const common_iterator<I2, S2>& y)
74
+ noexcept(noexcept(ranges::iter_swap(declval<const I&>(), declval<const I2&>())));
75
+
76
+ private:
77
+ variant<I, S> v_; // exposition only
78
+ };
79
+
80
+ template<class I, class S>
81
+ struct incrementable_traits<common_iterator<I, S>> {
82
+ using difference_type = iter_difference_t<I>;
83
+ };
84
+
85
+ template<input_iterator I, class S>
86
+ struct iterator_traits<common_iterator<I, S>> {
87
+ using iterator_concept = see below;
88
+ using iterator_category = see below;
89
+ using value_type = iter_value_t<I>;
90
+ using difference_type = iter_difference_t<I>;
91
+ using pointer = see below;
92
+ using reference = iter_reference_t<I>;
93
+ };
94
+ }
95
+ ```
96
+