|
222 | 222 | template<class T>
|
223 | 223 | inline constexpr bool enable_borrowed_range<owning_view<T>> = enable_borrowed_range<T>;
|
224 | 224 |
|
| 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 | + |
225 | 235 | // \ref{range.filter}, filter view
|
226 | 236 | template<@\libconcept{input_range}@ V, @\libconcept{indirect_unary_predicate}@<iterator_t<V>> Pred>
|
227 | 237 | requires @\libconcept{view}@<V> && is_object_v<Pred>
|
|
3803 | 3813 | Initializes \exposid{r_} with \tcode{std::move(t)}.
|
3804 | 3814 | \end{itemdescr}
|
3805 | 3815 |
|
| 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 | + |
3806 | 3907 | \rSec2[range.filter]{Filter view}
|
3807 | 3908 |
|
3808 | 3909 | \rSec3[range.filter.overview]{Overview}
|
|
0 commit comments