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_UNION_H 10134723edSLouis Dionne #define _LIBCPP___ALGORITHM_SET_UNION_H 11134723edSLouis Dionne 12134723edSLouis Dionne #include <__algorithm/comp.h> 13134723edSLouis Dionne #include <__algorithm/comp_ref_type.h> 14134723edSLouis Dionne #include <__algorithm/copy.h> 154d81a46fSArthur O'Dwyer #include <__config> 16134723edSLouis Dionne #include <__iterator/iterator_traits.h> 17*3151b95dSHui Xie #include <__utility/move.h> 18134723edSLouis Dionne 19134723edSLouis Dionne #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 20134723edSLouis Dionne # pragma GCC system_header 21134723edSLouis Dionne #endif 22134723edSLouis Dionne 23134723edSLouis Dionne _LIBCPP_BEGIN_NAMESPACE_STD 24134723edSLouis Dionne 25*3151b95dSHui Xie template <class _InIter1, class _InIter2, class _OutIter> 26*3151b95dSHui Xie struct __set_union_result { 27*3151b95dSHui Xie _InIter1 __in1_; 28*3151b95dSHui Xie _InIter2 __in2_; 29*3151b95dSHui Xie _OutIter __out_; 30*3151b95dSHui Xie 31*3151b95dSHui Xie // need a constructor as C++03 aggregate init is hard 32*3151b95dSHui Xie _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 33*3151b95dSHui Xie __set_union_result(_InIter1&& __in_iter1, _InIter2&& __in_iter2, _OutIter&& __out_iter) 34*3151b95dSHui Xie : __in1_(std::move(__in_iter1)), __in2_(std::move(__in_iter2)), __out_(std::move(__out_iter)) {} 35*3151b95dSHui Xie }; 36*3151b95dSHui Xie 37*3151b95dSHui Xie template <class _Compare, class _InIter1, class _Sent1, class _InIter2, class _Sent2, class _OutIter> 38*3151b95dSHui Xie _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 __set_union_result<_InIter1, _InIter2, _OutIter> __set_union( 39*3151b95dSHui Xie _InIter1 __first1, _Sent1 __last1, _InIter2 __first2, _Sent2 __last2, _OutIter __result, _Compare&& __comp) { 40*3151b95dSHui Xie for (; __first1 != __last1; ++__result) { 41*3151b95dSHui Xie if (__first2 == __last2) { 42*3151b95dSHui Xie auto __ret1 = std::__copy_impl(std::move(__first1), std::move(__last1), std::move(__result)); 43*3151b95dSHui Xie return __set_union_result<_InIter1, _InIter2, _OutIter>( 44*3151b95dSHui Xie std::move(__ret1.first), std::move(__first2), std::move((__ret1.second))); 45*3151b95dSHui Xie } 46*3151b95dSHui Xie if (__comp(*__first2, *__first1)) { 47134723edSLouis Dionne *__result = *__first2; 48134723edSLouis Dionne ++__first2; 49*3151b95dSHui Xie } else { 50*3151b95dSHui Xie if (!__comp(*__first1, *__first2)) { 51134723edSLouis Dionne ++__first2; 52*3151b95dSHui Xie } 53134723edSLouis Dionne *__result = *__first1; 54134723edSLouis Dionne ++__first1; 55134723edSLouis Dionne } 56134723edSLouis Dionne } 57*3151b95dSHui Xie auto __ret2 = std::__copy_impl(std::move(__first2), std::move(__last2), std::move(__result)); 58*3151b95dSHui Xie return __set_union_result<_InIter1, _InIter2, _OutIter>( 59*3151b95dSHui Xie std::move(__first1), std::move(__ret2.first), std::move((__ret2.second))); 60134723edSLouis Dionne } 61134723edSLouis Dionne 62134723edSLouis Dionne template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare> 63*3151b95dSHui Xie _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator set_union( 64*3151b95dSHui Xie _InputIterator1 __first1, 65*3151b95dSHui Xie _InputIterator1 __last1, 66*3151b95dSHui Xie _InputIterator2 __first2, 67*3151b95dSHui Xie _InputIterator2 __last2, 68*3151b95dSHui Xie _OutputIterator __result, 69*3151b95dSHui Xie _Compare __comp) { 70134723edSLouis Dionne typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 71*3151b95dSHui Xie return std::__set_union<_Comp_ref>( 72*3151b95dSHui Xie std::move(__first1), 73*3151b95dSHui Xie std::move(__last1), 74*3151b95dSHui Xie std::move(__first2), 75*3151b95dSHui Xie std::move(__last2), 76*3151b95dSHui Xie std::move(__result), 77*3151b95dSHui Xie __comp) 78*3151b95dSHui Xie .__out_; 79134723edSLouis Dionne } 80134723edSLouis Dionne 81134723edSLouis Dionne template <class _InputIterator1, class _InputIterator2, class _OutputIterator> 82*3151b95dSHui Xie _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator set_union( 83*3151b95dSHui Xie _InputIterator1 __first1, 84*3151b95dSHui Xie _InputIterator1 __last1, 85*3151b95dSHui Xie _InputIterator2 __first2, 86*3151b95dSHui Xie _InputIterator2 __last2, 87*3151b95dSHui Xie _OutputIterator __result) { 88*3151b95dSHui Xie return std::set_union( 89*3151b95dSHui Xie std::move(__first1), 90*3151b95dSHui Xie std::move(__last1), 91*3151b95dSHui Xie std::move(__first2), 92*3151b95dSHui Xie std::move(__last2), 93*3151b95dSHui Xie std::move(__result), 94134723edSLouis Dionne __less<typename iterator_traits<_InputIterator1>::value_type, 95134723edSLouis Dionne typename iterator_traits<_InputIterator2>::value_type>()); 96134723edSLouis Dionne } 97134723edSLouis Dionne 98134723edSLouis Dionne _LIBCPP_END_NAMESPACE_STD 99134723edSLouis Dionne 100134723edSLouis Dionne #endif // _LIBCPP___ALGORITHM_SET_UNION_H 101