From Jason Turner

[view.interface.general]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpd5ay63ze/{from.md → to.md} +97 -0
tmp/tmpd5ay63ze/{from.md → to.md} RENAMED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #### General <a id="view.interface.general">[[view.interface.general]]</a>
2
+
3
+ The class template `view_interface` is a helper for defining view-like
4
+ types that offer a container-like interface. It is parameterized with
5
+ the type that is derived from it.
6
+
7
+ ``` cpp
8
+ namespace std::ranges {
9
+ template<class D>
10
+ requires is_class_v<D> && same_as<D, remove_cv_t<D>>
11
+ class view_interface {
12
+ private:
13
+ constexpr D& derived() noexcept { // exposition only
14
+ return static_cast<D&>(*this);
15
+ }
16
+ constexpr const D& derived() const noexcept { // exposition only
17
+ return static_cast<const D&>(*this);
18
+ }
19
+
20
+ public:
21
+ constexpr bool empty() requires sized_range<D> || forward_range<D> {
22
+ if constexpr (sized_range<D>)
23
+ return ranges::size(derived()) == 0;
24
+ else
25
+ return ranges::begin(derived()) == ranges::end(derived());
26
+ }
27
+ constexpr bool empty() const requires sized_range<const D> || forward_range<const D> {
28
+ if constexpr (sized_range<const D>)
29
+ return ranges::size(derived()) == 0;
30
+ else
31
+ return ranges::begin(derived()) == ranges::end(derived());
32
+ }
33
+
34
+ constexpr auto cbegin() requires input_range<D> {
35
+ return ranges::cbegin(derived());
36
+ }
37
+ constexpr auto cbegin() const requires input_range<const D> {
38
+ return ranges::cbegin(derived());
39
+ }
40
+ constexpr auto cend() requires input_range<D> {
41
+ return ranges::cend(derived());
42
+ }
43
+ constexpr auto cend() const requires input_range<const D> {
44
+ return ranges::cend(derived());
45
+ }
46
+
47
+ constexpr explicit operator bool()
48
+ requires requires { ranges::empty(derived()); } {
49
+ return !ranges::empty(derived());
50
+ }
51
+ constexpr explicit operator bool() const
52
+ requires requires { ranges::empty(derived()); } {
53
+ return !ranges::empty(derived());
54
+ }
55
+
56
+ constexpr auto data() requires contiguous_iterator<iterator_t<D>> {
57
+ return to_address(ranges::begin(derived()));
58
+ }
59
+ constexpr auto data() const
60
+ requires range<const D> && contiguous_iterator<iterator_t<const D>> {
61
+ return to_address(ranges::begin(derived()));
62
+ }
63
+
64
+ constexpr auto size() requires forward_range<D> &&
65
+ sized_sentinel_for<sentinel_t<D>, iterator_t<D>> {
66
+ return to-unsigned-like(ranges::end(derived()) - ranges::begin(derived()));
67
+ }
68
+ constexpr auto size() const requires forward_range<const D> &&
69
+ sized_sentinel_for<sentinel_t<const D>, iterator_t<const D>> {
70
+ return to-unsigned-like(ranges::end(derived()) - ranges::begin(derived()));
71
+ }
72
+
73
+ constexpr decltype(auto) front() requires forward_range<D>;
74
+ constexpr decltype(auto) front() const requires forward_range<const D>;
75
+
76
+ constexpr decltype(auto) back() requires bidirectional_range<D> && common_range<D>;
77
+ constexpr decltype(auto) back() const
78
+ requires bidirectional_range<const D> && common_range<const D>;
79
+
80
+ template<random_access_range R = D>
81
+ constexpr decltype(auto) operator[](range_difference_t<R> n) {
82
+ return ranges::begin(derived())[n];
83
+ }
84
+ template<random_access_range R = const D>
85
+ constexpr decltype(auto) operator[](range_difference_t<R> n) const {
86
+ return ranges::begin(derived())[n];
87
+ }
88
+ };
89
+ }
90
+ ```
91
+
92
+ The template parameter `D` for `view_interface` may be an incomplete
93
+ type. Before any member of the resulting specialization of
94
+ `view_interface` other than special member functions is referenced, `D`
95
+ shall be complete, and model both `derived_from<view_interface<D>>` and
96
+ `view`.
97
+