xref: /llvm-project/libcxx/include/__cxx03/__algorithm/ranges_search.h (revision ce7771902dc50d900de639d499a60486b83f70e0)
1e78f53d1SNikolas Klauser //===----------------------------------------------------------------------===//
2e78f53d1SNikolas Klauser //
3e78f53d1SNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e78f53d1SNikolas Klauser // See https://llvm.org/LICENSE.txt for license information.
5e78f53d1SNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e78f53d1SNikolas Klauser //
7e78f53d1SNikolas Klauser //===----------------------------------------------------------------------===//
8e78f53d1SNikolas Klauser 
9*ce777190SNikolas Klauser #ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_SEARCH_H
10*ce777190SNikolas Klauser #define _LIBCPP___CXX03___ALGORITHM_RANGES_SEARCH_H
11e78f53d1SNikolas Klauser 
1273fbae83SNikolas Klauser #include <__cxx03/__algorithm/iterator_operations.h>
1373fbae83SNikolas Klauser #include <__cxx03/__algorithm/search.h>
1473fbae83SNikolas Klauser #include <__cxx03/__config>
1573fbae83SNikolas Klauser #include <__cxx03/__functional/identity.h>
1673fbae83SNikolas Klauser #include <__cxx03/__functional/ranges_operations.h>
1773fbae83SNikolas Klauser #include <__cxx03/__iterator/advance.h>
1873fbae83SNikolas Klauser #include <__cxx03/__iterator/concepts.h>
1973fbae83SNikolas Klauser #include <__cxx03/__iterator/distance.h>
2073fbae83SNikolas Klauser #include <__cxx03/__iterator/indirectly_comparable.h>
2173fbae83SNikolas Klauser #include <__cxx03/__ranges/access.h>
2273fbae83SNikolas Klauser #include <__cxx03/__ranges/concepts.h>
2373fbae83SNikolas Klauser #include <__cxx03/__ranges/size.h>
2473fbae83SNikolas Klauser #include <__cxx03/__ranges/subrange.h>
2573fbae83SNikolas Klauser #include <__cxx03/__utility/pair.h>
26e78f53d1SNikolas Klauser 
27e78f53d1SNikolas Klauser #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
28e78f53d1SNikolas Klauser #  pragma GCC system_header
29e78f53d1SNikolas Klauser #endif
30e78f53d1SNikolas Klauser 
31e78f53d1SNikolas Klauser #if _LIBCPP_STD_VER >= 20
32e78f53d1SNikolas Klauser 
33e78f53d1SNikolas Klauser _LIBCPP_BEGIN_NAMESPACE_STD
34e78f53d1SNikolas Klauser 
35e78f53d1SNikolas Klauser namespace ranges {
36e78f53d1SNikolas Klauser namespace __search {
37e78f53d1SNikolas Klauser struct __fn {
38e78f53d1SNikolas Klauser   template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Pred, class _Proj1, class _Proj2>
39e78f53d1SNikolas Klauser   _LIBCPP_HIDE_FROM_ABI static constexpr subrange<_Iter1> __ranges_search_impl(
40e78f53d1SNikolas Klauser       _Iter1 __first1,
41e78f53d1SNikolas Klauser       _Sent1 __last1,
42e78f53d1SNikolas Klauser       _Iter2 __first2,
43e78f53d1SNikolas Klauser       _Sent2 __last2,
44e78f53d1SNikolas Klauser       _Pred& __pred,
45e78f53d1SNikolas Klauser       _Proj1& __proj1,
46e78f53d1SNikolas Klauser       _Proj2& __proj2) {
47e78f53d1SNikolas Klauser     if constexpr (sized_sentinel_for<_Sent2, _Iter2>) {
48e78f53d1SNikolas Klauser       auto __size2 = ranges::distance(__first2, __last2);
49e78f53d1SNikolas Klauser       if (__size2 == 0)
50e78f53d1SNikolas Klauser         return {__first1, __first1};
51e78f53d1SNikolas Klauser 
52e78f53d1SNikolas Klauser       if constexpr (sized_sentinel_for<_Sent1, _Iter1>) {
53e78f53d1SNikolas Klauser         auto __size1 = ranges::distance(__first1, __last1);
54e78f53d1SNikolas Klauser         if (__size1 < __size2) {
55e78f53d1SNikolas Klauser           ranges::advance(__first1, __last1);
56e78f53d1SNikolas Klauser           return {__first1, __first1};
57e78f53d1SNikolas Klauser         }
58e78f53d1SNikolas Klauser 
59e78f53d1SNikolas Klauser         if constexpr (random_access_iterator<_Iter1> && random_access_iterator<_Iter2>) {
60e78f53d1SNikolas Klauser           auto __ret = std::__search_random_access_impl<_RangeAlgPolicy>(
61e78f53d1SNikolas Klauser               __first1, __last1, __first2, __last2, __pred, __proj1, __proj2, __size1, __size2);
62e78f53d1SNikolas Klauser           return {__ret.first, __ret.second};
63e78f53d1SNikolas Klauser         }
64e78f53d1SNikolas Klauser       }
65e78f53d1SNikolas Klauser     }
66e78f53d1SNikolas Klauser 
67e78f53d1SNikolas Klauser     auto __ret =
68e78f53d1SNikolas Klauser         std::__search_forward_impl<_RangeAlgPolicy>(__first1, __last1, __first2, __last2, __pred, __proj1, __proj2);
69e78f53d1SNikolas Klauser     return {__ret.first, __ret.second};
70e78f53d1SNikolas Klauser   }
71e78f53d1SNikolas Klauser 
72e78f53d1SNikolas Klauser   template <forward_iterator _Iter1,
73e78f53d1SNikolas Klauser             sentinel_for<_Iter1> _Sent1,
74e78f53d1SNikolas Klauser             forward_iterator _Iter2,
75e78f53d1SNikolas Klauser             sentinel_for<_Iter2> _Sent2,
76e78f53d1SNikolas Klauser             class _Pred  = ranges::equal_to,
77e78f53d1SNikolas Klauser             class _Proj1 = identity,
78e78f53d1SNikolas Klauser             class _Proj2 = identity>
79e78f53d1SNikolas Klauser     requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
80e78f53d1SNikolas Klauser   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter1> operator()(
81e78f53d1SNikolas Klauser       _Iter1 __first1,
82e78f53d1SNikolas Klauser       _Sent1 __last1,
83e78f53d1SNikolas Klauser       _Iter2 __first2,
84e78f53d1SNikolas Klauser       _Sent2 __last2,
85e78f53d1SNikolas Klauser       _Pred __pred   = {},
86e78f53d1SNikolas Klauser       _Proj1 __proj1 = {},
87e78f53d1SNikolas Klauser       _Proj2 __proj2 = {}) const {
88e78f53d1SNikolas Klauser     return __ranges_search_impl(__first1, __last1, __first2, __last2, __pred, __proj1, __proj2);
89e78f53d1SNikolas Klauser   }
90e78f53d1SNikolas Klauser 
91e78f53d1SNikolas Klauser   template <forward_range _Range1,
92e78f53d1SNikolas Klauser             forward_range _Range2,
93e78f53d1SNikolas Klauser             class _Pred  = ranges::equal_to,
94e78f53d1SNikolas Klauser             class _Proj1 = identity,
95e78f53d1SNikolas Klauser             class _Proj2 = identity>
96e78f53d1SNikolas Klauser     requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2>
97e78f53d1SNikolas Klauser   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range1> operator()(
98e78f53d1SNikolas Klauser       _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
99e78f53d1SNikolas Klauser     auto __first1 = ranges::begin(__range1);
100e78f53d1SNikolas Klauser     if constexpr (sized_range<_Range2>) {
101e78f53d1SNikolas Klauser       auto __size2 = ranges::size(__range2);
102e78f53d1SNikolas Klauser       if (__size2 == 0)
103e78f53d1SNikolas Klauser         return {__first1, __first1};
104e78f53d1SNikolas Klauser       if constexpr (sized_range<_Range1>) {
105e78f53d1SNikolas Klauser         auto __size1 = ranges::size(__range1);
106e78f53d1SNikolas Klauser         if (__size1 < __size2) {
107e78f53d1SNikolas Klauser           ranges::advance(__first1, ranges::end(__range1));
108e78f53d1SNikolas Klauser           return {__first1, __first1};
109e78f53d1SNikolas Klauser         }
110e78f53d1SNikolas Klauser       }
111e78f53d1SNikolas Klauser     }
112e78f53d1SNikolas Klauser 
113e78f53d1SNikolas Klauser     return __ranges_search_impl(
114e78f53d1SNikolas Klauser         ranges::begin(__range1),
115e78f53d1SNikolas Klauser         ranges::end(__range1),
116e78f53d1SNikolas Klauser         ranges::begin(__range2),
117e78f53d1SNikolas Klauser         ranges::end(__range2),
118e78f53d1SNikolas Klauser         __pred,
119e78f53d1SNikolas Klauser         __proj1,
120e78f53d1SNikolas Klauser         __proj2);
121e78f53d1SNikolas Klauser   }
122e78f53d1SNikolas Klauser };
123e78f53d1SNikolas Klauser } // namespace __search
124e78f53d1SNikolas Klauser 
125e78f53d1SNikolas Klauser inline namespace __cpo {
126e78f53d1SNikolas Klauser inline constexpr auto search = __search::__fn{};
127e78f53d1SNikolas Klauser } // namespace __cpo
128e78f53d1SNikolas Klauser } // namespace ranges
129e78f53d1SNikolas Klauser 
130e78f53d1SNikolas Klauser _LIBCPP_END_NAMESPACE_STD
131e78f53d1SNikolas Klauser 
132e78f53d1SNikolas Klauser #endif // _LIBCPP_STD_VER >= 20
133e78f53d1SNikolas Klauser 
134*ce777190SNikolas Klauser #endif // _LIBCPP___CXX03___ALGORITHM_RANGES_SEARCH_H
135