Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 219625e

Browse files
committed
contigous
1 parent d242a2a commit 219625e

7 files changed

Lines changed: 352 additions & 90 deletions

File tree

any_view.md

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -939,8 +939,8 @@ public:
939939
constexpr ~any_view();
940940
941941
// [range.any.access], range access
942-
constexpr auto begin();
943-
constexpr auto end();
942+
constexpr @*iterator*@ begin();
943+
constexpr @*sentinel*@ end();
944944
945945
constexpr @*make-unsigned-like-t*@<Diff> size() const;
946946
@@ -1108,22 +1108,14 @@ constexpr ~any_view();
11081108
#### ?.?.?.5 Range access [range.any.access] {-}
11091109

11101110
```cpp
1111-
constexpr auto begin();
1111+
constexpr @*iterator*@ begin();
11121112
```
11131113

11141114
:::bq
11151115

11161116
[1]{.pnum} *Preconditions*: `*this` has a *target view object*.
11171117

1118-
[2]{.pnum} *Effects*: Let `v` be an lvalue designating the *target view object* of `*this`.
1119-
1120-
- [2.1]{.pnum} If `Opts & any_view_options::contiguous` is `any_view_options::contiguous`, equivalent to:
1121-
1122-
```cpp
1123-
return to_address(ranges::begin(v));
1124-
```
1125-
1126-
- [2.2]{.pnum} Otherwise, returns an *iterator wrapper* object `@*iterator*@`, which holds a *target iterator object* of `ranges::begin(v)`
1118+
[2]{.pnum} *Effects*: Let `v` be an lvalue designating the *target view object* of `*this`, returns an object of *iterator wrapper type* `@*iterator*@`, which holds a *target iterator object* of `ranges::begin(v)`
11271119

11281120
:::
11291121

@@ -1135,15 +1127,7 @@ constexpr @*sentinel*@ end();
11351127

11361128
[3]{.pnum} *Preconditions*: `*this` has a *target view object*.
11371129

1138-
[4]{.pnum} *Effects*: Let `v` be an lvalue designating the *target view object* of `*this`.
1139-
1140-
- [4.1]{.pnum} If `Opts & any_view_options::contiguous` is `any_view_options::contiguous`, equivalent to:
1141-
1142-
```cpp
1143-
return to_address(ranges::end(v));
1144-
```
1145-
1146-
- [4.2]{.pnum} Otherwise, returns a *sentinel wrapper* object `@*sentinel*@`, which holds a *target sentinel object* of `ranges::end(v)`
1130+
[4]{.pnum} *Effects*: Let `v` be an lvalue designating the *target view object* of `*this`, returns an object of *sentinel wrapper type* `@*sentinel*@`, which holds a *target sentinel object* of `ranges::end(v)`
11471131

11481132
:::
11491133

