1134723edSLouis Dionne //===----------------------------------------------------------------------===//
2134723edSLouis Dionne //
3134723edSLouis Dionne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4134723edSLouis Dionne // See https://llvm.org/LICENSE.txt for license information.
5134723edSLouis Dionne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6134723edSLouis Dionne //
7134723edSLouis Dionne //===----------------------------------------------------------------------===//
8134723edSLouis Dionne
9134723edSLouis Dionne #ifndef _LIBCPP___ALGORITHM_SET_INTERSECTION_H
10134723edSLouis Dionne #define _LIBCPP___ALGORITHM_SET_INTERSECTION_H
11134723edSLouis Dionne
12134723edSLouis Dionne #include <__algorithm/comp.h>
13134723edSLouis Dionne #include <__algorithm/comp_ref_type.h>
1496b674f2SHui Xie #include <__algorithm/iterator_operations.h>
154d81a46fSArthur O'Dwyer #include <__config>
16134723edSLouis Dionne #include <__iterator/iterator_traits.h>
17101d1e9bSNikolas Klauser #include <__iterator/next.h>
1896b674f2SHui Xie #include <__utility/move.h>
19134723edSLouis Dionne
20134723edSLouis Dionne #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21134723edSLouis Dionne # pragma GCC system_header
22134723edSLouis Dionne #endif
23134723edSLouis Dionne
24134723edSLouis Dionne _LIBCPP_BEGIN_NAMESPACE_STD
25134723edSLouis Dionne
2696b674f2SHui Xie template <class _InIter1, class _InIter2, class _OutIter>
2796b674f2SHui Xie struct __set_intersection_result {
28*a5c0638dSHui Xie _InIter1 __in1_;
29*a5c0638dSHui Xie _InIter2 __in2_;
30*a5c0638dSHui Xie _OutIter __out_;
3196b674f2SHui Xie
3296b674f2SHui Xie // need a constructor as C++03 aggregate init is hard
3396b674f2SHui Xie _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
__set_intersection_result__set_intersection_result34e90e7e70SHui Xie __set_intersection_result(_InIter1&& __in_iter1, _InIter2&& __in_iter2, _OutIter&& __out_iter)
35*a5c0638dSHui Xie : __in1_(std::move(__in_iter1)), __in2_(std::move(__in_iter2)), __out_(std::move(__out_iter)) {}
3696b674f2SHui Xie };
3796b674f2SHui Xie
38295b951eSKonstantin Varlamov template <class _AlgPolicy, class _Compare, class _InIter1, class _Sent1, class _InIter2, class _Sent2, class _OutIter>
3996b674f2SHui Xie _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 __set_intersection_result<_InIter1, _InIter2, _OutIter>
__set_intersection(_InIter1 __first1,_Sent1 __last1,_InIter2 __first2,_Sent2 __last2,_OutIter __result,_Compare && __comp)4096b674f2SHui Xie __set_intersection(
4196b674f2SHui Xie _InIter1 __first1, _Sent1 __last1, _InIter2 __first2, _Sent2 __last2, _OutIter __result, _Compare&& __comp) {
4296b674f2SHui Xie while (__first1 != __last1 && __first2 != __last2) {
43134723edSLouis Dionne if (__comp(*__first1, *__first2))
44134723edSLouis Dionne ++__first1;
4596b674f2SHui Xie else {
4696b674f2SHui Xie if (!__comp(*__first2, *__first1)) {
47134723edSLouis Dionne *__result = *__first1;
48134723edSLouis Dionne ++__result;
49134723edSLouis Dionne ++__first1;
50134723edSLouis Dionne }
51134723edSLouis Dionne ++__first2;
52134723edSLouis Dionne }
53134723edSLouis Dionne }
5496b674f2SHui Xie
5596b674f2SHui Xie return __set_intersection_result<_InIter1, _InIter2, _OutIter>(
56295b951eSKonstantin Varlamov _IterOps<_AlgPolicy>::next(std::move(__first1), std::move(__last1)),
57295b951eSKonstantin Varlamov _IterOps<_AlgPolicy>::next(std::move(__first2), std::move(__last2)),
5896b674f2SHui Xie std::move(__result));
59134723edSLouis Dionne }
60134723edSLouis Dionne
61134723edSLouis Dionne template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
set_intersection(_InputIterator1 __first1,_InputIterator1 __last1,_InputIterator2 __first2,_InputIterator2 __last2,_OutputIterator __result,_Compare __comp)6296b674f2SHui Xie inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator set_intersection(
6396b674f2SHui Xie _InputIterator1 __first1,
6496b674f2SHui Xie _InputIterator1 __last1,
6596b674f2SHui Xie _InputIterator2 __first2,
6696b674f2SHui Xie _InputIterator2 __last2,
6796b674f2SHui Xie _OutputIterator __result,
6896b674f2SHui Xie _Compare __comp) {
69134723edSLouis Dionne typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
70295b951eSKonstantin Varlamov return std::__set_intersection<_ClassicAlgPolicy, _Comp_ref>(
7196b674f2SHui Xie std::move(__first1),
7296b674f2SHui Xie std::move(__last1),
7396b674f2SHui Xie std::move(__first2),
7496b674f2SHui Xie std::move(__last2),
7596b674f2SHui Xie std::move(__result),
7696b674f2SHui Xie __comp)
77*a5c0638dSHui Xie .__out_;
78134723edSLouis Dionne }
79134723edSLouis Dionne
80134723edSLouis Dionne template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
set_intersection(_InputIterator1 __first1,_InputIterator1 __last1,_InputIterator2 __first2,_InputIterator2 __last2,_OutputIterator __result)8196b674f2SHui Xie inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator set_intersection(
8296b674f2SHui Xie _InputIterator1 __first1,
8396b674f2SHui Xie _InputIterator1 __last1,
8496b674f2SHui Xie _InputIterator2 __first2,
8596b674f2SHui Xie _InputIterator2 __last2,
8696b674f2SHui Xie _OutputIterator __result) {
87295b951eSKonstantin Varlamov return std::__set_intersection<_ClassicAlgPolicy>(
8896b674f2SHui Xie std::move(__first1),
8996b674f2SHui Xie std::move(__last1),
9096b674f2SHui Xie std::move(__first2),
9196b674f2SHui Xie std::move(__last2),
9296b674f2SHui Xie std::move(__result),
93134723edSLouis Dionne __less<typename iterator_traits<_InputIterator1>::value_type,
9496b674f2SHui Xie typename iterator_traits<_InputIterator2>::value_type>())
95*a5c0638dSHui Xie .__out_;
96134723edSLouis Dionne }
97134723edSLouis Dionne
98134723edSLouis Dionne _LIBCPP_END_NAMESPACE_STD
99134723edSLouis Dionne
100134723edSLouis Dionne #endif // _LIBCPP___ALGORITHM_SET_INTERSECTION_H
101