Skip to content

Commit 2051755

Browse files
committed
[libc++] Implement ranges::starts_with
1 parent ca39168 commit 2051755

File tree

10 files changed

+374
-5
lines changed

10 files changed

+374
-5
lines changed

libcxx/include/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ set(files
166166
__algorithm/ranges_sort_heap.h
167167
__algorithm/ranges_stable_partition.h
168168
__algorithm/ranges_stable_sort.h
169+
__algorithm/ranges_starts_with.h
169170
__algorithm/ranges_swap_ranges.h
170171
__algorithm/ranges_transform.h
171172
__algorithm/ranges_unique.h
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef _LIBCPP___ALGORITHM_RANGES_STARTS_WITH_H
10+
#define _LIBCPP___ALGORITHM_RANGES_STARTS_WITH_H
11+
12+
#include "ranges_mismatch.h"
13+
#include <__algorithm/in_in_result.h>
14+
#include <__config>
15+
#include <__functional/identity.h>
16+
#include <__functional/ranges_operations.h>
17+
#include <__iterator/concepts.h>
18+
#include <__iterator/indirectly_comparable.h>
19+
#include <__ranges/access.h>
20+
#include <__ranges/concepts.h>
21+
#include <__utility/move.h>
22+
23+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
24+
# pragma GCC system_header
25+
#endif
26+
27+
#if _LIBCPP_STD_VER >= 23
28+
29+
_LIBCPP_BEGIN_NAMESPACE_STD
30+
31+
namespace ranges {
32+
namespace __starts_with {
33+
struct __fn {
34+
template <input_iterator _Iter1,
35+
sentinel_for<_Iter1> _Sent1,
36+
input_iterator _Iter2,
37+
sentinel_for<_Iter2> _Sent2,
38+
class _Pred = ranges::equal_to,
39+
class _Proj1 = identity,
40+
class _Proj2 = identity>
41+
requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
42+
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
43+
_Iter1 __first1,
44+
_Sent1 __last1,
45+
_Iter2 __first2,
46+
_Sent2 __last2,
47+
_Pred __pred = {},
48+
_Proj1 __proj1 = {},
49+
_Proj2 __proj2 = {}) const {
50+
return __mismatch::__fn::__go(
51+
std::move(__first1),
52+
std::move(__last1),
53+
std::move(__first2),
54+
std::move(__last2),
55+
__pred,
56+
__proj1,
57+
__proj2)
58+
.in2 == __last2;
59+
}
60+
61+
template <input_range _Range1,
62+
input_range _Range2,
63+
class _Pred = ranges::equal_to,
64+
class _Proj1 = identity,
65+
class _Proj2 = identity>
66+
requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2>
67+
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
68+
_Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
69+
return __mismatch::__fn::__go(
70+
ranges::begin(__range1),
71+
ranges::end(__range1),
72+
ranges::begin(__range2),
73+
ranges::end(__range2),
74+
__pred,
75+
__proj1,
76+
__proj2)
77+
.in2 == ranges::end(__range2);
78+
}
79+
};
80+
} // namespace __starts_with
81+
inline namespace __cpo {
82+
inline constexpr auto starts_with = __starts_with::__fn{};
83+
} // namespace __cpo
84+
} // namespace ranges
85+
86+
_LIBCPP_END_NAMESPACE_STD
87+
88+
#endif // _LIBCPP_STD_VER >= 23
89+
90+
#endif // _LIBCPP___ALGORITHM_RANGES_STARTS_WITH_H

