VCCC  2024.05
VisualCamp Common C++ library
lexicographical_compare.hpp
Go to the documentation of this file.
1 //
2 // Created by YongGyu Lee on 2/24/24.
3 //
4 
5 #ifndef VCCC_ALGORITHM_RANGES_LEXICOGRAPHICAL_COMPARE_HPP
6 #define VCCC_ALGORITHM_RANGES_LEXICOGRAPHICAL_COMPARE_HPP
7 
8 #include <functional>
9 #include <type_traits>
10 
19 #include "vccc/__ranges/begin.hpp"
20 #include "vccc/__ranges/end.hpp"
22 
23 namespace vccc {
24 namespace ranges {
25 namespace detail {
26 
27 struct lexicographical_compare_niebloid {
28  private:
29  template<typename I1, typename Proj1, typename I2, typename Proj2, typename Comp,
30  bool = conjunction<projectable<I1, Proj1>, projectable<I2, Proj2>>::value /* false_type */>
31  struct test_projectable_iterator : std::false_type {};
32  template<typename I1, typename Proj1, typename I2, typename Proj2, typename Comp>
33  struct test_projectable_iterator<I1, Proj1, I2, Proj2, Comp, true>
34  : indirect_strict_weak_order<Comp, projected<I1, Proj1>, projected<I2, Proj2>> {};
35 
36  template<typename R1, typename Proj1, typename R2, typename Proj2, typename Comp,
37  bool = conjunction<input_range<R1>, input_range<R2>>::value /* false_type */>
38  struct test_projectable_range : std::false_type {};
39  template<typename R1, typename Proj1, typename R2, typename Proj2, typename Comp>
40  struct test_projectable_range<R1, Proj1, R2, Proj2, Comp, true>
41  : test_projectable_iterator<iterator_t<R1>, Proj1, iterator_t<R2>, Proj2, Comp> {};
42 
43  public:
44  template<
45  typename I1, typename S1,
46  typename I2, typename S2,
47  typename Proj1 = identity, typename Proj2 = identity, typename Comp = ranges::less,
48  std::enable_if_t<conjunction<
49  input_iterator<I1>, sentinel_for<S1, I1>,
50  input_iterator<I2>, sentinel_for<S2, I2>,
51  test_projectable_iterator<I1, Proj1, I2, Proj2, Comp>
52  >::value, int> = 0
53  >
54  constexpr bool operator()(I1 first1, S1 last1, I2 first2, S2 last2, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const {
55  using namespace rel_ops;
56  for (; (first1 != last1) && (first2 != last2); ++first1, (void) ++first2) {
57  if (vccc::invoke(comp, vccc::invoke(proj1, *first1), vccc::invoke(proj2, *first2)))
58  return true;
59  if (vccc::invoke(comp, vccc::invoke(proj2, *first2), vccc::invoke(proj1, *first1)))
60  return false;
61  }
62  return (first1 == last1) && (first2 != last2);
63  }
64 
65  template<typename R1, typename R2, typename Proj1 = identity, typename Proj2 = identity, typename Comp = less, std::enable_if_t<
66  test_projectable_range<R1, Proj1, R2, Proj2, Comp>
67  ::value, int> = 0>
68  constexpr bool operator()(R1&& r1, R2&& r2, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const {
69  return (*this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), std::ref(comp), std::ref(proj1), std::ref(proj2));
70  }
71 
72 };
73 
74 } // namespace detail
75 
78 
80 VCCC_INLINE_OR_STATIC constexpr detail::lexicographical_compare_niebloid lexicographical_compare{};
81 
83 
84 } // namespace ranges
85 } // namespace vccc
86 
87 #endif // VCCC_ALGORITHM_RANGES_LEXICOGRAPHICAL_COMPARE_HPP
constexpr VCCC_INLINE_OR_STATIC detail::lexicographical_compare_niebloid lexicographical_compare
returns true if one range is lexicographically less than another
Definition: lexicographical_compare.hpp:80
constexpr invoke_result_t< F, Args... > invoke(F &&f, Args &&... args) noexcept(is_nothrow_invocable< F, Args... >::value)
Definition: invoke.hpp:38
constexpr VCCC_INLINE_OR_STATIC detail::begin_niebloid begin
returns an iterator to the beginning of a range
Definition: begin.hpp:116
constexpr VCCC_INLINE_OR_STATIC detail::end_niebloid end
returns a sentinel indicating the end of a range
Definition: end.hpp:120
#define VCCC_INLINE_OR_STATIC
Definition: inline_or_static.hpp:9
Definition: directory.h:12
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35