Skip to content

P2446R2 views::as_rvalue #5708

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions source/ranges.tex
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,16 @@
inline constexpr bool enable_borrowed_range<owning_view<T>> = // freestanding
enable_borrowed_range<T>;

// \ref{range.as.rvalue}, as rvalue view
template<@\libconcept{view}@ V>
requires @\libconcept{input_range}@<V>
class as_rvalue_view; // freestanding

template<class T>
inline constexpr bool enable_borrowed_range<as_rvalue_view<T>> = enable_borrowed_range<T>;

namespace views { inline constexpr @\unspecnc@ as_rvalue = @\unspecnc@; } // freestanding

// \ref{range.filter}, filter view
template<@\libconcept{input_range}@ V, @\libconcept{indirect_unary_predicate}@<iterator_t<V>> Pred>
requires @\libconcept{view}@<V> && is_object_v<Pred>
Expand Down Expand Up @@ -3953,6 +3963,97 @@
Initializes \exposid{r_} with \tcode{std::move(t)}.
\end{itemdescr}

\rSec2[range.as.rvalue]{As rvalue view}

\rSec3[range.as.rvalue.overview]{Overview}

\pnum
\tcode{as_rvalue_view} presents a \libconcept{view} of an underlying sequence
with the same behavior as the underlying sequence
except that its elements are rvalues.
Some generic algorithms can be called with a \tcode{as_rvalue_view}
to replace copying with moving.

\pnum
\indexlibrarymember{as_rvalue}{views}%
The name \tcode{views::as_rvalue} denotes
a range adaptor object\iref{range.adaptor.object}.
Let \tcode{E} be an expression and let \tcode{T} be \tcode{decltype((E))}.
The expression \tcode{views::as_rvalue(E)} is expression-equivalent to:
\begin{itemize}
\item
\tcode{views::all(E)} if \tcode{same_as<range_rvalue_reference_t<T>, range_reference_t<T>>} is \tcode{true}.
\item
Otherwise, \tcode{as_rvalue_view(E)}.
\end{itemize}

\pnum
\begin{example}
\begin{codeblock}
vector<string> words = {"the", "quick", "brown", "fox", "ate", "a", "pterodactyl"};
vector<string> new_words;
ranges::copy(words | views::as_rvalue, back_inserter(new_words));
// moves each string from \tcode{words} into \tcode{new_words}
\end{codeblock}
\end{example}

\rSec3[range.as.rvalue.view]{Class template \tcode{as_rvalue_view}}

\begin{codeblock}
namespace std::ranges {
template<@\libconcept{input_range}@ V>
requires @\libconcept{view}@<V>
class @\libglobal{as_rvalue_view}@ : public view_interface<as_rvalue_view<V>>
{
V @\exposid{base_}@ = V(); // \expos

public:
as_rvalue_view() requires @\libconcept{default_initializable}@<V> = default;
constexpr explicit as_rvalue_view(V base);

constexpr V base() const & requires copy_constructible<V> { return @\exposid{base_}@; }
constexpr V base() && { return std::move(@\exposid{base_}@); }

constexpr auto begin() requires (!@\exposconcept{simple-view}@<V>)
{ return move_iterator(ranges::begin(@\exposid{base_}@)); }
constexpr auto begin() const requires @\libconcept{range}@<const V>
{ return move_iterator(ranges::begin(@\exposid{base_}@)); }

constexpr auto end() requires (!@\exposconcept{simple-view}@<V>) {
if constexpr (@\libconcept{common_range}@<V>) {
return move_iterator(ranges::end(@\exposid{base_}@));
} else {
return move_sentinel(ranges::end(@\exposid{base_}@));
}
}
constexpr auto end() const requires @\libconcept{range}@<const V> {
if constexpr (@\libconcept{common_range}@<const V>) {
return move_iterator(ranges::end(@\exposid{base_}@));
} else {
return move_sentinel(ranges::end(@\exposid{base_}@));
}
}

constexpr auto size() requires @\libconcept{sized_range}@<V> { return ranges::size(@\exposid{base_}@); }
constexpr auto size() const requires @\libconcept{sized_range}@<const V> { return ranges::size(@\exposid{base_}@); }
};

template<class R>
as_rvalue_view(R&&) -> as_rvalue_view<views::all_t<R>>;
}
\end{codeblock}

\indexlibraryctor{as_rvalue_view}%
\begin{itemdecl}
constexpr explicit as_rvalue_view(V base);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes \exposid{base_} with \tcode{std::move(base)}.
\end{itemdescr}

\rSec2[range.filter]{Filter view}

\rSec3[range.filter.overview]{Overview}
Expand Down
1 change: 1 addition & 0 deletions source/support.tex
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,7 @@
#define @\defnlibxname{cpp_lib_ranges}@ 202202L
// also in \libheader{algorithm}, \libheader{functional}, \libheader{iterator}, \libheader{memory}, \libheader{ranges}
#define @\defnlibxname{cpp_lib_ranges_as_const}@ 202207L // also in \libheader{ranges}
#define @\defnlibxname{cpp_lib_ranges_as_rvalue}@ 202207L // also in \libheader{ranges}
#define @\defnlibxname{cpp_lib_ranges_cartesian_product}@ 202207L // also in \libheader{ranges}
#define @\defnlibxname{cpp_lib_ranges_chunk}@ 202202L // also in \libheader{ranges}
#define @\defnlibxname{cpp_lib_ranges_chunk_by}@ 202202L // also in \libheader{ranges}
Expand Down