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_LEXICOGRAPHICAL_COMPARE_H
10 #define _LIBCPP___ALGORITHM_RANGES_LEXICOGRAPHICAL_COMPARE_H
11 
12 #include <__config>
13 #include <__functional/identity.h>
14 #include <__functional/invoke.h>
15 #include <__functional/ranges_operations.h>
16 #include <__iterator/concepts.h>
17 #include <__iterator/projected.h>
18 #include <__ranges/access.h>
19 #include <__ranges/concepts.h>
20 #include <__utility/move.h>
21 
22 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
23 #  pragma GCC system_header
24 #endif
25 
26 #if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
27 
28 _LIBCPP_BEGIN_NAMESPACE_STD
29 
30 namespace ranges {
31 namespace __lexicographical_compare {
32 struct __fn {
33 
34   template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Proj1, class _Proj2, class _Comp>
35   _LIBCPP_HIDE_FROM_ABI constexpr static
36   bool __lexicographical_compare_impl(_Iter1 __first1, _Sent1 __last1,
37                                       _Iter2 __first2, _Sent2 __last2,
38                                       _Comp& __comp,
39                                       _Proj1& __proj1,
40                                       _Proj2& __proj2) {
41     while (__first2 != __last2) {
42       if (__first1 == __last1
43        || std::invoke(__comp, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__first2)))
44         return true;
45       if (std::invoke(__comp, std::invoke(__proj2, *__first2), std::invoke(__proj1, *__first1)))
46         return false;
47       ++__first1;
48       ++__first2;
49     }
50     return false;
51   }
52 
53   template <input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
54             input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
55             class _Proj1 = identity,
56             class _Proj2 = identity,
57             indirect_strict_weak_order<projected<_Iter1, _Proj1>, projected<_Iter2, _Proj2>> _Comp = ranges::less>
58   _LIBCPP_HIDE_FROM_ABI constexpr
59   bool operator()(_Iter1 __first1, _Sent1 __last1,
60                   _Iter2 __first2, _Sent2 __last2,
61                   _Comp __comp = {},
62                   _Proj1 __proj1 = {},
63                   _Proj2 __proj2 = {}) const {
64     return __lexicographical_compare_impl(std::move(__first1), std::move(__last1),
65                                           std::move(__first2), std::move(__last2),
66                                           __comp,
67                                           __proj1,
68                                           __proj2);
69   }
70 
71   template <input_range _Range1,
72             input_range _Range2,
73             class _Proj1 = identity,
74             class _Proj2 = identity,
75             indirect_strict_weak_order<projected<iterator_t<_Range1>, _Proj1>,
76                                        projected<iterator_t<_Range2>, _Proj2>> _Comp = ranges::less>
77   _LIBCPP_HIDE_FROM_ABI constexpr
78   bool operator()(_Range1&& __range1, _Range2&& __range2, _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
79     return __lexicographical_compare_impl(ranges::begin(__range1), ranges::end(__range1),
80                                           ranges::begin(__range2), ranges::end(__range2),
81                                           __comp,
82                                           __proj1,
83                                           __proj2);
84   }
85 
86 };
87 } // namespace __lexicographical_compare
88 
89 inline namespace __cpo {
90   inline constexpr auto lexicographical_compare = __lexicographical_compare::__fn{};
91 } // namespace __cpo
92 } // namespace ranges
93 
94 _LIBCPP_END_NAMESPACE_STD
95 
96 #endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
97 
98 #endif // _LIBCPP___ALGORITHM_RANGES_LEXICOGRAPHICAL_COMPARE_H
99