VCCC  2024.05
VisualCamp Common C++ library
set_intersection.hpp
Go to the documentation of this file.
1 //
2 // Created by YongGyu Lee on 3/19/24.
3 //
4 
5 #ifndef VCCC_ALGORITHM_RANGES_SET_INTERSECTION_HPP_
6 #define VCCC_ALGORITHM_RANGES_SET_INTERSECTION_HPP_
7 
8 #include <utility>
9 
17 #include "vccc/__iterator/next.hpp"
23 
24 namespace vccc {
25 namespace ranges {
26 
29 
30 template< class I1, class I2, class O >
32 
33 namespace detail {
34 
35 struct set_intersection_niebloid {
36  private:
37  template<typename R1, typename R2, typename O, typename Comp, typename Proj1, typename Proj2,
39  struct check_range : std::false_type {};
40  template<typename R1, typename R2, typename O, typename Comp, typename Proj1, typename Proj2>
41  struct check_range<R1, R2, O, Comp, Proj1, Proj2, true>
42  : conjunction<
43  weakly_incrementable<O>,
44  mergeable<iterator_t<R1>, iterator_t<R2>, O, Comp, Proj1, Proj2>
45  > {};
46 
47  public:
48  template<
49  typename I1, typename S1,
50  typename I2, typename S2,
51  typename O,
52  typename Comp = ranges::less,
53  typename Proj1 = identity,
54  typename Proj2 = identity,
55  std::enable_if_t<conjunction<
60  >::value, int> = 0>
62  operator()(I1 first1, S1 last1, I2 first2, S2 last2, O result, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const {
63  while (first1 != last1 && first2 != last2) {
64  if (vccc::invoke(comp, vccc::invoke(proj1, *first1), vccc::invoke(proj2, *first2))) {
65  ++first1;
66  } else if (vccc::invoke(comp, vccc::invoke(proj2, *first2), vccc::invoke(proj1, *first1))) {
67  ++first2;
68  } else {
69  *result = *first1;
70  ++first1;
71  ++first2;
72  ++result;
73  }
74  }
75  return {
76  ranges::next(std::move(first1), std::move(last1)),
77  ranges::next(std::move(first2), std::move(last2)),
78  std::move(result)
79  };
80  }
81 
82  template<
83  typename R1, typename R2,
84  typename O,
85  typename Comp = ranges::less,
86  typename Proj1 = identity,
87  typename Proj2 = identity,
88  std::enable_if_t<
89  check_range<R1, R2, O, Comp, Proj1, Proj2>
90  ::value, int> = 0>
92  operator()(R1&& r1, R2&& r2, O result, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const {
93  return (*this)(ranges::begin(r1), ranges::end(r1),
94  ranges::begin(r2), ranges::end(r2),
95  std::move(result), std::move(comp),
96  std::move(proj1), std::move(proj2));
97  }
98 };
99 
100 } // namespace detail
101 
102 VCCC_INLINE_OR_STATIC constexpr detail::set_intersection_niebloid set_intersection{};
103 
105 
106 } // namespace ranges
107 } // namespace vccc
108 
109 #endif // VCCC_ALGORITHM_RANGES_SET_INTERSECTION_HPP_
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::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::set_intersection_niebloid set_intersection
Definition: set_intersection.hpp:102
constexpr VCCC_INLINE_OR_STATIC detail::end_niebloid end
returns a sentinel indicating the end of a range
Definition: end.hpp:120
typename borrowed_iterator< R >::type borrowed_iterator_t
Definition: borrowed_iterator_t.hpp:36
#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
Definition: conjunction.hpp:22
function object that returns its argument unchanged
Definition: identity.hpp:25
specifies that a type is an input iterator, that is, its referenced values can be read and it can be ...
Definition: input_iterator.hpp:55
Definition: mergeable.hpp:48
Definition: in_in_out_result.hpp:22
specifies a range whose iterator type satisfies input_iterator
Definition: input_range.hpp:46
Definition: less.hpp:20
Definition: sentinel_for.hpp:24
Definition: weakly_incrementable.hpp:52