Skip to content

Commit 1ec6391

Browse files
committed
P1456R1 Move-only views
1 parent 81f1d68 commit 1ec6391

File tree

1 file changed

+59
-71
lines changed

1 file changed

+59
-71
lines changed

source/ranges.tex

Lines changed: 59 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,7 @@
720720
the requirement that the number of elements in the range can be determined
721721
in constant time using the \tcode{ranges::size} function.
722722
The \libconcept{view} concept specifies requirements on a \libconcept{range} type
723-
with constant-time copy and assign operations.
723+
with constant-time destruction and move operations.
724724

725725
\pnum
726726
Several refinements of \libconcept{range} group requirements
@@ -898,19 +898,31 @@
898898

899899
\rSec2[range.view]{Views}
900900

901+
\pnum
902+
The \libconcept{view} concept specifies the requirements of a \libconcept{range} type
903+
that has constant time move construction, move assignment, and destruction;
904+
that is, the cost of these operations is
905+
% FIXME: Shouldn't this be "independent of the number of elements"?
906+
not proportional to the number of elements in the \tcode{view}.
907+
901908
\begin{itemdecl}
902909
template<class T>
903910
concept @\deflibconcept{view}@ =
904-
range<T> && semiregular<T> && enable_view<T>;
911+
range<T> && movable<T> && default_constructible<T> && enable_view<T>;
905912
\end{itemdecl}
906913

907914
\begin{itemdescr}
908-
% FIXME: This should explicitly say when view is modeled.
909915
\pnum
910-
The \libconcept{view} concept specifies the requirements of a \libconcept{range} type
911-
that has constant time copy, move, and assignment operators; that is, the cost of
912-
these operations is not proportional to the number of elements in the
913-
\tcode{view}.
916+
\tcode{T} models \libconcept{view} only if:
917+
\begin{itemize}
918+
\item
919+
\tcode{copy_constructible<T>} is \tcode{false}, or
920+
\tcode{T} has \bigoh{1} copy construction; and
921+
922+
\item
923+
\tcode{copyable<T>} is \tcode{false}, or
924+
\tcode{T} has \bigoh{1} copy assignment.
925+
\end{itemize}
914926

915927
\pnum
916928
\begin{example}
@@ -925,7 +937,7 @@
925937
\end{itemize}
926938

927939
Most containers\iref{containers} are not views since
928-
copying the container copies the elements,
940+
destruction of the container destroys the elements,
929941
which cannot be done in constant time.
930942
\end{example}
931943
\end{itemdescr}
@@ -2701,6 +2713,8 @@
27012713
\rSec3[range.filter.view]{Class template \tcode{filter_view}}
27022714