libcxx/include/algorithm

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,18 @@ namespace ranges {
446446
indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
447447
constexpr bool ranges::none_of(R&& r, Pred pred, Proj proj = {}); // since C++20
448448
449+
template<input_iterator I1, sentinel_for<I1> S1, input_iterator I2, sentinel_for<I2> S2,
450+
class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity>
451+
requires indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
452+
constexpr bool ranges::starts_with(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {},
453+
Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++23
454+
455+
template<input_range R1, input_range R2, class Pred = ranges::equal_to, class Proj1 = identity,
456+
class Proj2 = identity>
457+
requires indirectly_comparable<iterator_t<R1>, iterator_t<R2>, Pred, Proj1, Proj2>
458+
constexpr bool ranges::starts_with(R1&& r1, R2&& r2, Pred pred = {},
459+
Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++23
460+
449461
template<input_iterator I1, sentinel_for<I1> S1,
450462
random_access_iterator I2, sentinel_for<I2> S2,
451463
class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity>
@@ -1874,6 +1886,7 @@ template <class BidirectionalIterator, class Compare>
18741886
#include <__algorithm/ranges_sort_heap.h>
18751887
#include <__algorithm/ranges_stable_partition.h>
18761888
#include <__algorithm/ranges_stable_sort.h>
1889+
#include <__algorithm/ranges_starts_with.h>
18771890
#include <__algorithm/ranges_swap_ranges.h>
18781891
#include <__algorithm/ranges_transform.h>
18791892
#include <__algorithm/ranges_unique.h>

libcxx/include/module.modulemap.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,7 @@ module std [system] {
578578
private header "__algorithm/ranges_stable_sort.h"
579579
export functional.__functional.ranges_operations
580580
}
581+
module ranges_starts_with { private header "__algorithm/ranges_starts_with.h" }
581582
module ranges_swap_ranges {
582583
private header "__algorithm/ranges_swap_ranges.h"
583584
export algorithm.__algorithm.in_in_result

libcxx/test/libcxx/algorithms/ranges_robust_against_copying_comparators.pass.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,8 @@ constexpr bool all_the_algorithms()
215215
if (!std::is_constant_evaluated()) { (void)std::ranges::stable_sort(first, last, Less(&copies)); assert(copies == 0); }
216216
if (!std::is_constant_evaluated()) { (void)std::ranges::stable_sort(a, Less(&copies)); assert(copies == 0); }
217217
#if TEST_STD_VER > 20
218-
//(void)std::ranges::starts_with(first, last, first2, last2, Equal(&copies)); assert(copies == 0);
218+
(void)std::ranges::starts_with(first, last, first2, last2, Equal(&copies)); assert(copies == 0);
219+
(void)std::ranges::starts_with(a, b, Equal(&copies)); assert(copies == 0);
219220
#endif
220221
(void)std::ranges::transform(first, last, first2, UnaryTransform(&copies)); assert(copies == 0);
221222
(void)std::ranges::transform(a, first2, UnaryTransform(&copies)); assert(copies == 0);

libcxx/test/libcxx/algorithms/ranges_robust_against_copying_projections.pass.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,8 @@ constexpr bool all_the_algorithms()
206206
if (!std::is_constant_evaluated()) { (void)std::ranges::stable_sort(first, last, Less(), Proj(&copies)); assert(copies == 0); }
207207
if (!std::is_constant_evaluated()) { (void)std::ranges::stable_sort(a, Less(), Proj(&copies)); assert(copies == 0); }
208208
#if TEST_STD_VER > 20
209-
//(void)std::ranges::starts_with(first, last, first2, last2, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0);
209+
(void)std::ranges::starts_with(first, last, first2, last2, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0);
210+
(void)std::ranges::starts_with(a, b, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0);
210211
#endif
211212
(void)std::ranges::transform(first, last, first2, UnaryTransform(), Proj(&copies)); assert(copies == 0);
212213
(void)std::ranges::transform(a, first2, UnaryTransform(), Proj(&copies)); assert(copies == 0);

libcxx/test/libcxx/private_headers.verify.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ END-SCRIPT
204204
#include <__algorithm/ranges_sort_heap.h> // expected-error@*:* {{use of private header from outside its module: '__algorithm/ranges_sort_heap.h'}}
205205
#include <__algorithm/ranges_stable_partition.h> // expected-error@*:* {{use of private header from outside its module: '__algorithm/ranges_stable_partition.h'}}
206206
#include <__algorithm/ranges_stable_sort.h> // expected-error@*:* {{use of private header from outside its module: '__algorithm/ranges_stable_sort.h'}}
207+
#include <__algorithm/ranges_starts_with.h> // expected-error@*:* {{use of private header from outside its module: '__algorithm/ranges_starts_with.h'}}
207208
#include <__algorithm/ranges_swap_ranges.h> // expected-error@*:* {{use of private header from outside its module: '__algorithm/ranges_swap_ranges.h'}}
208209
#include <__algorithm/ranges_transform.h> // expected-error@*:* {{use of private header from outside its module: '__algorithm/ranges_transform.h'}}
209210
#include <__algorithm/ranges_unique.h> // expected-error@*:* {{use of private header from outside its module: '__algorithm/ranges_unique.h'}}

0 commit comments

Comments
 (0)