Skip to content

Commit 85973aa

Browse files
committed
P2446R2 views::as_rvalue
1 parent 78b91e8 commit 85973aa

File tree

2 files changed

+102
-0
lines changed

2 files changed

+102
-0
lines changed

source/ranges.tex

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,16 @@
222222
template<class T>
223223
inline constexpr bool enable_borrowed_range<owning_view<T>> = enable_borrowed_range<T>;
224224

225+
// \ref{range.as.rvalue}, as rvalue view
226+
template<@\libconcept{view}@ V>
227+
requires @\libconcept{input_range}@<V>
228+
class as_rvalue_view;
229+
230+
template<class T>
231+
inline constexpr bool enable_borrowed_range<as_rvalue_view<T>> = enable_borrowed_range<T>;
232+
233+
namespace views { inline constexpr @\unspec@ as_rvalue = @\unspec@; }
234+
225235
// \ref{range.filter}, filter view
226236
template<@\libconcept{input_range}@ V, @\libconcept{indirect_unary_predicate}@<iterator_t<V>> Pred>
227237
requires @\libconcept{view}@<V> && is_object_v<Pred>
@@ -3803,6 +3813,97 @@
38033813
Initializes \exposid{r_} with \tcode{std::move(t)}.
38043814
\end{itemdescr}
38053815

3816+
\rSec2[range.as.rvalue]{As rvalue view}
3817+
3818+
\rSec3[range.as.rvalue.overview]{Overview}
3819+
3820+
\pnum
3821+
\tcode{as_rvalue_view} presents a \libconcept{view} of an underlying sequence
3822+
with the same behavior as the underlying sequence
3823+
except that its elements are rvalues.
3824+
Some generic algorithms can be called with a \tcode{as_rvalue_view}
3825+
to replace copying with moving.
3826+
3827+
\pnum
3828+
\indexlibrarymember{as_rvalue}{views}%
3829+
The name \tcode{views::as_rvalue} denotes
3830+
a range adaptor object\iref{range.adaptor.object}.
3831+
Let \tcode{E} be an expression and let \tcode{T} be \tcode{decltype((E))}.
3832+
The expression \tcode{views::as_rvalue(E)} is expression-equivalent to:
3833+
\begin{itemize}
3834+
\item
3835+
\tcode{views::all(E)} if \tcode{same_as<range_rvalue_reference_t<T>, range_reference_t<T>>} is \tcode{true}.
3836+
\item
3837+
Otherwise, \tcode{ranges::as_rvalue_view(E)}.
3838+
\end{itemize}
3839+
3840+
\pnum
3841+
\begin{example}
3842+
\begin{codeblock}
3843+
vector<string> words = {"the", "quick", "brown", "fox", "ate", "a", "pterodactyl"};
3844+
vector<string> new_words;
3845+
ranges::copy(words | views::as_rvalue, back_inserter(new_words));
3846+
// moves each string from \tcode{words} into \tcode{new_words}
3847+
\end{codeblock}
3848+
\end{example}
3849+
3850+
\rSec3[range.as.rvalue.view]{Class template \tcode{as_rvalue_view}}
3851+
3852+
\begin{codeblock}
3853+
namespace std::ranges {
3854+
template<@\libconcept{input_range}@ V>
3855+
requires @\libconcept{view}@<V>
3856+
class @\libglobal{as_rvalue_view}@ : public view_interface<as_rvalue_view<V>>
3857+
{
3858+
V @\exposid{base_}@ = V(); // \expos
3859+
3860+
public:
3861+
as_rvalue_view() requires @\libconcept{default_initializable}@<V> = default;
3862+
constexpr explicit as_rvalue_view(V base);
3863+
3864+
constexpr V base() const & requires copy_constructible<V> { return @\exposid{base_}@; }
3865+
constexpr V base() && { return std::move(@\exposid{base_}@); }
3866+
3867+
constexpr auto begin() requires (!@\exposconcept{simple-view}@<V>)
3868+
{ return move_iterator(ranges::begin(@\exposid{base_}@)); }
3869+
constexpr auto begin() const requires @\libconcept{range}@<const V>
3870+
{ return move_iterator(ranges::begin(@\exposid{base_}@)); }
3871+
3872+
constexpr auto end() requires (!@\exposconcept{simple-view}@<V>) {
3873+
if constexpr (@\libconcept{common_range}@<V>) {
3874+
return move_iterator(ranges::end(@\exposid{base_}@));
3875+
} else {
3876+
return move_sentinel(ranges::end(@\exposid{base_}@));
3877+
}
3878+
}
3879+
constexpr auto end() const requires @\libconcept{range}@<const V> {
3880+
if constexpr (@\libconcept{common_range}@<const V>) {
3881+
return move_iterator(ranges::end(@\exposid{base_}@));
3882+
} else {
3883+
return move_sentinel(ranges::end(@\exposid{base_}@));
3884+
}
3885+
}
3886+
3887+
constexpr auto size() requires @\libconcept{sized_range}@<V> { return ranges::size(@\exposid{base_}@); }
3888+
constexpr auto size() const requires @\libconcept{sized_range}@<const V> { return ranges::size(@\exposid{base_}@); }
3889+
};
3890+
3891+
template<class R>
3892+
as_rvalue_view(R&&) -> as_rvalue_view<views::all_t<R>>;
3893+
}
3894+
\end{codeblock}
3895+
3896+
\indexlibraryctor{as_rvalue_view}%
3897+
\begin{itemdecl}
3898+
constexpr explicit as_rvalue_view(V base);
3899+
\end{itemdecl}
3900+
3901+
\begin{itemdescr}
3902+
\pnum
3903+
\effects
3904+
Initializes \exposid{base_} with \tcode{std::move(base)}.
3905+
\end{itemdescr}
3906+
38063907
\rSec2[range.filter]{Filter view}
38073908

38083909
\rSec3[range.filter.overview]{Overview}

source/support.tex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,7 @@
671671
#define @\defnlibxname{cpp_lib_quoted_string_io}@ 201304L // also in \libheader{iomanip}
672672
#define @\defnlibxname{cpp_lib_ranges}@ 202202L
673673
// also in \libheader{algorithm}, \libheader{functional}, \libheader{iterator}, \libheader{memory}, \libheader{ranges}
674+
#define @\defnlibxname{cpp_lib_ranges_as_rvalue}@ 202207L // also in \libheader{ranges}
674675
#define @\defnlibxname{cpp_lib_ranges_chunk}@ 202202L // also in \libheader{ranges}
675676
#define @\defnlibxname{cpp_lib_ranges_chunk_by}@ 202202L // also in \libheader{ranges}
676677
#define @\defnlibxname{cpp_lib_ranges_iota}@ 202202L // also in \libheader{numeric}

0 commit comments

Comments
 (0)