27032715
\indexlibraryglobal{filter_view}%
2716+
\indexlibrarymember{base}{filter_view}%
2717+
\indexlibrarymember{end}{filter_view}%
27042718
\begin{codeblock}
27052719
namespace std::ranges {
27062720
template<input_range V, indirect_unary_predicate<iterator_t<V>> Pred>
@@ -2722,7 +2736,8 @@
27222736
requires viewable_range<R> && constructible_from<V, all_view<R>>
27232737
constexpr filter_view(R&& r, Pred pred);
27242738

2725-
constexpr V base() const;
2739+
constexpr V base() const& requires copy_constructible<V> { return base_; }
2740+
constexpr V base() && { return std::move(base_); }
27262741

27272742
constexpr iterator begin();
27282743
constexpr auto end() {
@@ -2764,17 +2779,6 @@
27642779
and initializes \tcode{pred_} with \tcode{std::\brk{}move(pred)}.
27652780
\end{itemdescr}
27662781

2767-
\indexlibrarymember{base}{filter_view}%
2768-
\begin{itemdecl}
2769-
constexpr V base() const;
2770-
\end{itemdecl}
2771-
2772-
\begin{itemdescr}
2773-
\pnum
2774-
\effects
2775-
Equivalent to: \tcode{return base_;}
2776-
\end{itemdescr}
2777-
27782782
\indexlibrarymember{begin}{filter_view}%
27792783
\begin{itemdecl}
27802784
constexpr iterator begin();
@@ -3116,6 +3120,8 @@
31163120
\rSec3[range.transform.view]{Class template \tcode{transform_view}}
31173121

31183122
\indexlibraryglobal{transform_view}%
3123+
\indexlibrarymember{base}{transform_view}%
3124+
\indexlibrarymember{size}{transform_view}%
31193125
\begin{codeblock}
31203126
namespace std::ranges {
31213127
template<input_range V, copy_constructible F>
@@ -3138,7 +3144,8 @@
31383144
requires viewable_range<R> && constructible_from<V, all_view<R>>
31393145
constexpr transform_view(R&& r, F fun);
31403146

3141-
constexpr V base() const;
3147+
constexpr V base() const& requires copy_constructible<V> { return base_; }
3148+
constexpr V base() && { return std::move(base_); }
31423149

31433150
constexpr iterator<false> begin();
31443151
constexpr iterator<true> begin() const
@@ -3190,17 +3197,6 @@
31903197
and \tcode{fun_} with \tcode{std::move(fun)}.
31913198
\end{itemdescr}
31923199

3193-
\indexlibrarymember{base}{transform_view}%
3194-
\begin{itemdecl}
3195-
constexpr V base() const;
3196-
\end{itemdecl}
3197-
3198-
\begin{itemdescr}
3199-
\pnum
3200-
\effects
3201-
Equivalent to: \tcode{return base_;}
3202-
\end{itemdescr}
3203-
32043200
\indexlibrarymember{begin}{transform_view}%
32053201
\begin{itemdecl}
32063202
constexpr iterator<false> begin();
@@ -3804,6 +3800,10 @@
38043800
\rSec3[range.take.view]{Class template \tcode{take_view}}
38053801

38063802
\indexlibraryglobal{take_view}%
3803+
\indexlibrarymember{base}{take_view}%
3804+
\indexlibrarymember{begin}{take_view}%
3805+
\indexlibrarymember{end}{take_view}%
3806+
\indexlibrarymember{size}{take_view}%
38073807
\begin{codeblock}
38083808
namespace std::ranges {
38093809
template<view V>
@@ -3820,7 +3820,8 @@
38203820
requires constructible_from<V, all_view<R>>
38213821
constexpr take_view(R&& r, range_difference_t<V> count);
38223822

3823-
constexpr V base() const;
3823+
constexpr V base() const& requires copy_constructible<V> { return base_; }
3824+
constexpr V base() && { return std::move(base_); }
38243825

38253826
constexpr auto begin() requires (!@\placeholder{simple-view}@<V>) {
38263827
if constexpr (sized_range<V>) {
@@ -3905,17 +3906,6 @@
39053906
and \tcode{count_} with \tcode{count}.
39063907
\end{itemdescr}
39073908

3908-
\indexlibrarymember{base}{take_view}%
3909-
\begin{itemdecl}
3910-
constexpr V base() const;
3911-
\end{itemdecl}
3912-
3913-
\begin{itemdescr}
3914-
\pnum
3915-
\effects
3916-
Equivalent to: \tcode{return base_;}
3917-
\end{itemdescr}
3918-
39193909
\rSec3[range.take.sentinel]{Class template \tcode{take_view::sentinel}}
39203910

39213911
\indexlibraryglobal{take_view::sentinel}%
@@ -4436,6 +4426,9 @@
44364426
\rSec3[range.join.view]{Class template \tcode{join_view}}
44374427

44384428
\indexlibraryglobal{join_view}%
4429+
\indexlibrarymember{base}{join_view}%
4430+
\indexlibrarymember{begin}{join_view}%
4431+
\indexlibrarymember{end}{join_view}%
44394432
\begin{codeblock}
44404433
namespace std::ranges {
44414434
template<input_range V>
@@ -4464,6 +4457,9 @@
44644457
requires viewable_range<R> && constructible_from<V, all_view<R>>
44654458
constexpr explicit join_view(R&& r);
44664459

4460+
constexpr V base() const& requires copy_constructible<V> { return base_; }
4461+
constexpr V base() && { return std::move(base_); }
4462+
44674463
constexpr auto begin() {
44684464
return iterator<@\placeholder{simple-view}@<V>>{*this, ranges::begin(base_)};
44694465
}
@@ -4649,11 +4645,11 @@
46494645
\effects
46504646
Equivalent to:
46514647
\begin{codeblock}
4652-
auto update_inner = [this](range_reference_t<Base> x) -> decltype(auto) {
4648+
auto update_inner = [this](range_reference_t<Base> x) -> auto& {
46534649
if constexpr (ref_is_glvalue) // \tcode{x} is a reference
4654-
return (x); // \tcode{(x)} is an lvalue
4650+
return x;
46554651
else
4656-
return (parent_->inner_ = views::all(x));
4652+
return (parent_->inner_ = views::all(std::move(x)));
46574653
};
46584654

46594655
for (; outer_ != ranges::end(parent_->base_); ++outer_) {
@@ -4922,6 +4918,9 @@
49224918
\rSec3[range.split.view]{Class template \tcode{split_view}}
49234919

49244920
\indexlibraryglobal{split_view}%
4921+
\indexlibrarymember{base}{split_view}%
4922+
\indexlibrarymember{begin}{split_view}%
4923+
\indexlibrarymember{end}{split_view}%
49254924
\begin{codeblock}
49264925
namespace std::ranges {
49274926
template<auto> struct @\placeholdernc{require-constant}@; // \expos
@@ -4959,6 +4958,9 @@
49594958
constructible_from<Pattern, single_view<range_value_t<R>>>
49604959
constexpr split_view(R&& r, range_value_t<R> e);
49614960

4961+
constexpr V base() const& requires copy_constructible<V> { return base_; }
4962+
constexpr V base() && { return std::move(base_); }
4963+
49624964
constexpr auto begin() {
49634965
if constexpr (forward_range<V>)
49644966
return outer_iterator<@\placeholder{simple-view}@<V>>{*this, ranges::begin(base_)};
@@ -5459,6 +5461,10 @@
54595461
\rSec3[range.common.view]{Class template \tcode{common_view}}
54605462

54615463
\indexlibraryglobal{common_view}%
5464+
\indexlibrarymember{base}{common_view}%
5465+
\indexlibrarymember{size}{common_view}%
5466+
\indexlibrarymember{begin}{common_view}%
5467+
\indexlibrarymember{end}{common_view}%
54625468
\begin{codeblock}
54635469
namespace std::ranges {
54645470
template<view V>
@@ -5475,7 +5481,8 @@
54755481
requires (!common_range<R> && constructible_from<V, all_view<R>>)
54765482
constexpr explicit common_view(R&& r);
54775483

5478-
constexpr V base() const;
5484+
constexpr V base() const& requires copy_constructible<V> { return base_; }
5485+
constexpr V base() && { return std::move(base_); }
54795486

54805487
constexpr auto size() requires sized_range<V> {
54815488
return ranges::size(base_);
@@ -5542,17 +5549,6 @@
55425549
Initializes \tcode{base_} with \tcode{views::all(std::forward<R>(r))}.
55435550
\end{itemdescr}
55445551

5545-
\indexlibrarymember{base}{common_view}%
5546-
\begin{itemdecl}
5547-
constexpr V base() const;
5548-
\end{itemdecl}
5549-
5550-
\begin{itemdescr}
5551-
\pnum
5552-
\effects
5553-
Equivalent to: \tcode{return base_;}
5554-
\end{itemdescr}
5555-
55565552
\rSec3[range.common.adaptor]{\tcode{views::common}}
55575553

55585554
\pnum
@@ -5589,6 +5585,8 @@
55895585
\rSec3[range.reverse.view]{Class template \tcode{reverse_view}}
55905586

55915587
\indexlibraryglobal{reverse_view}%
5588+
\indexlibrarymember{base}{reverse_view}%
5589+
\indexlibrarymember{size}{reverse_view}%
55925590
\begin{codeblock}
55935591
namespace std::ranges {
55945592
template<view V>
@@ -5605,7 +5603,8 @@
56055603
requires bidirectional_range<R> && constructible_from<V, all_view<R>>
56065604
constexpr explicit reverse_view(R&& r);
56075605

5608-
constexpr V base() const;
5606+
constexpr V base() const& requires copy_constructible<V> { return base_; }
5607+
constexpr V base() && { return std::move(base_); }
56095608

56105609
constexpr reverse_iterator<iterator_t<V>> begin();
56115610
constexpr reverse_iterator<iterator_t<V>> begin() requires common_range<V>;
@@ -5653,17 +5652,6 @@
56535652
Initializes \tcode{base_} with \tcode{views::all(std::forward<R>(r))}.
56545653
\end{itemdescr}
56555654

5656-
\indexlibrarymember{base}{reverse_view}%
5657-
\begin{itemdecl}
5658-
constexpr V base() const;
5659-
\end{itemdecl}
5660-
5661-
\begin{itemdescr}
5662-
\pnum
5663-
\effects
5664-
Equivalent to: \tcode{return base_;}
5665-
\end{itemdescr}
5666-
56675655
\indexlibrarymember{begin}{reverse_view}%
56685656
\begin{itemdecl}
56695657
constexpr reverse_iterator<iterator_t<V>> begin();

0 commit comments

Comments
 (0)