VCCC  2024.05
VisualCamp Common C++ library
find_end.hpp
Go to the documentation of this file.
1 //
2 // Created by YongGyu Lee on 4/12/24.
3 //
4 
5 #ifndef VCCC_ALGORITHM_RANGES_FIND_END_HPP_
6 #define VCCC_ALGORITHM_RANGES_FIND_END_HPP_
7 
8 #include <iterator>
9 #include <type_traits>
10 #include <utility>
11 
18 #include "vccc/__iterator/next.hpp"
20 #include "vccc/__ranges/begin.hpp"
22 #include "vccc/__ranges/end.hpp"
26 
27 namespace vccc {
28 namespace ranges {
29 namespace detail {
30 
31 struct find_end_niebloid {
32  template<typename I1, typename S1,
33  typename I2, typename S2,
34  typename Pred = ranges::equal_to,
35  typename Proj1 = identity, typename Proj2 = identity,
36  std::enable_if_t<conjunction<
37  forward_iterator<I1>, sentinel_for<S1, I1>,
38  forward_iterator<I2>, sentinel_for<S2, I2>,
39  indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
40  >::value, int> = 0>
41  constexpr subrange<I1> operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const {
42  if (first2 == last2) {
43  auto last_it = ranges::next(first1, last1);
44  return {last_it, last_it};
45  }
46 
47  auto result = ranges::search(std::move(first1),last1, first2, last2, pred, proj1, proj2);
48  if (result.empty())
49  return result;
50 
51  for (;;) {
52  auto new_result = ranges::search(std::next(result.begin()), last1, first2, last2, pred, proj1, proj2);
53  if (new_result.empty())
54  return result;
55  result = std::move(new_result);
56  }
57  }
58 
59  template<typename R1, typename R2,
60  typename Pred = ranges::equal_to, typename Proj1 = identity, typename Proj2 = identity,
61  std::enable_if_t<conjunction<
62  forward_range<R1>, forward_range<R2>,
63  indirectly_comparable<iterator_t<R1>, iterator_t<R2>, Pred, Proj1, Proj2>
64  >::value, int> = 0>
65  constexpr borrowed_subrange_t<R1> operator()(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const {
66  return (*this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), std::move(pred), std::move(proj1), std::move(proj2));
67  }
68 };
69 
70 } // namespace detail
71 
74 
75 VCCC_INLINE_OR_STATIC constexpr detail::find_end_niebloid find_end{};
76 
78 
79 } // namespace ranges
80 } // namespace vccc
81 
82 #endif // VCCC_ALGORITHM_RANGES_FIND_END_HPP_
constexpr VCCC_INLINE_OR_STATIC detail::search_niebloid search
Definition: search.hpp:87
constexpr VCCC_INLINE_OR_STATIC detail::find_end_niebloid find_end
Definition: find_end.hpp:75
constexpr VCCC_INLINE_OR_STATIC detail::next_niebloid next
Definition: next.hpp:65
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