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_PARTITION_H 10134723edSLouis Dionne #define _LIBCPP___ALGORITHM_PARTITION_H 11134723edSLouis Dionne 128ed702b8SKonstantin Varlamov #include <__algorithm/iterator_operations.h> 13134723edSLouis Dionne #include <__config> 14134723edSLouis Dionne #include <__iterator/iterator_traits.h> 15*09e3a360SLouis Dionne #include <__type_traits/remove_cvref.h> 168ed702b8SKonstantin Varlamov #include <__utility/move.h> 178ed702b8SKonstantin Varlamov #include <__utility/pair.h> 18134723edSLouis Dionne 19134723edSLouis Dionne #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 20134723edSLouis Dionne # pragma GCC system_header 21134723edSLouis Dionne #endif 22134723edSLouis Dionne 237b462251SLouis Dionne _LIBCPP_PUSH_MACROS 247b462251SLouis Dionne #include <__undef_macros> 257b462251SLouis Dionne 26134723edSLouis Dionne _LIBCPP_BEGIN_NAMESPACE_STD 27134723edSLouis Dionne 288ed702b8SKonstantin Varlamov template <class _Predicate, class _AlgPolicy, class _ForwardIterator, class _Sentinel> 295146b57bSNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> 309783f28cSLouis Dionne __partition_impl(_ForwardIterator __first, _Sentinel __last, _Predicate __pred, forward_iterator_tag) { 319783f28cSLouis Dionne while (true) { 32134723edSLouis Dionne if (__first == __last) 33f73050e7SLouis Dionne return std::make_pair(__first, __first); 34134723edSLouis Dionne if (!__pred(*__first)) 35134723edSLouis Dionne break; 36134723edSLouis Dionne ++__first; 37134723edSLouis Dionne } 388ed702b8SKonstantin Varlamov 398ed702b8SKonstantin Varlamov _ForwardIterator __p = __first; 409783f28cSLouis Dionne while (++__p != __last) { 419783f28cSLouis Dionne if (__pred(*__p)) { 428ed702b8SKonstantin Varlamov _IterOps<_AlgPolicy>::iter_swap(__first, __p); 43134723edSLouis Dionne ++__first; 44134723edSLouis Dionne } 45134723edSLouis Dionne } 468ed702b8SKonstantin Varlamov return std::make_pair(std::move(__first), std::move(__p)); 47134723edSLouis Dionne } 48134723edSLouis Dionne 498ed702b8SKonstantin Varlamov template <class _Predicate, class _AlgPolicy, class _BidirectionalIterator, class _Sentinel> 505146b57bSNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator, _BidirectionalIterator> 519783f28cSLouis Dionne __partition_impl(_BidirectionalIterator __first, _Sentinel __sentinel, _Predicate __pred, bidirectional_iterator_tag) { 528ed702b8SKonstantin Varlamov _BidirectionalIterator __original_last = _IterOps<_AlgPolicy>::next(__first, __sentinel); 538ed702b8SKonstantin Varlamov _BidirectionalIterator __last = __original_last; 548ed702b8SKonstantin Varlamov 559783f28cSLouis Dionne while (true) { 569783f28cSLouis Dionne while (true) { 57134723edSLouis Dionne if (__first == __last) 588ed702b8SKonstantin Varlamov return std::make_pair(std::move(__first), std::move(__original_last)); 59134723edSLouis Dionne if (!__pred(*__first)) 60134723edSLouis Dionne break; 61134723edSLouis Dionne ++__first; 62134723edSLouis Dionne } 639783f28cSLouis Dionne do { 64134723edSLouis Dionne if (__first == --__last) 658ed702b8SKonstantin Varlamov return std::make_pair(std::move(__first), std::move(__original_last)); 66134723edSLouis Dionne } while (!__pred(*__last)); 678ed702b8SKonstantin Varlamov _IterOps<_AlgPolicy>::iter_swap(__first, __last); 68134723edSLouis Dionne ++__first; 69134723edSLouis Dionne } 70134723edSLouis Dionne } 71134723edSLouis Dionne 728ed702b8SKonstantin Varlamov template <class _AlgPolicy, class _ForwardIterator, class _Sentinel, class _Predicate, class _IterCategory> 739783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> 749783f28cSLouis Dionne __partition(_ForwardIterator __first, _Sentinel __last, _Predicate&& __pred, _IterCategory __iter_category) { 755fab33afSNikolas Klauser return std::__partition_impl<__remove_cvref_t<_Predicate>&, _AlgPolicy>( 768ed702b8SKonstantin Varlamov std::move(__first), std::move(__last), __pred, __iter_category); 778ed702b8SKonstantin Varlamov } 788ed702b8SKonstantin Varlamov 79134723edSLouis Dionne template <class _ForwardIterator, class _Predicate> 809783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator 819783f28cSLouis Dionne partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { 828ed702b8SKonstantin Varlamov using _IterCategory = typename iterator_traits<_ForwardIterator>::iterator_category; 838ed702b8SKonstantin Varlamov auto __result = std::__partition<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __pred, _IterCategory()); 848ed702b8SKonstantin Varlamov return __result.first; 85134723edSLouis Dionne } 86134723edSLouis Dionne 87134723edSLouis Dionne _LIBCPP_END_NAMESPACE_STD 88134723edSLouis Dionne 897b462251SLouis Dionne _LIBCPP_POP_MACROS 907b462251SLouis Dionne 91134723edSLouis Dionne #endif // _LIBCPP___ALGORITHM_PARTITION_H 92