1a203acb9SNikolas Klauser //===----------------------------------------------------------------------===// 2a203acb9SNikolas Klauser // 3a203acb9SNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4a203acb9SNikolas Klauser // See https://llvm.org/LICENSE.txt for license information. 5a203acb9SNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6a203acb9SNikolas Klauser // 7a203acb9SNikolas Klauser //===----------------------------------------------------------------------===// 8a203acb9SNikolas Klauser 9a203acb9SNikolas Klauser #ifndef _LIBCPP___ALGORITHM_RANGES_CLAMP_H 10a203acb9SNikolas Klauser #define _LIBCPP___ALGORITHM_RANGES_CLAMP_H 11a203acb9SNikolas Klauser 12a203acb9SNikolas Klauser #include <__assert> 13a203acb9SNikolas Klauser #include <__config> 14a203acb9SNikolas Klauser #include <__functional/identity.h> 15a203acb9SNikolas Klauser #include <__functional/invoke.h> 16a203acb9SNikolas Klauser #include <__functional/ranges_operations.h> 17a203acb9SNikolas Klauser #include <__iterator/concepts.h> 18a203acb9SNikolas Klauser #include <__iterator/projected.h> 19a203acb9SNikolas Klauser #include <__utility/forward.h> 20a203acb9SNikolas Klauser 21a203acb9SNikolas Klauser #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 22a203acb9SNikolas Klauser # pragma GCC system_header 23a203acb9SNikolas Klauser #endif 24a203acb9SNikolas Klauser 257b462251SLouis Dionne _LIBCPP_PUSH_MACROS 267b462251SLouis Dionne #include <__undef_macros> 277b462251SLouis Dionne 284f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 20 29a203acb9SNikolas Klauser 30a203acb9SNikolas Klauser _LIBCPP_BEGIN_NAMESPACE_STD 31a203acb9SNikolas Klauser 32a203acb9SNikolas Klauser namespace ranges { 33*d10dc5a0SChristopher Di Bella struct __clamp { 34a203acb9SNikolas Klauser template <class _Type, 35a203acb9SNikolas Klauser class _Proj = identity, 36a203acb9SNikolas Klauser indirect_strict_weak_order<projected<const _Type*, _Proj>> _Comp = ranges::less> 3783bc7b57SNikolas Klauser [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Type& operator()( 385aa03b64SLouis Dionne const _Type& __value, const _Type& __low, const _Type& __high, _Comp __comp = {}, _Proj __proj = {}) const { 39dc577520SKonstantin Varlamov _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN( 40dc577520SKonstantin Varlamov !bool(std::invoke(__comp, std::invoke(__proj, __high), std::invoke(__proj, __low))), 41a203acb9SNikolas Klauser "Bad bounds passed to std::ranges::clamp"); 42a203acb9SNikolas Klauser 43979c19abSLouis Dionne auto&& __projected = std::invoke(__proj, __value); 44979c19abSLouis Dionne if (std::invoke(__comp, std::forward<decltype(__projected)>(__projected), std::invoke(__proj, __low))) 45a203acb9SNikolas Klauser return __low; 46979c19abSLouis Dionne else if (std::invoke(__comp, std::invoke(__proj, __high), std::forward<decltype(__projected)>(__projected))) 47a203acb9SNikolas Klauser return __high; 48a203acb9SNikolas Klauser else 49a203acb9SNikolas Klauser return __value; 50a203acb9SNikolas Klauser } 51a203acb9SNikolas Klauser }; 52a203acb9SNikolas Klauser 53a203acb9SNikolas Klauser inline namespace __cpo { 54*d10dc5a0SChristopher Di Bella inline constexpr auto clamp = __clamp{}; 55a203acb9SNikolas Klauser } // namespace __cpo 56a203acb9SNikolas Klauser } // namespace ranges 57a203acb9SNikolas Klauser 58a203acb9SNikolas Klauser _LIBCPP_END_NAMESPACE_STD 59a203acb9SNikolas Klauser 604f15267dSNikolas Klauser #endif // _LIBCPP_STD_VER >= 20 61a203acb9SNikolas Klauser 627b462251SLouis Dionne _LIBCPP_POP_MACROS 637b462251SLouis Dionne 64a203acb9SNikolas Klauser #endif // _LIBCPP___ALGORITHM_RANGES_CLAMP_H 65