xref: /llvm-project/libcxx/include/__algorithm/ranges_set_difference.h (revision a2042521a0387d7d7b80b2987f4b21f5a50bc7bb)
11cdec6c9SHui Xie //===----------------------------------------------------------------------===//
21cdec6c9SHui Xie //
31cdec6c9SHui Xie // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
41cdec6c9SHui Xie // See https://llvm.org/LICENSE.txt for license information.
51cdec6c9SHui Xie // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61cdec6c9SHui Xie //
71cdec6c9SHui Xie //===----------------------------------------------------------------------===//
81cdec6c9SHui Xie 
91cdec6c9SHui Xie #ifndef _LIBCPP___ALGORITHM_RANGES_SET_DIFFERENCE_H
101cdec6c9SHui Xie #define _LIBCPP___ALGORITHM_RANGES_SET_DIFFERENCE_H
111cdec6c9SHui Xie 
121cdec6c9SHui Xie #include <__algorithm/in_out_result.h>
131cdec6c9SHui Xie #include <__algorithm/make_projected.h>
141cdec6c9SHui Xie #include <__algorithm/set_difference.h>
151cdec6c9SHui Xie #include <__config>
161cdec6c9SHui Xie #include <__functional/identity.h>
171cdec6c9SHui Xie #include <__functional/invoke.h>
181cdec6c9SHui Xie #include <__functional/ranges_operations.h>
191cdec6c9SHui Xie #include <__iterator/concepts.h>
201cdec6c9SHui Xie #include <__iterator/mergeable.h>
211cdec6c9SHui Xie #include <__ranges/access.h>
221cdec6c9SHui Xie #include <__ranges/concepts.h>
231cdec6c9SHui Xie #include <__ranges/dangling.h>
241cdec6c9SHui Xie #include <__type_traits/decay.h>
251cdec6c9SHui Xie #include <__utility/move.h>
26d5e26775SNikolas Klauser #include <__utility/pair.h>
271cdec6c9SHui Xie 
281cdec6c9SHui Xie #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
291cdec6c9SHui Xie #  pragma GCC system_header
301cdec6c9SHui Xie #endif
311cdec6c9SHui Xie 
327b462251SLouis Dionne _LIBCPP_PUSH_MACROS
337b462251SLouis Dionne #include <__undef_macros>
347b462251SLouis Dionne 
354f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 20
361cdec6c9SHui Xie 
371cdec6c9SHui Xie _LIBCPP_BEGIN_NAMESPACE_STD
381cdec6c9SHui Xie 
391cdec6c9SHui Xie namespace ranges {
401cdec6c9SHui Xie 
411cdec6c9SHui Xie template <class _InIter, class _OutIter>
421cdec6c9SHui Xie using set_difference_result = in_out_result<_InIter, _OutIter>;
431cdec6c9SHui Xie 
44d10dc5a0SChristopher Di Bella struct __set_difference {
455aa03b64SLouis Dionne   template <input_iterator _InIter1,
461cdec6c9SHui Xie             sentinel_for<_InIter1> _Sent1,
471cdec6c9SHui Xie             input_iterator _InIter2,
481cdec6c9SHui Xie             sentinel_for<_InIter2> _Sent2,
491cdec6c9SHui Xie             weakly_incrementable _OutIter,
501cdec6c9SHui Xie             class _Comp  = less,
511cdec6c9SHui Xie             class _Proj1 = identity,
521cdec6c9SHui Xie             class _Proj2 = identity>
531cdec6c9SHui Xie     requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2>
541cdec6c9SHui Xie   _LIBCPP_HIDE_FROM_ABI constexpr set_difference_result<_InIter1, _OutIter> operator()(
551cdec6c9SHui Xie       _InIter1 __first1,
561cdec6c9SHui Xie       _Sent1 __last1,
571cdec6c9SHui Xie       _InIter2 __first2,
581cdec6c9SHui Xie       _Sent2 __last2,
591cdec6c9SHui Xie       _OutIter __result,
601cdec6c9SHui Xie       _Comp __comp   = {},
611cdec6c9SHui Xie       _Proj1 __proj1 = {},
621cdec6c9SHui Xie       _Proj2 __proj2 = {}) const {
63*a2042521SNikolas Klauser     auto __ret = std::__set_difference(
641cdec6c9SHui Xie         __first1, __last1, __first2, __last2, __result, ranges::__make_projected_comp(__comp, __proj1, __proj2));
651cdec6c9SHui Xie     return {std::move(__ret.first), std::move(__ret.second)};
661cdec6c9SHui Xie   }
671cdec6c9SHui Xie 
685aa03b64SLouis Dionne   template <input_range _Range1,
691cdec6c9SHui Xie             input_range _Range2,
701cdec6c9SHui Xie             weakly_incrementable _OutIter,
711cdec6c9SHui Xie             class _Comp  = less,
721cdec6c9SHui Xie             class _Proj1 = identity,
731cdec6c9SHui Xie             class _Proj2 = identity>
741cdec6c9SHui Xie     requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _OutIter, _Comp, _Proj1, _Proj2>
751cdec6c9SHui Xie   _LIBCPP_HIDE_FROM_ABI constexpr set_difference_result<borrowed_iterator_t<_Range1>, _OutIter>
765aa03b64SLouis Dionne   operator()(_Range1&& __range1,
771cdec6c9SHui Xie              _Range2&& __range2,
781cdec6c9SHui Xie              _OutIter __result,
791cdec6c9SHui Xie              _Comp __comp   = {},
801cdec6c9SHui Xie              _Proj1 __proj1 = {},
811cdec6c9SHui Xie              _Proj2 __proj2 = {}) const {
82*a2042521SNikolas Klauser     auto __ret = std::__set_difference(
831cdec6c9SHui Xie         ranges::begin(__range1),
841cdec6c9SHui Xie         ranges::end(__range1),
851cdec6c9SHui Xie         ranges::begin(__range2),
861cdec6c9SHui Xie         ranges::end(__range2),
871cdec6c9SHui Xie         __result,
881cdec6c9SHui Xie         ranges::__make_projected_comp(__comp, __proj1, __proj2));
891cdec6c9SHui Xie     return {std::move(__ret.first), std::move(__ret.second)};
901cdec6c9SHui Xie   }
911cdec6c9SHui Xie };
921cdec6c9SHui Xie 
931cdec6c9SHui Xie inline namespace __cpo {
94d10dc5a0SChristopher Di Bella inline constexpr auto set_difference = __set_difference{};
951cdec6c9SHui Xie } // namespace __cpo
961cdec6c9SHui Xie } // namespace ranges
971cdec6c9SHui Xie 
981cdec6c9SHui Xie _LIBCPP_END_NAMESPACE_STD
991cdec6c9SHui Xie 
1004f15267dSNikolas Klauser #endif // _LIBCPP_STD_VER >= 20
1017b462251SLouis Dionne 
1027b462251SLouis Dionne _LIBCPP_POP_MACROS
1037b462251SLouis Dionne 
1041cdec6c9SHui Xie #endif // _LIBCPP___ALGORITHM_RANGES_SET_DIFFERENCE_H
105