Skip to content

Commit 0e87f77

Browse files
committed
P3137R3 views::to_input
1 parent 422ded5 commit 0e87f77

File tree

2 files changed

+295
-0
lines changed

2 files changed

+295
-0
lines changed

source/ranges.tex

Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,17 @@
548548
class cache_latest_view;
549549

550550
namespace views { inline constexpr @\unspec@ cache_latest = @\unspec@; }
551+
552+
// \ref{range.to.input}, to input view
553+
template<@\libconcept{input_range}@ V>
554+
requires @\libconcept{view}@<V>
555+
class to_input_view;
556+
557+
template<class V>
558+
constexpr bool enable_borrowed_range<to_input_view<V>> =
559+
enable_borrowed_range<V>;
560+
561+
namespace views { inline constexpr @\unspec@ to_input = @\unspec@; }
551562
}
552563

553564
namespace std {
@@ -17085,6 +17096,289 @@
1708517096
\tcode{x.\exposid{end_} - y.\exposid{current_}}.
1708617097
\end{itemdescr}
1708717098

17099+
\rSec2[range.to.input]{To input view}
17100+
17101+
\rSec3[range.to.input.overview]{Overview}
17102+
17103+
\pnum
17104+
\tcode{to_input_view} presents a view of an underlying sequence
17105+
as an input-only non-common range.
17106+
\begin{note}
17107+
This is useful to avoid overhead
17108+
that may be necessary to provide support for the operations
17109+
needed for greater iterator strength.
17110+
\end{note}
17111+
17112+
\pnum
17113+
The name \tcode{views::to_input} denotes
17114+
a range adaptor object\iref{range.adaptor.object}.
17115+
Let \tcode{E} be an expression and let \tcode{T} be \tcode{decltype((E))}.
17116+
The expression \tcode{views::to_input(E)} is expression-equivalent to:
17117+
\begin{itemize}
17118+
\item
17119+
\tcode{views::all(E)}
17120+
if \tcode{T} models \libconcept{input_range},
17121+
does not satisfy \libconcept{common_range}, and
17122+
does not satisfy \libconcept{forward_range};
17123+
\item
17124+
Otherwise, \tcode{to_input_view(E)}.
17125+
\end{itemize}
17126+
17127+
\rSec3[range.to.input.view]{Class template \tcode{to_input_view}}
17128+
17129+
\begin{codeblock}
17130+
template<@\libconcept{input_range}@ V>
17131+
requires @\libconcept{view}@<V>
17132+
class to_input_view : public view_interface<to_input_view<V>> {
17133+
V @\exposid{base_}@ = V(); // \expos
17134+
17135+
template<bool Const> class @\exposid{iterator}@; // \expos
17136+
17137+
public:
17138+
to_input_view() requires @\libconcept{default_initializable}@<V> = default;
17139+
constexpr explicit to_input_view(V base);
17140+
17141+
constexpr V base() const & requires @\libconcept{copy_constructible}@<V> { return @\exposid{base_}@; }
17142+
constexpr V base() && { return std::move(@\exposid{base_}@); }
17143+
17144+
constexpr auto begin() requires (!@\exposconcept{simple-view}@<V>);
17145+
constexpr auto begin() const requires @\libconcept{range}@<const V>;
17146+
17147+
constexpr auto end() requires (!@\exposconcept{simple-view}@<V>);
17148+
constexpr auto end() const requires @\libconcept{range}@<const V>;
17149+
17150+
constexpr auto size() requires @\libconcept{sized_range}@<V>;
17151+
constexpr auto size() const requires @\libconcept{sized_range}@<const V>;
17152+
};
17153+
17154+
template<class R>
17155+
to_input_view(R&&) -> to_input_view<views::all_t<R>>;
17156+
\end{codeblock}
17157+
17158+
\begin{itemdecl}
17159+
constexpr explicit to_input_view(V base);
17160+
\end{itemdecl}
17161+
17162+
\begin{itemdescr}
17163+
\pnum
17164+
\effects
17165+
Initializes \exposid{base_} with std::move(base).
17166+
\end{itemdescr}
17167+
17168+
\begin{itemdecl}
17169+
constexpr auto begin() requires (!@\exposconcept{simple-view}@<V>);
17170+
\end{itemdecl}
17171+
17172+
\begin{itemdescr}
17173+
\pnum
17174+
\effects
17175+
Equivalent to: \tcode{return \exposid{iterator}<false>(ranges::begin(\exposid{base_}));}
17176+
\end{itemdescr}
17177+
17178+
\begin{itemdecl}
17179+
constexpr auto begin() const requires @\libconcept{range}@<const V>;
17180+
\end{itemdecl}
17181+
17182+
\begin{itemdescr}
17183+
\pnum
17184+
\effects
17185+
Equivalent to: \tcode{return \exposid{iterator}<true>(ranges::begin(\exposid{base_}));}
17186+
\end{itemdescr}
17187+
17188+
\begin{itemdecl}
17189+
constexpr auto end() requires (!@\exposconcept{simple-view}@<V>);
17190+
constexpr auto end() const requires @\libconcept{range}@<const V>;
17191+
\end{itemdecl}
17192+
17193+
\begin{itemdescr}
17194+
\pnum
17195+
\effects
17196+
Equivalent to: \tcode{return ranges::end(\exposid{base_});}
17197+
\end{itemdescr}
17198+
17199+
\begin{itemdecl}
17200+
constexpr auto size() requires @\libconcept{sized_range}@<V>;
17201+
constexpr auto size() const requires @\libconcept{sized_range}@<const V>;
17202+
\end{itemdecl}
17203+
17204+
\begin{itemdescr}
17205+
\pnum
17206+
\effects
17207+
Equivalent to: \tcode{return ranges::size(\exposid{base_});}
17208+
\end{itemdescr}
17209+
17210+
\rSec3[range.to.input.iterator]{Class template \tcode{to_input_view::\exposid{iterator}}}
17211+
17212+
\begin{codeblock}
17213+
namespace std::ranges {
17214+
template<@\libconcept{input_range}@ V>
17215+
requires @\libconcept{view}@<V>
17216+
template<bool Const>
17217+
class to_input_view<V>::@\exposid{iterator}@ {
17218+
using @\exposid{Base}@ = @\exposid{maybe-const}@<Const, V>; // \expos
17219+
17220+
iterator_t<@\exposid{Base}@> @\exposid{current_}@ = iterator_t<@\exposid{Base}@>(); // \expos
17221+
17222+
constexpr explicit @\exposid{iterator}@(iterator_t<@\exposid{Base}@> current); // \expos
17223+
17224+
public:
17225+
using difference_type = range_difference_t<@\exposid{Base}@>;
17226+
using value_type = range_value_t<@\exposid{Base}@>;
17227+
using iterator_concept = input_iterator_tag;
17228+
17229+
@\exposid{iterator}@() requires @\libconcept{default_initializable}@<iterator_t<@\exposid{Base}@>> = default;
17230+
17231+
@\exposid{iterator}@(@\exposid{iterator}@&&) = default;
17232+
@\exposid{iterator}@& operator=(@\exposid{iterator}@&&) = default;
17233+
17234+
constexpr @\exposid{iterator}@(@\exposid{iterator}@<!Const> i)
17235+
requires Const && @\libconcept{convertible_to}@<iterator_t<V>, iterator_t<@\exposid{Base}@>>;
17236+
17237+
constexpr iterator_t<@\exposid{Base}@> base() &&;
17238+
constexpr const iterator_t<@\exposid{Base}@>& base() const & noexcept;
17239+
17240+
constexpr decltype(auto) operator*() const { return *@\exposid{current_}@; }
17241+
17242+
constexpr @\exposid{iterator}@& operator++();
17243+
constexpr void operator++(int);
17244+
17245+
friend constexpr bool operator==(const @\exposid{iterator}@& x, const sentinel_t<@\exposid{Base}@>& y);
17246+
17247+
friend constexpr difference_type operator-(const sentinel_t<@\exposid{Base}@>& y, const @\exposid{iterator}@& x)
17248+
requires @\libconcept{sized_sentinel_for}@<sentinel_t<@\exposid{Base}@>, iterator_t<@\exposid{Base}@>>;
17249+
friend constexpr difference_type operator-(const @\exposid{iterator}@& x, const sentinel_t<@\exposid{Base}@>& y)
17250+
requires @\libconcept{sized_sentinel_for}@<sentinel_t<@\exposid{Base}@>, iterator_t<@\exposid{Base}@>>;
17251+
17252+
friend constexpr range_rvalue_reference_t<@\exposid{Base}@> iter_move(const @\exposid{iterator}@& i)
17253+
noexcept(noexcept(ranges::iter_move(i.@\exposid{current_}@)));
17254+
17255+
friend constexpr void iter_swap(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y)
17256+
noexcept(noexcept(ranges::iter_swap(x.@\exposid{current_}@, y.@\exposid{current_}@)))
17257+
requires @\libconcept{indirectly_swappable}@<iterator_t<@\exposid{Base}@>>;
17258+
};
17259+
}
17260+
\end{codeblock}
17261+
17262+
\begin{itemdecl}
17263+
constexpr explicit @\exposid{iterator}@(iterator_t<@\exposid{Base}@> current);
17264+
\end{itemdecl}
17265+
17266+
\begin{itemdescr}
17267+
\pnum
17268+
\effects
17269+
Initializes \exposid{current_} with \tcode{std::move(current)}.
17270+
\end{itemdescr}
17271+
17272+
\begin{itemdecl}
17273+
constexpr @\exposid{iterator}@(@\exposid{iterator}@<!Const> i)
17274+
requires Const && @\libconcept{convertible_to}@<iterator_t<V>, iterator_t<Base>>;
17275+
\end{itemdecl}
17276+
17277+
\begin{itemdescr}
17278+
\pnum
17279+
\effects
17280+
Initializes \exposid{current_} with \tcode{std::move(i.\exposid{current_})}.
17281+
\end{itemdescr}
17282+
17283+
\begin{itemdecl}
17284+
constexpr iterator_t<Base> base() &&;
17285+
\end{itemdecl}
17286+
17287+
\begin{itemdescr}
17288+
\pnum
17289+
\returns
17290+
\tcode{std::move(\exposid{current_)}}.
17291+
\end{itemdescr}
17292+
17293+
\begin{itemdecl}
17294+
constexpr const iterator_t<Base>& base() const & noexcept;
17295+
\end{itemdecl}
17296+
17297+
\begin{itemdescr}
17298+
\pnum
17299+
\returns
17300+
\exposid{current_}.
17301+
\end{itemdescr}
17302+
17303+
\begin{itemdecl}
17304+
constexpr iterator& operator++();
17305+
\end{itemdecl}
17306+
17307+
\begin{itemdescr}
17308+
\pnum
17309+
\effects
17310+
Equivalent to:
17311+
\begin{codeblock}
17312+
++@\exposid{current_}@;
17313+
return *this;
17314+
\end{codeblock}
17315+
\end{itemdescr}
17316+
17317+
\begin{itemdecl}
17318+
constexpr void operator++(int);
17319+
\end{itemdecl}
17320+
17321+
\begin{itemdescr}
17322+
\pnum
17323+
\effects
17324+
Equivalent to: \tcode{++*this;}
17325+
\end{itemdescr}
17326+
17327+
\begin{itemdecl}
17328+
friend constexpr bool operator==(const @\exposid{iterator}@& x, const sentinel_t<Base>& y);
17329+
\end{itemdecl}
17330+
17331+
\begin{itemdescr}
17332+
\pnum
17333+
\returns
17334+
\tcode{x.\exposid{current_} == y}.
17335+
\end{itemdescr}
17336+
17337+
\begin{itemdecl}
17338+
friend constexpr difference_type operator-(const sentinel_t<@\exposid{Base}@>& y, const @\exposid{iterator}@& x)
17339+
requires @\libconcept{sized_sentinel_for}@<sentinel_t<@\exposid{Base}@>, iterator_t<@\exposid{Base}@>>;
17340+
\end{itemdecl}
17341+
17342+
\begin{itemdescr}
17343+
\pnum
17344+
\returns
17345+
\tcode{y - x.\exposid{current_}}.
17346+
\end{itemdescr}
17347+
17348+
\begin{itemdecl}
17349+
friend constexpr difference_type operator-(const @\exposid{iterator}@& x, const sentinel_t<@\exposid{Base}@>& y)
17350+
requires @\libconcept{sized_sentinel_for}@<sentinel_t<@\exposid{Base}@>, iterator_t<@\exposid{Base}@>>;
17351+
\end{itemdecl}
17352+
17353+
\begin{itemdescr}
17354+
\pnum
17355+
\returns
17356+
\tcode{x.\exposid{current_} - y}.
17357+
\end{itemdescr}
17358+
17359+
\begin{itemdecl}
17360+
friend constexpr range_rvalue_reference_t<@\exposid{Base}@> iter_move(const @\exposid{iterator}@& i)
17361+
noexcept(noexcept(ranges::iter_move(i.@\exposid{current_}@)));
17362+
\end{itemdecl}
17363+
17364+
\begin{itemdescr}
17365+
\pnum
17366+
\effects
17367+
Equivalent to: \tcode{return ranges::iter_move(i.\exposid{current_});}
17368+
\end{itemdescr}
17369+
17370+
\begin{itemdecl}
17371+
friend constexpr void iter_swap(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y)
17372+
noexcept(noexcept(ranges::iter_swap(x.@\exposid{current_}@, y.@\exposid{current_)}@))
17373+
requires @\libconcept{indirectly_swappable}@<iterator_t<@\exposid{Base}@>>;
17374+
\end{itemdecl}
17375+
17376+
\begin{itemdescr}
17377+
\pnum
17378+
\effects
17379+
Equivalent to: \tcode{ranges::iter_swap(x.\exposid{current_}, y.\exposid{current_});}
17380+
\end{itemdescr}
17381+
1708817382
\rSec1[coro.generator]{Range generators}
1708917383

1709017384
\rSec2[coroutine.generator.overview]{Overview}

source/support.tex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,7 @@
761761
#define @\defnlibxname{cpp_lib_ranges_starts_ends_with}@ 202106L // also in \libheader{algorithm}
762762
#define @\defnlibxname{cpp_lib_ranges_stride}@ 202207L // freestanding, also in \libheader{ranges}
763763
#define @\defnlibxname{cpp_lib_ranges_to_container}@ 202202L // freestanding, also in \libheader{ranges}
764+
#define @\defnlibxname{cpp_lib_ranges_to_input}@ 202502L // freestanding, also in \libheader{ranges}
764765
#define @\defnlibxname{cpp_lib_ranges_zip}@ 202110L
765766
// freestanding, also in \libheader{ranges}, \libheader{tuple}, \libheader{utility}
766767
#define @\defnlibxname{cpp_lib_ratio}@ 202306L // freestanding, also in \libheader{ratio}

0 commit comments

Comments
 (0)