1fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 2fe6060f1SDimitry Andric // 3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6fe6060f1SDimitry Andric // 7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 8fe6060f1SDimitry Andric 9fe6060f1SDimitry Andric #ifndef _LIBCPP___ALGORITHM_MINMAX_H 10fe6060f1SDimitry Andric #define _LIBCPP___ALGORITHM_MINMAX_H 11fe6060f1SDimitry Andric 12fe6060f1SDimitry Andric #include <__algorithm/comp.h> 1381ad6265SDimitry Andric #include <__algorithm/minmax_element.h> 1404eeddc0SDimitry Andric #include <__config> 1581ad6265SDimitry Andric #include <__functional/identity.h> 1681ad6265SDimitry Andric #include <__type_traits/is_callable.h> 1781ad6265SDimitry Andric #include <__utility/pair.h> 18fe6060f1SDimitry Andric #include <initializer_list> 19fe6060f1SDimitry Andric 20fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 21fe6060f1SDimitry Andric # pragma GCC system_header 22fe6060f1SDimitry Andric #endif 23fe6060f1SDimitry Andric 24fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 25fe6060f1SDimitry Andric 26fe6060f1SDimitry Andric template <class _Tp, class _Compare> 27*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<const _Tp&, const _Tp&> 28cb14a3feSDimitry Andric minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp) { 29cb14a3feSDimitry Andric return __comp(__b, __a) ? pair<const _Tp&, const _Tp&>(__b, __a) : pair<const _Tp&, const _Tp&>(__a, __b); 30fe6060f1SDimitry Andric } 31fe6060f1SDimitry Andric 32fe6060f1SDimitry Andric template <class _Tp> 33*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<const _Tp&, const _Tp&> 34cb14a3feSDimitry Andric minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) { 3506c3fb27SDimitry Andric return std::minmax(__a, __b, __less<>()); 36fe6060f1SDimitry Andric } 37fe6060f1SDimitry Andric 38fe6060f1SDimitry Andric #ifndef _LIBCPP_CXX03_LANG 39fe6060f1SDimitry Andric 40fe6060f1SDimitry Andric template <class _Tp, class _Compare> 41*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Tp, _Tp> 42cb14a3feSDimitry Andric minmax(initializer_list<_Tp> __t, _Compare __comp) { 4381ad6265SDimitry Andric static_assert(__is_callable<_Compare, _Tp, _Tp>::value, "The comparator has to be callable"); 4481ad6265SDimitry Andric __identity __proj; 4581ad6265SDimitry Andric auto __ret = std::__minmax_element_impl(__t.begin(), __t.end(), __comp, __proj); 4681ad6265SDimitry Andric return pair<_Tp, _Tp>(*__ret.first, *__ret.second); 47fe6060f1SDimitry Andric } 48fe6060f1SDimitry Andric 49fe6060f1SDimitry Andric template <class _Tp> 50*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Tp, _Tp> 51cb14a3feSDimitry Andric minmax(initializer_list<_Tp> __t) { 5206c3fb27SDimitry Andric return std::minmax(__t, __less<>()); 53fe6060f1SDimitry Andric } 54fe6060f1SDimitry Andric 55fe6060f1SDimitry Andric #endif // _LIBCPP_CXX03_LANG 56fe6060f1SDimitry Andric 57fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD 58fe6060f1SDimitry Andric 59fe6060f1SDimitry Andric #endif // _LIBCPP___ALGORITHM_MINMAX_H 60