VCCC  2024.05
VisualCamp Common C++ library
search.hpp
Go to the documentation of this file.
1 //
2 // Created by yonggyulee on 2/3/24.
3 //
4 
5 #ifndef VCCC_ALGORITHM_SEARCH_HPP
6 #define VCCC_ALGORITHM_SEARCH_HPP
7 
8 #include <type_traits>
9 #include <utility>
10 
18 #include "vccc/__ranges/begin.hpp"
20 #include "vccc/__ranges/end.hpp"
25 
26 namespace vccc {
27 namespace ranges {
28 namespace detail {
29 
30 struct search_niebloid {
31  private:
32  template<typename R1, typename R2, typename Pred, typename Proj1, typename Proj2,
33  bool = conjunction<forward_range<R1>, forward_range<R2>>::value /* false */>
34  struct check_range : std::false_type {};
35  template<typename R1, typename R2, typename Pred, typename Proj1, typename Proj2>
36  struct check_range<R1, R2, Pred, Proj1, Proj2, true>
37  : indirectly_comparable<iterator_t<R1>, iterator_t<R2>, Pred, Proj1, Proj2> {};
38 
39  public:
40  template<
41  typename I1, typename S1,
42  typename I2, typename S2,
43  typename Pred = equal_to, typename Proj1 = identity, typename Proj2 = identity,
44  std::enable_if_t<conjunction<
45  forward_iterator<I1>, sentinel_for<S1, I1>,
46  forward_iterator<I2>, sentinel_for<S2, I2>,
47  indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
48  >::value, int> = 0
49  >
50  constexpr subrange<I1>
51  operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const {
52  for (;; ++first1) {
53  I1 it1 = first1;
54  I2 it2 = first2;
55  for (;; ++it1, (void)++it2) {
56  if (it2 == last2)
57  return {first1, it1};
58  if (it1 == last1)
59  return {it1, it1};
60  if (!vccc::invoke(pred, vccc::invoke(proj1, *it1), vccc::invoke(proj2, *it2)))
61  break;
62  }
63  }
64 
65  // unreachable
66  return {last1, last1};
67  }
68 
69  template<
70  typename R1, typename R2,
71  typename Pred = equal_to, typename Proj1 = identity, typename Proj2 = identity,
73  >
74  constexpr borrowed_subrange_t<R1>
75  operator()(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const {
76  return (*this)(ranges::begin(r1), ranges::end(r1),
77  ranges::begin(r2), ranges::end(r2),
78  std::move(pred), std::move(proj1), std::move(proj2));
79  }
80 };
81 
82 } // namespace detail
83 
86 
87 VCCC_INLINE_OR_STATIC constexpr detail::search_niebloid search{};
88 
90 
91 } // namespace ranges
92 } // namespace vccc
93 
94 #endif // VCCC_ALGORITHM_SEARCH_HPP
constexpr VCCC_INLINE_OR_STATIC detail::search_niebloid search
Definition: search.hpp:87
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