From 9418a95824a24057f6733155e8266d41e0b9758d Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Wed, 9 Jun 2021 17:47:24 +0200 Subject: [PATCH] P1659R3 starts_with and ends_with --- source/algorithms.tex | 105 ++++++++++++++++++++++++++++++++++++++++++ source/support.tex | 1 + 2 files changed, 106 insertions(+) diff --git a/source/algorithms.tex b/source/algorithms.tex index e1e1a470c4..d5b735317a 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -1131,6 +1131,36 @@ constexpr ForwardIterator search(ForwardIterator first, ForwardIterator last, const Searcher& searcher); + namespace ranges { + // \ref{alg.starts.with}, starts with + template<@\libconcept{input_iterator}@ I1, @\libconcept{sentinel_for}@ S1, @\libconcept{input_iterator}@ I2, @\libconcept{sentinel_for}@ S2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@ + constexpr bool starts_with(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); + template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2, class Pred = ranges::equal_to, + class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + constexpr bool starts_with(R1&& r1, R2&& r2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); + + // \ref{alg.ends.with}, ends with + template<@\libconcept{input_iterator}@ I1, @\libconcept{sentinel_for}@ S1, @\libconcept{input_iterator}@ I2, @\libconcept{sentinel_for}@ S2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires (@\libconcept{forward_iterator}@ || @\libconcept{sized_sentinel_for}@) && + (@\libconcept{forward_iterator}@ || @\libconcept{sized_sentinel_for}@) && + @\libconcept{indirectly_comparable}@ + constexpr bool ends_with(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); + template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2, class Pred = ranges::equal_to, + class Proj1 = identity, class Proj2 = identity> + requires (@\libconcept{forward_range}@ || @\libconcept{sized_range}@) && + (@\libconcept{forward_range}@ || @\libconcept{sized_range}@) && + @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + constexpr bool ends_with(R1&& r1, R2&& r2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); + } + // \ref{alg.modifying.operations}, mutating sequence operations // \ref{alg.copy}, copy template @@ -4219,6 +4249,81 @@ \tcode{Searcher} need not meet the \oldconcept{CopyConstructible} requirements. \end{itemdescr} +\rSec2[alg.starts.with]{Starts with} + +\indexlibraryglobal{starts_with}% +\begin{itemdecl} +template<@\libconcept{input_iterator}@ I1, @\libconcept{sentinel_for}@ S1, @\libconcept{input_iterator}@ I2, @\libconcept{sentinel_for}@ S2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@ + constexpr bool ranges::starts_with(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); +template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2, class Pred = ranges::equal_to, class Proj1 = identity, + class Proj2 = identity> + requires @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + constexpr bool ranges::starts_with(R1&& r1, R2&& r2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{codeblock} +ranges::mismatch(std::move(first1), last1, std::move(first2), last2, + pred, proj1, proj2).in2 == last2 +\end{codeblock} +\end{itemdescr} + +\rSec2[alg.ends.with]{Ends with} + +\indexlibraryglobal{ends_with}% +\begin{itemdecl} +template<@\libconcept{input_iterator}@ I1, @\libconcept{sentinel_for}@ S1, @\libconcept{input_iterator}@ I2, @\libconcept{sentinel_for}@ S2, + class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> + requires (@\libconcept{forward_iterator}@ || @\libconcept{sized_sentinel_for}@) && + (@\libconcept{forward_iterator}@ || @\libconcept{sized_sentinel_for}@) && + @\libconcept{indirectly_comparable}@ + constexpr bool ranges::ends_with(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{N1} be \tcode{last1 - first1} and +\tcode{N2} be \tcode{last2 - first2}. + +\pnum +\returns +\tcode{false} if $\tcode{N1} < \tcode{N2}$, otherwise +\begin{codeblock} +ranges::equal(std::move(first1) + (N1 - N2), last1, std::move(first2), last2, + pred, proj1, proj2) +\end{codeblock} +\end{itemdescr} + +\begin{itemdecl} +template<@\libconcept{input_range}@ R1, @\libconcept{input_range}@ R2, class Pred = ranges::equal_to, class Proj1 = identity, + class Proj2 = identity> + requires (@\libconcept{forward_range}@ || @\libconcept{sized_range}@) && + (@\libconcept{forward_range}@ || @\libconcept{sized_range}@) && + @\libconcept{indirectly_comparable}@, iterator_t, Pred, Proj1, Proj2> + constexpr bool ranges::ends_with(R1&& r1, R2&& r2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{N1} be \tcode{ranges::distance(r1)} and +\tcode{N2} be \tcode{ranges::distance(r2)}. + +\pnum +\returns +\tcode{false} if $\tcode{N1} < \tcode{N2}$, otherwise +\begin{codeblock} +ranges::equal(ranges::drop_view(ranges::ref_view(r1), N1 - N2), r2, pred, proj1, proj2) +\end{codeblock} +\end{itemdescr} + \rSec1[alg.modifying.operations]{Mutating sequence operations} \rSec2[alg.copy]{Copy} diff --git a/source/support.tex b/source/support.tex index fbd2b51ab5..fa649bab01 100644 --- a/source/support.tex +++ b/source/support.tex @@ -661,6 +661,7 @@ #define @\defnlibxname{cpp_lib_quoted_string_io}@ 201304L // also in \libheader{iomanip} #define @\defnlibxname{cpp_lib_ranges}@ 201911L // also in \libheader{algorithm}, \libheader{functional}, \libheader{iterator}, \libheader{memory}, \libheader{ranges} +#define @\defnlibxname{cpp_lib_ranges_starts_ends_with}@ 202106L // also in \libheader{algorithm} #define @\defnlibxname{cpp_lib_raw_memory_algorithms}@ 201606L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_remove_cvref}@ 201711L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_result_of_sfinae}@ 201210L // also in \libheader{functional}, \libheader{type_traits}