|
541 | 541 | class cartesian_product_view; // freestanding
|
542 | 542 |
|
543 | 543 | namespace views { inline constexpr @\unspecnc@ cartesian_product = @\unspecnc@; } // freestanding
|
| 544 | + |
| 545 | + // \ref{range.cache.latest}, cache latest view |
| 546 | + template<@\libconcept{input_range}@ V> |
| 547 | + requires @\libconcept{view}@<V> |
| 548 | + class cache_latest_view; |
| 549 | + |
| 550 | + namespace views { inline constexpr @\unspec@ cache_latest = @\unspec@; } |
544 | 551 | }
|
545 | 552 |
|
546 | 553 | namespace std {
|
|
15684 | 15691 | \begin{itemdescr}
|
15685 | 15692 | \pnum
|
15686 | 15693 | \effects
|
15687 |
| -Equivalent to: \tcode{++*this;} |
| 15694 | +Equivalent to \tcode{++*this;} |
15688 | 15695 | \end{itemdescr}
|
15689 | 15696 |
|
15690 | 15697 | \indexlibrarymember{operator++}{stride_view::\exposid{iterator}}%
|
@@ -16737,6 +16744,346 @@
|
16737 | 16744 | \end{itemize}
|
16738 | 16745 | \end{itemdescr}
|
16739 | 16746 |
|
| 16747 | +\rSec2[range.cache.latest]{Cache latest view} |
| 16748 | + |
| 16749 | +\rSec3[range.cache.latest.overview]{Overview} |
| 16750 | + |
| 16751 | +\pnum |
| 16752 | +\tcode{cache_latest_view} caches the last-accessed element of |
| 16753 | +its underlying sequence |
| 16754 | +so that the element does not have to be recomputed on repeated access. |
| 16755 | +\begin{note} |
| 16756 | +This is useful if computation of the element to produce is expensive. |
| 16757 | +\end{note} |
| 16758 | + |
| 16759 | +\pnum |
| 16760 | +The name \tcode{views::cache_latest} denotes |
| 16761 | +a range adaptor object\iref{range.adaptor.object}. |
| 16762 | +Let \tcode{E} be an expression. |
| 16763 | +The expression \tcode{views::cache_latest(E)} is expression-equivalent to |
| 16764 | +\tcode{cache_latest_view(E)}. |
| 16765 | + |
| 16766 | +\rSec3[range.cache.latest.view]{Class template \tcode{cache_latest_view}} |
| 16767 | + |
| 16768 | +\begin{codeblock} |
| 16769 | +namespace std::ranges { |
| 16770 | + template<@\libconcept{input_range}@ V> |
| 16771 | + requires @\libconcept{view}@<V> |
| 16772 | + class @\libglobal{cache_latest_view}@ : public view_interface<cache_latest_view<V>> { |
| 16773 | + V @\exposid{base_}@ = V(); // \expos |
| 16774 | + using @\exposid{cache-t}@ = conditional_t<is_reference_v<range_reference_t<V>>, // \expos |
| 16775 | + add_pointer_t<range_reference_t<V>>, |
| 16776 | + range_reference_t<V>>; |
| 16777 | + |
| 16778 | + @\exposid{non-propagating-cache}@<cache-t> @\exposid{cache_}@; // \expos |
| 16779 | + |
| 16780 | + class @\exposid{iterator}@; // \expos |
| 16781 | + class @\exposid{sentinel}@; // \expos |
| 16782 | + |
| 16783 | + public: |
| 16784 | + cache_latest_view() requires @\libconcept{default_initializable}@<V> = default; |
| 16785 | + constexpr explicit cache_latest_view(V base); |
| 16786 | + |
| 16787 | + constexpr V base() const & requires @\libconcept{copy_constructible}@<V> { return @\exposid{base_}@; } |
| 16788 | + constexpr V base() && { return std::move(@\exposid{base_}@); } |
| 16789 | + |
| 16790 | + constexpr auto begin(); |
| 16791 | + constexpr auto end(); |
| 16792 | + |
| 16793 | + constexpr auto size() requires @\libconcept{sized_range}@<V>; |
| 16794 | + constexpr auto size() const requires @\libconcept{sized_range}@<const V>; |
| 16795 | + }; |
| 16796 | + |
| 16797 | + template<class R> |
| 16798 | + cache_latest_view(R&&) -> cache_latest_view<views::all_t<R>>; |
| 16799 | +} |
| 16800 | +\end{codeblock} |
| 16801 | + |
| 16802 | +\indexlibraryctor{cache_latest_view}% |
| 16803 | +\begin{itemdecl} |
| 16804 | +constexpr explicit cache_latest_view(V base); |
| 16805 | +\end{itemdecl} |
| 16806 | + |
| 16807 | +\begin{itemdescr} |
| 16808 | +\pnum |
| 16809 | +\effects |
| 16810 | +Initializes \exposid{base_} with \tcode{std::move(base)}. |
| 16811 | +\end{itemdescr} |
| 16812 | + |
| 16813 | +\indexlibrarymember{begin}{cache_latest_view}% |
| 16814 | +\begin{itemdecl} |
| 16815 | +constexpr auto begin(); |
| 16816 | +\end{itemdecl} |
| 16817 | + |
| 16818 | +\begin{itemdescr} |
| 16819 | +\pnum |
| 16820 | +\effects |
| 16821 | +Equivalent to: \tcode{return \exposid{iterator}(*this);} |
| 16822 | +\end{itemdescr} |
| 16823 | + |
| 16824 | +\indexlibrarymember{end}{cache_latest_view}% |
| 16825 | +\begin{itemdecl} |
| 16826 | +constexpr auto end(); |
| 16827 | +\end{itemdecl} |
| 16828 | + |
| 16829 | +\begin{itemdescr} |
| 16830 | +\pnum |
| 16831 | +\effects |
| 16832 | +Equivalent to: \tcode{return \exposid{sentinel}(*this);} |
| 16833 | +\end{itemdescr} |
| 16834 | + |
| 16835 | +\indexlibrarymember{size}{cache_latest_view}% |
| 16836 | +\begin{itemdecl} |
| 16837 | +constexpr auto size() requires sized_range<V>; |
| 16838 | +constexpr auto size() const requires sized_range<const V>; |
| 16839 | +\end{itemdecl} |
| 16840 | + |
| 16841 | +\begin{itemdescr} |
| 16842 | +\pnum |
| 16843 | +\effects |
| 16844 | +Equivalent to: \tcode{return ranges::size(\exposid{base_});} |
| 16845 | +\end{itemdescr} |
| 16846 | + |
| 16847 | +\rSec3[range.cache.latest.iterator]{Class \tcode{cache_latest_view::\exposid{iterator}}} |
| 16848 | + |
| 16849 | +\begin{codeblock} |
| 16850 | +namespace std::ranges { |
| 16851 | + template<@\libconcept{input_range}@ V> |
| 16852 | + requires @\libconcept{view}@<V> |
| 16853 | + class cache_latest_view<V>::@\exposid{iterator}@ { |
| 16854 | + cache_latest_view* @\exposid{parent_}@; // \expos |
| 16855 | + iterator_t<V> @\exposid{current_}@; // \expos |
| 16856 | + |
| 16857 | + constexpr explicit @\exposid{iterator}@(cache_latest_view& parent); // \expos |
| 16858 | + |
| 16859 | + public: |
| 16860 | + using difference_type = range_difference_t<V>; |
| 16861 | + using value_type = range_value_t<V>; |
| 16862 | + using iterator_concept = input_iterator_tag; |
| 16863 | + |
| 16864 | + @\exposid{iterator}@(@\exposid{iterator}@&&) = default; |
| 16865 | + @\exposid{iterator}@& operator=(@\exposid{iterator}@&&) = default; |
| 16866 | + |
| 16867 | + constexpr iterator_t<V> base() &&; |
| 16868 | + constexpr const iterator_t<V>& base() const & noexcept; |
| 16869 | + |
| 16870 | + constexpr range_reference_t<V>& operator*() const; |
| 16871 | + |
| 16872 | + constexpr @\exposid{iterator}@& operator++(); |
| 16873 | + constexpr void operator++(int); |
| 16874 | + |
| 16875 | + friend constexpr range_rvalue_reference_t<V> iter_move(const @\exposid{iterator}@& i) |
| 16876 | + noexcept(noexcept(ranges::iter_move(i.@\exposid{current_}@))); |
| 16877 | + |
| 16878 | + friend constexpr void iter_swap(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) |
| 16879 | + noexcept(noexcept(ranges::iter_swap(x.@\exposid{current_}@, y.@\exposid{current_}@))) |
| 16880 | + requires @\libconcept{indirectly_swappable}@<iterator_t<V>>; |
| 16881 | + }; |
| 16882 | +} |
| 16883 | +\end{codeblock} |
| 16884 | + |
| 16885 | +\indexlibraryctor{cache_latest_view::\exposid{iterator}}% |
| 16886 | +\begin{itemdecl} |
| 16887 | +constexpr explicit @\exposid{iterator}@(cache_latest_view& parent); |
| 16888 | +\end{itemdecl} |
| 16889 | + |
| 16890 | +\begin{itemdescr} |
| 16891 | +\pnum |
| 16892 | +\effects |
| 16893 | +Initializes \exposid{current_} with |
| 16894 | +\tcode{ranges::begin(parent.\exposid{base_})} |
| 16895 | +and \exposid{parent_} with \tcode{addressof(par\-ent)}. |
| 16896 | +\end{itemdescr} |
| 16897 | + |
| 16898 | +\indexlibrarymember{base}{cache_latest_view::\exposid{iterator}}% |
| 16899 | +\begin{itemdecl} |
| 16900 | +constexpr iterator_t<V> base() &&; |
| 16901 | +\end{itemdecl} |
| 16902 | + |
| 16903 | +\begin{itemdescr} |
| 16904 | +\pnum |
| 16905 | +\returns |
| 16906 | +\tcode{std::move(\exposid{current_})}. |
| 16907 | +\end{itemdescr} |
| 16908 | + |
| 16909 | +\indexlibrarymember{base}{cache_latest_view::\exposid{iterator}}% |
| 16910 | +\begin{itemdecl} |
| 16911 | +constexpr const iterator_t<V>& base() const & noexcept; |
| 16912 | +\end{itemdecl} |
| 16913 | + |
| 16914 | +\begin{itemdescr} |
| 16915 | +\pnum |
| 16916 | +\returns |
| 16917 | +\exposid{current_}. |
| 16918 | +\end{itemdescr} |
| 16919 | + |
| 16920 | +\indexlibrarymember{operator++}{cache_latest_view::\exposid{iterator}}% |
| 16921 | +\begin{itemdecl} |
| 16922 | +constexpr iterator& operator++(); |
| 16923 | +\end{itemdecl} |
| 16924 | + |
| 16925 | +\begin{itemdescr} |
| 16926 | +\pnum |
| 16927 | +\effects |
| 16928 | +Equivalent to: |
| 16929 | +\begin{codeblock} |
| 16930 | +@\exposid{parent_}@->@\exposid{cache_}@.reset(); |
| 16931 | +++@\exposid{current_}@; |
| 16932 | +return *this; |
| 16933 | +\end{codeblock} |
| 16934 | +\end{itemdescr} |
| 16935 | + |
| 16936 | +\indexlibrarymember{operator++}{cache_latest_view::\exposid{iterator}}% |
| 16937 | +\begin{itemdecl} |
| 16938 | +constexpr void operator++(int); |
| 16939 | +\end{itemdecl} |
| 16940 | + |
| 16941 | +\begin{itemdescr} |
| 16942 | +\pnum |
| 16943 | +\effects |
| 16944 | +Equivalent to: \tcode{++*this}. |
| 16945 | +\end{itemdescr} |
| 16946 | + |
| 16947 | +\indexlibrarymember{operator*}{cache_latest_view::\exposid{iterator}}% |
| 16948 | +\begin{itemdecl} |
| 16949 | +constexpr range_reference_t<V>& operator*() const; |
| 16950 | +\end{itemdecl} |
| 16951 | + |
| 16952 | +\begin{itemdescr} |
| 16953 | +\pnum |
| 16954 | +\effects |
| 16955 | +Equivalent to: |
| 16956 | +\begin{codeblock} |
| 16957 | +if constexpr (is_reference_v<range_reference_t<V>>) { |
| 16958 | + if (!@\exposid{parent_}@->@\exposid{cache_}@) { |
| 16959 | + @\exposid{parent_}@->@\exposid{cache_}@ = addressof(@\exposid{as-lvalue}@(*@\exposid{current_}@)); |
| 16960 | + } |
| 16961 | + return **@\exposid{parent_}@->@\exposid{cache_}@; |
| 16962 | +} else { |
| 16963 | + if (!@\exposid{parent_}@->c@\exposid{ache_}@) { |
| 16964 | + @\exposid{parent_}@->@\exposid{cache_}@.@\exposid{emplace-deref}@(@\exposid{current_}@); |
| 16965 | + } |
| 16966 | + return *@\exposid{parent_}@->@\exposid{cache_}@; |
| 16967 | +} |
| 16968 | +\end{codeblock} |
| 16969 | +\begin{note} |
| 16970 | +Evaluations of \tcode{operator*} on the same iterator object |
| 16971 | +can conflict\iref{intro.races}. |
| 16972 | +\end{note} |
| 16973 | +\end{itemdescr} |
| 16974 | + |
| 16975 | +\indexlibrarymember{iter_move}{cache_latest_view::\exposid{iterator}}% |
| 16976 | +\begin{itemdecl} |
| 16977 | +friend constexpr range_rvalue_reference_t<V> iter_move(const @\exposid{iterator}@& i) |
| 16978 | + noexcept(noexcept(ranges::iter_move(i.@\exposid{current_}@))); |
| 16979 | +\end{itemdecl} |
| 16980 | + |
| 16981 | +\begin{itemdescr} |
| 16982 | +\pnum |
| 16983 | +\effects |
| 16984 | +Equivalent to: \tcode{return ranges::iter_move(i.\exposid{current_});} |
| 16985 | +\end{itemdescr} |
| 16986 | + |
| 16987 | +\indexlibrarymember{iter_swap}{cache_latest_view::\exposid{iterator}}% |
| 16988 | +\begin{itemdecl} |
| 16989 | +friend constexpr void iter_swap(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) |
| 16990 | + noexcept(noexcept(ranges::iter_swap(x.@\exposid{current_}@, y.@\exposid{current_}@))) |
| 16991 | + requires @\libconcept{indirectly_swappable}@<iterator_t<V>>; |
| 16992 | +\end{itemdecl} |
| 16993 | + |
| 16994 | +\begin{itemdescr} |
| 16995 | +\pnum |
| 16996 | +\effects |
| 16997 | +Equivalent to |
| 16998 | +\tcode{ranges::iter_swap(x.\exposid{current_}, y.\exposid{current_})}. |
| 16999 | +\end{itemdescr} |
| 17000 | + |
| 17001 | +\rSec3[range.cache.latest.sentinel]{Class \tcode{cache_latest_view::\exposid{sentinel}}} |
| 17002 | + |
| 17003 | +\begin{codeblock} |
| 17004 | +namespace std::ranges { |
| 17005 | + template<@\libconcept{input_range}@ V> |
| 17006 | + requires @\libconcept{view}@<V> |
| 17007 | + class cache_latest_view<V>::@\exposid{sentinel}@ { |
| 17008 | + sentinel_t<V> @\exposid{end_}@ = sentinel_t<V>(); // \expos |
| 17009 | + |
| 17010 | + constexpr explicit @\exposid{sentinel}@(cache_latest_view& parent); // \expos |
| 17011 | + |
| 17012 | + public: |
| 17013 | + @\exposid{sentinel}@() = default; |
| 17014 | + |
| 17015 | + constexpr sentinel_t<V> base() const; |
| 17016 | + |
| 17017 | + friend constexpr bool operator==(const @\exposid{iterator}@& x, const @\exposid{sentinel}@& y); |
| 17018 | + |
| 17019 | + friend constexpr range_difference_t<V> operator-(const @\exposid{iterator}@& x, const @\exposid{sentinel}@& y) |
| 17020 | + requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>; |
| 17021 | + friend constexpr range_difference_t<V> operator-(const @\exposid{sentinel}@& x, const @\exposid{iterator}@& y) |
| 17022 | + requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>; |
| 17023 | + }; |
| 17024 | +} |
| 17025 | +\end{codeblock} |
| 17026 | + |
| 17027 | +\indexlibraryctor{cache_latest_view::\exposid{sentinel}}% |
| 17028 | +\begin{itemdecl} |
| 17029 | +constexpr explicit @\exposid{sentinel}@(cache_latest_view& parent); |
| 17030 | +\end{itemdecl} |
| 17031 | + |
| 17032 | +\begin{itemdescr} |
| 17033 | +\pnum |
| 17034 | +\effects |
| 17035 | +Initializes \exposid{end_} with \tcode{ranges::end(parent.\exposid{base_})}. |
| 17036 | +\end{itemdescr} |
| 17037 | + |
| 17038 | +\indexlibrarymember{base}{cache_latest_view::\exposid{sentinel}}% |
| 17039 | +\begin{itemdecl} |
| 17040 | +constexpr sentinel_t<V> base() const; |
| 17041 | +\end{itemdecl} |
| 17042 | + |
| 17043 | +\begin{itemdescr} |
| 17044 | +\pnum |
| 17045 | +\returns |
| 17046 | +\exposid{end_}. |
| 17047 | +\end{itemdescr} |
| 17048 | + |
| 17049 | +\indexlibrarymember{operator==}{cache_latest_view::\exposid{iterator}}% |
| 17050 | +\indexlibrarymember{operator==}{cache_latest_view::\exposid{sentinel}}% |
| 17051 | +\begin{itemdecl} |
| 17052 | +friend constexpr bool operator==(const iterator& x, const sentinel& y); |
| 17053 | +\end{itemdecl} |
| 17054 | + |
| 17055 | +\begin{itemdescr} |
| 17056 | +\pnum |
| 17057 | +\returns |
| 17058 | +\tcode{x.\exposid{current_} == y.\exposid{end_}}. |
| 17059 | +\end{itemdescr} |
| 17060 | + |
| 17061 | +\indexlibrarymember{operator-}{cache_latest_view::\exposid{iterator}}% |
| 17062 | +\indexlibrarymember{operator-}{cache_latest_view::\exposid{sentinel}}% |
| 17063 | +\begin{itemdecl} |
| 17064 | +friend constexpr range_difference_t<V> operator-(const @\exposid{iterator}@& x, const @\exposid{sentinel}@& y) |
| 17065 | + requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>; |
| 17066 | +\end{itemdecl} |
| 17067 | + |
| 17068 | +\begin{itemdescr} |
| 17069 | +\pnum |
| 17070 | +\returns |
| 17071 | +\tcode{x.\exposid{current_} - y.\exposid{end_}}. |
| 17072 | +\end{itemdescr} |
| 17073 | + |
| 17074 | +\indexlibrarymember{operator-}{cache_latest_view::\exposid{iterator}}% |
| 17075 | +\indexlibrarymember{operator-}{cache_latest_view::\exposid{sentinel}}% |
| 17076 | +\begin{itemdecl} |
| 17077 | +friend constexpr range_difference_t<V> operator-(const @\exposid{sentinel}@& x, const @\exposid{iterator}@& y) |
| 17078 | + requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>; |
| 17079 | +\end{itemdecl} |
| 17080 | + |
| 17081 | +\begin{itemdescr} |
| 17082 | +\pnum |
| 17083 | +\returns |
| 17084 | +\tcode{x.\exposid{end_} - y.\exposid{current_}}. |
| 17085 | +\end{itemdescr} |
| 17086 | + |
16740 | 17087 | \rSec1[coro.generator]{Range generators}
|
16741 | 17088 |
|
16742 | 17089 | \rSec2[coroutine.generator.overview]{Overview}
|
|
0 commit comments