xref: /llvm-project/libcxx/include/__algorithm/ranges_is_partitioned.h (revision d10dc5a06fac4dcabf2264c64c8672c6f6ae36fb)
137ba1b9dSNikolas Klauser //===----------------------------------------------------------------------===//
237ba1b9dSNikolas Klauser //
337ba1b9dSNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
437ba1b9dSNikolas Klauser // See https://llvm.org/LICENSE.txt for license information.
537ba1b9dSNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
637ba1b9dSNikolas Klauser //
737ba1b9dSNikolas Klauser //===----------------------------------------------------------------------===//
837ba1b9dSNikolas Klauser 
937ba1b9dSNikolas Klauser #ifndef _LIBCPP___ALGORITHM_RANGES_IS_PARTITIONED_H
1037ba1b9dSNikolas Klauser #define _LIBCPP___ALGORITHM_RANGES_IS_PARTITIONED_H
1137ba1b9dSNikolas Klauser 
1237ba1b9dSNikolas Klauser #include <__config>
1337ba1b9dSNikolas Klauser #include <__functional/identity.h>
1437ba1b9dSNikolas Klauser #include <__functional/invoke.h>
1537ba1b9dSNikolas Klauser #include <__iterator/concepts.h>
1637ba1b9dSNikolas Klauser #include <__iterator/indirectly_comparable.h>
1737ba1b9dSNikolas Klauser #include <__iterator/projected.h>
1837ba1b9dSNikolas Klauser #include <__ranges/access.h>
1937ba1b9dSNikolas Klauser #include <__ranges/concepts.h>
2037ba1b9dSNikolas Klauser #include <__utility/move.h>
2137ba1b9dSNikolas Klauser 
2237ba1b9dSNikolas Klauser #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2337ba1b9dSNikolas Klauser #  pragma GCC system_header
2437ba1b9dSNikolas Klauser #endif
2537ba1b9dSNikolas Klauser 
267b462251SLouis Dionne _LIBCPP_PUSH_MACROS
277b462251SLouis Dionne #include <__undef_macros>
287b462251SLouis Dionne 
294f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 20
3037ba1b9dSNikolas Klauser 
3137ba1b9dSNikolas Klauser _LIBCPP_BEGIN_NAMESPACE_STD
3237ba1b9dSNikolas Klauser 
3337ba1b9dSNikolas Klauser namespace ranges {
34*d10dc5a0SChristopher Di Bella struct __is_partitioned {
3537ba1b9dSNikolas Klauser   template <class _Iter, class _Sent, class _Proj, class _Pred>
365aa03b64SLouis Dionne   _LIBCPP_HIDE_FROM_ABI constexpr static bool
37f4ec54b5SAmirreza Ashouri   __is_partitioned_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
3837ba1b9dSNikolas Klauser     for (; __first != __last; ++__first) {
3937ba1b9dSNikolas Klauser       if (!std::invoke(__pred, std::invoke(__proj, *__first)))
4037ba1b9dSNikolas Klauser         break;
4137ba1b9dSNikolas Klauser     }
4237ba1b9dSNikolas Klauser 
4337ba1b9dSNikolas Klauser     if (__first == __last)
4437ba1b9dSNikolas Klauser       return true;
4537ba1b9dSNikolas Klauser     ++__first;
4637ba1b9dSNikolas Klauser 
4737ba1b9dSNikolas Klauser     for (; __first != __last; ++__first) {
4837ba1b9dSNikolas Klauser       if (std::invoke(__pred, std::invoke(__proj, *__first)))
4937ba1b9dSNikolas Klauser         return false;
5037ba1b9dSNikolas Klauser     }
5137ba1b9dSNikolas Klauser 
5237ba1b9dSNikolas Klauser     return true;
5337ba1b9dSNikolas Klauser   }
5437ba1b9dSNikolas Klauser 
555aa03b64SLouis Dionne   template <input_iterator _Iter,
565aa03b64SLouis Dionne             sentinel_for<_Iter> _Sent,
5737ba1b9dSNikolas Klauser             class _Proj = identity,
5837ba1b9dSNikolas Klauser             indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
5983bc7b57SNikolas Klauser   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool
605aa03b64SLouis Dionne   operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
61f4ec54b5SAmirreza Ashouri     return __is_partitioned_impl(std::move(__first), std::move(__last), __pred, __proj);
6237ba1b9dSNikolas Klauser   }
6337ba1b9dSNikolas Klauser 
6437ba1b9dSNikolas Klauser   template <input_range _Range,
6537ba1b9dSNikolas Klauser             class _Proj = identity,
6637ba1b9dSNikolas Klauser             indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
6783bc7b57SNikolas Klauser   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool
685aa03b64SLouis Dionne   operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
69f4ec54b5SAmirreza Ashouri     return __is_partitioned_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
7037ba1b9dSNikolas Klauser   }
7137ba1b9dSNikolas Klauser };
7237ba1b9dSNikolas Klauser 
7337ba1b9dSNikolas Klauser inline namespace __cpo {
74*d10dc5a0SChristopher Di Bella inline constexpr auto is_partitioned = __is_partitioned{};
7537ba1b9dSNikolas Klauser } // namespace __cpo
7637ba1b9dSNikolas Klauser } // namespace ranges
7737ba1b9dSNikolas Klauser 
7837ba1b9dSNikolas Klauser _LIBCPP_END_NAMESPACE_STD
7937ba1b9dSNikolas Klauser 
804f15267dSNikolas Klauser #endif // _LIBCPP_STD_VER >= 20
8137ba1b9dSNikolas Klauser 
827b462251SLouis Dionne _LIBCPP_POP_MACROS
837b462251SLouis Dionne 
8437ba1b9dSNikolas Klauser #endif // _LIBCPP___ALGORITHM_RANGES_IS_PARTITIONED_H
85