xref: /llvm-project/libcxx/include/__algorithm/ranges_min_element.h (revision d10dc5a06fac4dcabf2264c64c8672c6f6ae36fb)
13b470d1cSNikolas Klauser //===----------------------------------------------------------------------===//
23b470d1cSNikolas Klauser //
33b470d1cSNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
43b470d1cSNikolas Klauser // See https://llvm.org/LICENSE.txt for license information.
53b470d1cSNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63b470d1cSNikolas Klauser //
73b470d1cSNikolas Klauser //===----------------------------------------------------------------------===//
83b470d1cSNikolas Klauser 
93b470d1cSNikolas Klauser #ifndef _LIBCPP___ALGORITHM_RANGES_MIN_ELEMENT_H
103b470d1cSNikolas Klauser #define _LIBCPP___ALGORITHM_RANGES_MIN_ELEMENT_H
113b470d1cSNikolas Klauser 
123b470d1cSNikolas Klauser #include <__config>
133b470d1cSNikolas Klauser #include <__functional/identity.h>
143b470d1cSNikolas Klauser #include <__functional/invoke.h>
153b470d1cSNikolas Klauser #include <__functional/ranges_operations.h>
163b470d1cSNikolas Klauser #include <__iterator/concepts.h>
173b470d1cSNikolas Klauser #include <__iterator/projected.h>
183b470d1cSNikolas Klauser #include <__ranges/access.h>
193b470d1cSNikolas Klauser #include <__ranges/concepts.h>
203b470d1cSNikolas Klauser #include <__ranges/dangling.h>
213b470d1cSNikolas Klauser #include <__utility/forward.h>
223b470d1cSNikolas Klauser 
233b470d1cSNikolas Klauser #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
243b470d1cSNikolas Klauser #  pragma GCC system_header
253b470d1cSNikolas Klauser #endif
263b470d1cSNikolas Klauser 
277b462251SLouis Dionne _LIBCPP_PUSH_MACROS
287b462251SLouis Dionne #include <__undef_macros>
297b462251SLouis Dionne 
304f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 20
313b470d1cSNikolas Klauser 
323b470d1cSNikolas Klauser _LIBCPP_BEGIN_NAMESPACE_STD
333b470d1cSNikolas Klauser 
343b470d1cSNikolas Klauser namespace ranges {
35f83d833eSNikolas Klauser 
36a7c3379cSKonstantin Varlamov // TODO(ranges): `ranges::min_element` can now simply delegate to `std::__min_element`.
373b470d1cSNikolas Klauser template <class _Ip, class _Sp, class _Proj, class _Comp>
385aa03b64SLouis Dionne _LIBCPP_HIDE_FROM_ABI constexpr _Ip __min_element_impl(_Ip __first, _Sp __last, _Comp& __comp, _Proj& __proj) {
393b470d1cSNikolas Klauser   if (__first == __last)
403b470d1cSNikolas Klauser     return __first;
413b470d1cSNikolas Klauser 
423b470d1cSNikolas Klauser   _Ip __i = __first;
433b470d1cSNikolas Klauser   while (++__i != __last)
443b470d1cSNikolas Klauser     if (std::invoke(__comp, std::invoke(__proj, *__i), std::invoke(__proj, *__first)))
453b470d1cSNikolas Klauser       __first = __i;
463b470d1cSNikolas Klauser   return __first;
473b470d1cSNikolas Klauser }
483b470d1cSNikolas Klauser 
49*d10dc5a0SChristopher Di Bella struct __min_element {
505aa03b64SLouis Dionne   template <forward_iterator _Ip,
515aa03b64SLouis Dionne             sentinel_for<_Ip> _Sp,
525aa03b64SLouis Dionne             class _Proj                                             = identity,
533b470d1cSNikolas Klauser             indirect_strict_weak_order<projected<_Ip, _Proj>> _Comp = ranges::less>
5483bc7b57SNikolas Klauser   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Ip
555aa03b64SLouis Dionne   operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const {
56f83d833eSNikolas Klauser     return ranges::__min_element_impl(__first, __last, __comp, __proj);
573b470d1cSNikolas Klauser   }
583b470d1cSNikolas Klauser 
595aa03b64SLouis Dionne   template <forward_range _Rp,
605aa03b64SLouis Dionne             class _Proj                                                         = identity,
613b470d1cSNikolas Klauser             indirect_strict_weak_order<projected<iterator_t<_Rp>, _Proj>> _Comp = ranges::less>
6283bc7b57SNikolas Klauser   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp>
635aa03b64SLouis Dionne   operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
64f83d833eSNikolas Klauser     return ranges::__min_element_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj);
653b470d1cSNikolas Klauser   }
663b470d1cSNikolas Klauser };
673b470d1cSNikolas Klauser 
683b470d1cSNikolas Klauser inline namespace __cpo {
69*d10dc5a0SChristopher Di Bella inline constexpr auto min_element = __min_element{};
703b470d1cSNikolas Klauser } // namespace __cpo
713b470d1cSNikolas Klauser } // namespace ranges
723b470d1cSNikolas Klauser 
733b470d1cSNikolas Klauser _LIBCPP_END_NAMESPACE_STD
743b470d1cSNikolas Klauser 
754f15267dSNikolas Klauser #endif // _LIBCPP_STD_VER >= 20
763b470d1cSNikolas Klauser 
777b462251SLouis Dionne _LIBCPP_POP_MACROS
787b462251SLouis Dionne 
793b470d1cSNikolas Klauser #endif // _LIBCPP___ALGORITHM_RANGES_MIN_ELEMENT_H
80