xref: /freebsd/contrib/llvm-project/libcxx/include/__algorithm/set_intersection.h (revision d54a7d337331d991e039e4f42f6b4dc64aedce08)
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_SET_INTERSECTION_H
10  #define _LIBCPP___ALGORITHM_SET_INTERSECTION_H
11  
12  #include <__algorithm/comp.h>
13  #include <__algorithm/comp_ref_type.h>
14  #include <__algorithm/iterator_operations.h>
15  #include <__config>
16  #include <__iterator/iterator_traits.h>
17  #include <__iterator/next.h>
18  #include <__utility/move.h>
19  
20  #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21  #  pragma GCC system_header
22  #endif
23  
24  _LIBCPP_BEGIN_NAMESPACE_STD
25  
26  template <class _InIter1, class _InIter2, class _OutIter>
27  struct __set_intersection_result {
28    _InIter1 __in1_;
29    _InIter2 __in2_;
30    _OutIter __out_;
31  
32    // need a constructor as C++03 aggregate init is hard
33    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
34    __set_intersection_result(_InIter1&& __in_iter1, _InIter2&& __in_iter2, _OutIter&& __out_iter)
35        : __in1_(std::move(__in_iter1)), __in2_(std::move(__in_iter2)), __out_(std::move(__out_iter)) {}
36  };
37  
38  template <class _AlgPolicy, class _Compare, class _InIter1, class _Sent1, class _InIter2, class _Sent2, class _OutIter>
39  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __set_intersection_result<_InIter1, _InIter2, _OutIter>
40  __set_intersection(
41      _InIter1 __first1, _Sent1 __last1, _InIter2 __first2, _Sent2 __last2, _OutIter __result, _Compare&& __comp) {
42    while (__first1 != __last1 && __first2 != __last2) {
43      if (__comp(*__first1, *__first2))
44        ++__first1;
45      else {
46        if (!__comp(*__first2, *__first1)) {
47          *__result = *__first1;
48          ++__result;
49          ++__first1;
50        }
51        ++__first2;
52      }
53    }
54  
55    return __set_intersection_result<_InIter1, _InIter2, _OutIter>(
56        _IterOps<_AlgPolicy>::next(std::move(__first1), std::move(__last1)),
57        _IterOps<_AlgPolicy>::next(std::move(__first2), std::move(__last2)),
58        std::move(__result));
59  }
60  
61  template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
62  inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_intersection(
63      _InputIterator1 __first1,
64      _InputIterator1 __last1,
65      _InputIterator2 __first2,
66      _InputIterator2 __last2,
67      _OutputIterator __result,
68      _Compare __comp) {
69    return std::__set_intersection<_ClassicAlgPolicy, __comp_ref_type<_Compare> >(
70               std::move(__first1),
71               std::move(__last1),
72               std::move(__first2),
73               std::move(__last2),
74               std::move(__result),
75               __comp)
76        .__out_;
77  }
78  
79  template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
80  inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_intersection(
81      _InputIterator1 __first1,
82      _InputIterator1 __last1,
83      _InputIterator2 __first2,
84      _InputIterator2 __last2,
85      _OutputIterator __result) {
86    return std::__set_intersection<_ClassicAlgPolicy>(
87               std::move(__first1),
88               std::move(__last1),
89               std::move(__first2),
90               std::move(__last2),
91               std::move(__result),
92               __less<typename iterator_traits<_InputIterator1>::value_type,
93                      typename iterator_traits<_InputIterator2>::value_type>())
94        .__out_;
95  }
96  
97  _LIBCPP_END_NAMESPACE_STD
98  
99  #endif // _LIBCPP___ALGORITHM_SET_INTERSECTION_H
100