@@ -1216,6 +1200,7 @@ namespace std::ranges {
12161200
constexpr @*iterator*@& operator-=(difference_type n);
12171201

12181202
constexpr Ref operator[](difference_type n) const;
1203+
constexpr add_pointer_t<Ref> operator->() const;
12191204

12201205
friend constexpr bool operator==(const @*iterator*@& x, const @*iterator*@& y);
12211206

@@ -1238,20 +1223,24 @@ namespace std::ranges {
12381223
12391224
[1]{.pnum} `@*iterator*@::iterator_concept` is defined as follows:
12401225
1241-
- [1.1]{.pnum} If `Opts & any_view_options::random_access` is `any_view_options::random_access`, then `iterator_concept` denotes `random_access_iterator_tag`.
1226+
- [1.1]{.pnum} If `Opts & any_view_options::contiguous` is `any_view_options::contiguous`, then `iterator_concept` denotes `contiguous_iterator_tag`.
1227+
1228+
- [1.2]{.pnum} Otherwise, if `Opts & any_view_options::random_access` is `any_view_options::random_access`, then `iterator_concept` denotes `random_access_iterator_tag`.
12421229
1243-
- [1.2]{.pnum} Otherwise, if `Opts & any_view_options::bidirectional` is `any_view_options::bidirectional`, then `iterator_concept` denotes `bidirectional_iterator_tag`.
1230+
- [1.3]{.pnum} Otherwise, if `Opts & any_view_options::bidirectional` is `any_view_options::bidirectional`, then `iterator_concept` denotes `bidirectional_iterator_tag`.
12441231
1245-
- [1.3]{.pnum} Otherwise, if `Opts & any_view_options::forward` is `any_view_options::forward`, then `iterator_concept` denotes `forward_iterator_tag`.
1232+
- [1.4]{.pnum} Otherwise, if `Opts & any_view_options::forward` is `any_view_options::forward`, then `iterator_concept` denotes `forward_iterator_tag`.
12461233
1247-
- [1.4]{.pnum} Otherwise, `iterator_concept` denotes `input_iterator_tag`.
1234+
- [1.5]{.pnum} Otherwise, `iterator_concept` denotes `input_iterator_tag`.
12481235
12491236
12501237
[2]{.pnum} The member typedef-name `iterator_category` is defined if and only if `Opts & any_view_options::forward` is `any_view_options::forward`. In that case, `@*iterator*@​::​iterator_category` is defined as follows:
12511238
1252-
- [2.1]{.pnum} If `is_reference_v<Ref>` is `true`, then `iterator_category` denotes `iterator_concept`.
1239+
- [2.1]{.pnum} If `is_reference_v<Ref>` is `true`, and `iterator_concept` is `contiguous_iterator_tag`, then `iterator_category` denotes `random_access_iterator_tag`.
12531240
1254-
- [2.1]{.pnum} Otherwise, `iterator_category` denotes `input_iterator_tag`.
1241+
- [2.2]{.pnum} Otherwise, if `is_reference_v<Ref>` is `true`, then `iterator_category` denotes `iterator_concept`.
1242+
1243+
- [2.3]{.pnum} Otherwise, `iterator_category` denotes `input_iterator_tag`.
12551244
12561245
```cpp
12571246
constexpr @*iterator*@();
@@ -1419,6 +1408,26 @@ return *((*this) + n);
14191408

14201409
:::
14211410

1411+
```cpp
1412+
constexpr add_pointer_t<Ref> operator->() const;
1413+
```
1414+
1415+
:::bq
1416+
1417+
[20]{.pnum} *Constraints*: `Opts & any_view_options::contiguous` is `any_view_options::contiguous`
1418+
1419+
[21]{.pnum} *Preconditions*: `*this` has a *target iterator object*.
1420+
1421+
[22]{.pnum} *Effects*: Equivalent to:
1422+
1423+
```cpp
1424+
return to_address(it);
1425+
```
1426+
1427+
where `it` is an lvalue designating the *target iterator object* of `*this`
1428+
1429+
:::
1430+
14221431
```cpp
14231432
friend constexpr bool operator==(const @*iterator*@& x, const @*iterator*@& y);
14241433
```

impl/any_view/any_view.hpp

Lines changed: 52 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,15 @@ struct __rvalue_ref {
5454
};
5555

5656
template <class T>
57-
struct __rvalue_ref<T&> {
58-
using type = T&&;
57+
struct __rvalue_ref<T &> {
58+
using type = T &&;
5959
};
6060

6161
template <class T>
6262
using __rvalue_ref_t = typename __rvalue_ref<T>::type;
6363

6464
template <class Element, any_view_options Opts = any_view_options::input,
65-
class Ref = Element&,
66-
class RValueRef = __rvalue_ref_t<Ref>,
65+
class Ref = Element &, class RValueRef = __rvalue_ref_t<Ref>,
6766
class Diff = ptrdiff_t>
6867
class any_view {
6968
public:
@@ -96,8 +95,7 @@ class any_view {
9695
bool (*equal_)(const iterator_storage &, const iterator_storage &);
9796
};
9897

99-
struct forward_iterator_vtable : input_iterator_vtable,
100-
equality_vtable {};
98+
struct forward_iterator_vtable : input_iterator_vtable, equality_vtable {};
10199

102100
struct bidirectional_iterator_vtable : forward_iterator_vtable {
103101
void (*decrement_)(iterator_storage &);
@@ -108,8 +106,9 @@ class any_view {
108106
Diff (*distance_to_)(const iterator_storage &, const iterator_storage &);
109107
};
110108

111-
// for contiguous , we just return raw pointers
112-
struct contiguous_iterator_vtable {};
109+
struct contiguous_iterator_vtable : random_access_iterator_vtable {
110+
std::add_pointer_t<Ref> (*arrow_)(const iterator_storage &);
111+
};
113112

114113
using any_iterator_vtable = conditional_t<
115114
Traversal == any_view_options::contiguous, contiguous_iterator_vtable,
@@ -120,31 +119,32 @@ class any_view {
120119
Traversal == any_view_options::bidirectional,
121120
bidirectional_iterator_vtable,
122121
conditional_t<Traversal == any_view_options::forward,
123-
forward_iterator_vtable,
124-
input_iterator_vtable>>>>;
122+
forward_iterator_vtable, input_iterator_vtable>>>>;
125123

126124
struct iterator_vtable_gen {
127125
template <class Iter>
128126
static constexpr auto generate() {
129127
any_iterator_vtable t;
130128

131-
if constexpr (Traversal != any_view_options::contiguous) {
132-
t.deref_ = &deref<Iter>;
133-
t.increment_ = &increment<Iter>;
134-
t.iter_move_ = &iter_move<Iter>;
129+
t.deref_ = &deref<Iter>;
130+
t.increment_ = &increment<Iter>;
131+
t.iter_move_ = &iter_move<Iter>;
132+
133+
if constexpr (Traversal >= any_view_options::forward) {
134+
t.equal_ = &equal<Iter>;
135+
}
135136

136-
if constexpr (Traversal >= any_view_options::forward) {
137-
t.equal_ = &equal<Iter>;
138-
}
137+
if constexpr (Traversal >= any_view_options::bidirectional) {
138+
t.decrement_ = &decrement<Iter>;
139+
}
139140

140-
if constexpr (Traversal >= any_view_options::bidirectional) {
141-
t.decrement_ = &decrement<Iter>;
142-
}
141+
if constexpr (Traversal >= any_view_options::random_access) {
142+
t.advance_ = &advance<Iter>;
143+
t.distance_to_ = &distance_to<Iter>;
144+
}
143145

144-
if constexpr (Traversal >= any_view_options::random_access) {
145-
t.advance_ = &advance<Iter>;
146-
t.distance_to_ = &distance_to<Iter>;
147-
}
146+
if constexpr (Traversal == any_view_options::contiguous) {
147+
t.arrow_ = &arrow<Iter>;
148148
}
149149
return t;
150150
}
@@ -194,6 +194,12 @@ class any_view {
194194
return Diff((*self.template get_ptr<Iter>()) -
195195
(*other.template get_ptr<Iter>()));
196196
}
197+
198+
// contiguous
199+
template <class Iter>
200+
static constexpr add_pointer_t<Ref> arrow(const iterator_storage &self) {
201+
return std::to_address(*(self.template get_ptr<Iter>()));
202+
};
197203
};
198204

199205
struct empty_iterator_category {};
@@ -310,6 +316,13 @@ class any_view {
310316
return *((*this) + n);
311317
}
312318

319+
constexpr std::add_pointer_t<Ref> operator->() const
320+
requires(Traversal == any_view_options::contiguous)
321+
{
322+
assert(!is_singular());
323+
return (*(iter_vtable_->arrow_))(iter_);
324+
}
325+
313326
friend constexpr bool operator<(const any_iterator &x,
314327
const any_iterator &y)
315328
requires(Traversal >= any_view_options::random_access)
@@ -398,8 +411,7 @@ class any_view {
398411
constexpr bool is_singular() const { return iter_.is_singular(); }
399412
};
400413

401-
using iterator = std::conditional_t<Traversal == any_view_options::contiguous,
402-
std::add_pointer_t<Ref>, any_iterator>;
414+
using iterator = any_iterator;
403415

404416
using sentinel_storage =
405417
detail::storage<3 * sizeof(void *), sizeof(void *), true>;
@@ -418,14 +430,9 @@ class any_view {
418430
template <class Iter, class Sent>
419431
static constexpr bool equal(const iterator &iter,
420432
const any_sentinel &sent) {
421-
if (sent.is_singular()) return false;
422-
if constexpr (Traversal == any_view_options::contiguous) {
423-
return iter == *sent.sent_.template get_ptr<Sent>();
424-
} else {
425-
if (iter.is_singular()) return false;
426-
return *(iter.iter_.template get_ptr<Iter>()) ==
427-
*(sent.sent_.template get_ptr<Sent>());
428-
}
433+
if (sent.is_singular() || iter.is_singular()) return false;
434+
return *(iter.iter_.template get_ptr<Iter>()) ==
435+
*(sent.sent_.template get_ptr<Sent>());
429436
}
430437
};
431438

@@ -458,8 +465,7 @@ class any_view {
458465
constexpr bool is_singular() const { return sent_.is_singular(); }
459466
};
460467

461-
using sentinel = std::conditional_t<Traversal == any_view_options::contiguous,
462-
std::add_pointer_t<Ref>, any_sentinel>;
468+
using sentinel = any_sentinel;
463469

464470
using view_storage =
465471
detail::storage<4 * sizeof(void *), sizeof(void *), is_view_copyable>;
@@ -490,24 +496,16 @@ class any_view {
490496
template <class View>
491497
static constexpr iterator begin(view_storage &v) {
492498
auto &view = *(v.template get_ptr<View>());
493-
if constexpr (Traversal == any_view_options::contiguous) {
494-
return std::to_address(std::ranges::begin(view));
495-
} else {
496-
return any_iterator(&iter_vtable<std::ranges::iterator_t<View>>,
497-
std::ranges::begin(view));
498-
}
499+
return any_iterator(&iter_vtable<std::ranges::iterator_t<View>>,
500+
std::ranges::begin(view));
499501
}
500502

501503
template <class View>
502504
static constexpr sentinel end(view_storage &v) {
503505
auto &view = *(v.template get_ptr<View>());
504-
if constexpr (Traversal == any_view_options::contiguous) {
505-
return std::to_address(std::ranges::end(view));
506-
} else {
507-
return any_sentinel(&sent_vtable<std::ranges::iterator_t<View>,
508-
std::ranges::sentinel_t<View>>,
509-
std::ranges::end(view));
510-
}
506+
return any_sentinel(&sent_vtable<std::ranges::iterator_t<View>,
507+
std::ranges::sentinel_t<View>>,
508+
std::ranges::end(view));
511509
}
512510

513511
template <class View>
@@ -547,11 +545,13 @@ class any_view {
547545
}
548546

549547
template <class Range>
550-
requires(!std::same_as<remove_cvref_t<Range>, any_view> && std::ranges::viewable_range<Range> &&
548+
requires(!std::same_as<remove_cvref_t<Range>, any_view> &&
549+
std::ranges::viewable_range<Range> &&
551550
view_options_constraint<views::all_t<Range>>())
552-
constexpr any_view(Range&& range)
551+
constexpr any_view(Range &&range)
553552
: view_vtable_(&view_vtable<views::all_t<Range>>),
554-
view_(detail::type<views::all_t<Range>>{}, views::all(std::forward<Range>(range))) {}
553+
view_(detail::type<views::all_t<Range>>{},
554+
views::all(std::forward<Range>(range))) {}
555555

556556
constexpr any_view(const any_view &)
557557
requires is_view_copyable

impl/any_view/test/iterator/bidirectional.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,9 @@ constexpr bool test() {
149149
return true;
150150
}
151151

152-
TEST_POINT("forward") {
152+
TEST_POINT("bidirectional") {
153153
test();
154-
// static_assert(test());
154+
static_assert(test());
155155
}
156156

157157
} // namespace

0 commit comments

Comments
 (0)