Implement P0025R0: 'An algorithm to clamp a value between a pair of boundary values' for C++17

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@262871 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/algorithm b/include/algorithm
index 71e5df3..7dba11e 100644
--- a/include/algorithm
+++ b/include/algorithm
@@ -543,6 +543,12 @@
     T
     min(initializer_list<T> t, Compare comp);  // constexpr in C++14
 
+template<class T>
+    constexpr const T& clamp( const T& v, const T& lo, const T& hi );               // C++17
+
+template<class T, class Compare>
+    constexpr const T& clamp( const T& v, const T& lo, const T& hi, Compare comp ); // C++17
+
 template <class ForwardIterator>
     ForwardIterator
     max_element(ForwardIterator first, ForwardIterator last);  // constexpr in C++14
@@ -2657,6 +2663,27 @@
 
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 
+#if _LIBCPP_STD_VER > 14
+// clamp
+template<class _Tp, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+const _Tp&
+clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi, _Compare __comp)
+{
+    _LIBCPP_ASSERT(!__comp(__hi, __lo), "Bad bounds passed to std::clamp");
+    return __comp(__v, __lo) ? __lo : __comp(__hi, __v) ? __hi : __v;
+
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+const _Tp&
+clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi)
+{
+    return _VSTD::clamp(__v, __lo, __hi, __less<_Tp>());
+}
+#endif
+
 // minmax_element
 
 template <class _ForwardIterator, class _Compare>