public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [libstdc++] Add C++17clamp
@ 2016-07-14 23:50 Ed Smith-Rowland
  2016-07-15  7:34 ` Jonathan Wakely
  2016-07-21 23:38 ` NightStrike
  0 siblings, 2 replies; 11+ messages in thread
From: Ed Smith-Rowland @ 2016-07-14 23:50 UTC (permalink / raw)
  To: libstdc++, gcc-patches, Jonathan Wakely

[-- Attachment #1: Type: text/plain, Size: 240 bytes --]

Here is an implementation of P0025
An algorithm to "clamp" a value between a pair of boundary values.

Testing is almost finished - looks good so far.

OK if testing passes?

I didn't see a feature test in any of the SD-6 papers or P0025.


[-- Attachment #2: CL_clamp --]
[-- Type: text/plain, Size: 520 bytes --]


2016-07-15  Edward Smith-Rowland  <3dw4rd@verizon.net>

	Implement C++17 P0025 clamp.
	* include/bits/algorithmfwd.h: Declare clamp overloads.
	* include/bits/stl_algo.h: Implement clamp.
	* testsuite/25_algorithms/clamp/1.cc: New test.
	* testsuite/25_algorithms/clamp/2.cc: New test.
	* testsuite/25_algorithms/clamp/constexpr.cc: New test.
	* testsuite/25_algorithms/clamp/requirements/explicit_instantiation/
	1.cc: New test.
	* testsuite/25_algorithms/clamp/requirements/explicit_instantiation/
	pod.cc: New test.

[-- Attachment #3: patch_clamp --]
[-- Type: text/plain, Size: 13467 bytes --]

Index: include/bits/algorithmfwd.h
===================================================================
--- include/bits/algorithmfwd.h	(revision 238302)
+++ include/bits/algorithmfwd.h	(working copy)
@@ -48,6 +48,7 @@
     all_of (C++0x)
     any_of (C++0x)
     binary_search
+    clamp (C++17)
     copy
     copy_backward
     copy_if (C++0x)
@@ -208,6 +209,18 @@
     bool 
     binary_search(_FIter, _FIter, const _Tp&, _Compare);
 
+#if __cplusplus > 201402L
+  template<typename _Tp>
+    _GLIBCXX14_CONSTEXPR
+    const _Tp&
+    clamp(const _Tp&, const _Tp&, const _Tp&);
+
+  template<typename _Tp, typename _Compare>
+    _GLIBCXX14_CONSTEXPR
+    const _Tp&
+    clamp(const _Tp&, const _Tp&, const _Tp&, _Compare);
+#endif
+
   template<typename _IIter, typename _OIter>
     _OIter 
     copy(_IIter, _IIter, _OIter);
Index: include/bits/stl_algo.h
===================================================================
--- include/bits/stl_algo.h	(revision 238302)
+++ include/bits/stl_algo.h	(working copy)
@@ -3698,8 +3698,44 @@
       return std::__is_permutation(__first1, __last1, __first2, __last2,
 				   __gnu_cxx::__ops::__iter_comp_iter(__pred));
     }
-#endif
 
+#if __cplusplus > 201402L
+  /**
+   *  @brief  Returns the value clamped between lo and hi.
+   *  @ingroup sorting_algorithms
+   *  @param  __val  A value of arbitrary type.
+   *  @param  __lo   A lower limit of arbitrary type.
+   *  @param  __hi   An upper limit of arbitrary type.
+   *  @return max(__val, __lo) if __val < __hi or min(__val, __hi) otherwise.
+   */
+  template<typename _Tp>
+    constexpr const _Tp&
+    clamp(const _Tp& __val, const _Tp& __lo, const _Tp& __hi)
+    {
+      __glibcxx_assert(!(__hi < __lo));
+      return (__val < __lo) ? __lo : (__hi < __val) ? __hi : __val;
+    }
+
+  /**
+   *  @brief  Returns the value clamped between lo and hi.
+   *  @ingroup sorting_algorithms
+   *  @param  __val   A value of arbitrary type.
+   *  @param  __lo    A lower limit of arbitrary type.
+   *  @param  __hi    An upper limit of arbitrary type.
+   *  @param  __comp  A comparison functor.
+   *  @return max(__val, __lo, __comp) if __comp(__val, __hi)
+   *	      or min(__val, __hi, __comp) otherwise.
+   */
+  template<typename _Tp, typename _Compare>
+    constexpr const _Tp&
+    clamp(const _Tp& __val, const _Tp& __lo, const _Tp& __hi, _Compare __comp)
+    {
+      __glibcxx_assert(!__comp(__hi, __lo));
+      return __comp(__val, __lo) ? __lo : __comp(__hi, __val) ? __hi : __val;
+    }
+#endif // C++17
+#endif // C++14
+
 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
   /**
    *  @brief Shuffle the elements of a sequence using a uniform random
Index: testsuite/25_algorithms/clamp/1.cc
===================================================================
--- testsuite/25_algorithms/clamp/1.cc	(nonexistent)
+++ testsuite/25_algorithms/clamp/1.cc	(working copy)
@@ -0,0 +1,48 @@
+// { dg-options "-std=gnu++17" }
+
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <algorithm>
+#include <functional>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  const int x = std::clamp(1, 2, 4);
+  const int y = std::clamp(3, 2, 4);
+  const int z = std::clamp(5, 2, 4);
+  VERIFY( x == 2 );
+  VERIFY( y == 3 );
+  VERIFY( z == 4 );
+
+  const int xc = std::clamp(1, 2, 4, std::greater<int>());
+  const int yc = std::clamp(3, 2, 4, std::greater<int>());
+  const int zc = std::clamp(5, 2, 4, std::greater<int>());
+  VERIFY( xc == 4 );
+  VERIFY( yc == 2 );
+  VERIFY( zc == 2 );
+}
+
+int
+main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/25_algorithms/clamp/2.cc
===================================================================
--- testsuite/25_algorithms/clamp/2.cc	(nonexistent)
+++ testsuite/25_algorithms/clamp/2.cc	(working copy)
@@ -0,0 +1,102 @@
+// { dg-options "-std=gnu++17" }
+
+// Copyright (C) 2000-2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <algorithm>
+#include <functional>
+#include <testsuite_hooks.h>
+
+template<typename T>
+  struct A { static const T a; };
+
+template<typename T>
+const T A<T>::a = T(3);
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+
+  VERIFY( 3 == std::clamp(A<int>::a, 2, 4) );
+  VERIFY( 2 == std::clamp(A<int>::a, 1, 2) );
+  VERIFY( 4 == std::clamp(A<int>::a, 4, 6) );
+
+  VERIFY( 3u == std::clamp(A<unsigned int>::a, 2u, 4u) );
+  VERIFY( 2u == std::clamp(A<unsigned int>::a, 1u, 2u) );
+  VERIFY( 4u == std::clamp(A<unsigned int>::a, 4u, 6u) );
+
+  VERIFY( 3l == std::clamp(A<long>::a, 2l, 4l) );
+  VERIFY( 2l == std::clamp(A<long>::a, 1l, 2l) );
+  VERIFY( 4l == std::clamp(A<long>::a, 4l, 6l) );
+
+  VERIFY( 3ul == std::clamp(A<unsigned long>::a, 2ul, 4ul) );
+  VERIFY( 2ul == std::clamp(A<unsigned long>::a, 1ul, 2ul) );
+  VERIFY( 4ul == std::clamp(A<unsigned long>::a, 4ul, 6ul) );
+
+#ifdef _GLIBCXX_USE_LONG_LONG
+  VERIFY( 3ll == std::clamp(A<long long>::a, 2ll, 4ll) );
+  VERIFY( 2ll == std::clamp(A<long long>::a, 1ll, 2ll) );
+  VERIFY( 4ll == std::clamp(A<long long>::a, 4ll, 6ll) );
+
+  VERIFY( 3ull == std::clamp(A<unsigned long long>::a, 2ull, 4ull) );
+  VERIFY( 2ull == std::clamp(A<unsigned long long>::a, 1ull, 2ull) );
+  VERIFY( 4ull == std::clamp(A<unsigned long long>::a, 4ull, 6ull) );
+#endif
+
+  VERIFY( (short)3 == std::clamp(A<short>::a, (short)2, (short)4) );
+  VERIFY( (short)2 == std::clamp(A<short>::a, (short)1, (short)2) );
+  VERIFY( (short)4 == std::clamp(A<short>::a, (short)4, (short)6) );
+
+  VERIFY( (unsigned short)3 == std::clamp(A<unsigned short>::a, (unsigned short)2, (unsigned short)4) );
+  VERIFY( (unsigned short)2 == std::clamp(A<unsigned short>::a, (unsigned short)1, (unsigned short)2) );
+  VERIFY( (unsigned short)4 == std::clamp(A<unsigned short>::a, (unsigned short)4, (unsigned short)6) );
+
+  VERIFY( (char)3 == std::clamp(A<char>::a, (char)2, (char)4) );
+  VERIFY( (char)2 == std::clamp(A<char>::a, (char)1, (char)2) );
+  VERIFY( (char)4 == std::clamp(A<char>::a, (char)4, (char)6) );
+
+  VERIFY( (signed char)3 == std::clamp(A<signed char>::a, (signed char)2, (signed char)4) );
+  VERIFY( (signed char)2 == std::clamp(A<signed char>::a, (signed char)1, (signed char)2) );
+  VERIFY( (signed char)4 == std::clamp(A<signed char>::a, (signed char)4, (signed char)6) );
+
+  VERIFY( (unsigned char)3 == std::clamp(A<unsigned char>::a, (unsigned char)2, (unsigned char)4) );
+  VERIFY( (unsigned char)2 == std::clamp(A<unsigned char>::a, (unsigned char)1, (unsigned char)2) );
+  VERIFY( (unsigned char)4 == std::clamp(A<unsigned char>::a, (unsigned char)4, (unsigned char)6) );
+
+  VERIFY( (wchar_t)3 == std::clamp(A<wchar_t>::a, (wchar_t)2, (wchar_t)4) );
+  VERIFY( (wchar_t)2 == std::clamp(A<wchar_t>::a, (wchar_t)1, (wchar_t)2) );
+  VERIFY( (wchar_t)4 == std::clamp(A<wchar_t>::a, (wchar_t)4, (wchar_t)6) );
+
+  VERIFY( 3.0 == std::clamp(A<double>::a, 2.0, 4.0) );
+  VERIFY( 2.0 == std::clamp(A<double>::a, 1.0, 2.0) );
+  VERIFY( 4.0 == std::clamp(A<double>::a, 4.0, 6.0) );
+
+  VERIFY( 3.0f == std::clamp(A<float>::a, 2.0f, 4.0f) );
+  VERIFY( 2.0f == std::clamp(A<float>::a, 1.0f, 2.0f) );
+  VERIFY( 4.0f == std::clamp(A<float>::a, 4.0f, 6.0f) );
+
+  VERIFY( 3.0l == std::clamp(A<long double>::a, 2.0l, 4.0l) );
+  VERIFY( 2.0l == std::clamp(A<long double>::a, 1.0l, 2.0l) );
+  VERIFY( 4.0l == std::clamp(A<long double>::a, 4.0l, 6.0l) );
+}
+
+int
+main()
+{
+  test02();
+  return 0;
+}
Index: testsuite/25_algorithms/clamp/constexpr.cc
===================================================================
--- testsuite/25_algorithms/clamp/constexpr.cc	(nonexistent)
+++ testsuite/25_algorithms/clamp/constexpr.cc	(working copy)
@@ -0,0 +1,25 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <algorithm>
+#include <functional>
+
+static_assert(std::clamp(2, 0, 1) == 1, "");
+static_assert(std::clamp(2, 0, 1, std::greater<int>()) == 0, "");
Index: testsuite/25_algorithms/clamp/requirements/explicit_instantiation/1.cc
===================================================================
--- testsuite/25_algorithms/clamp/requirements/explicit_instantiation/1.cc	(nonexistent)
+++ testsuite/25_algorithms/clamp/requirements/explicit_instantiation/1.cc	(working copy)
@@ -0,0 +1,38 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <algorithm>
+#include <functional>
+#include <testsuite_api.h>
+
+namespace std
+{
+  using __gnu_test::NonDefaultConstructible;
+
+  typedef NonDefaultConstructible	value_type;
+  typedef value_type*			iterator_type;
+  typedef std::less<value_type>		compare_type;
+
+  template const value_type& clamp(const value_type&,
+				   const value_type&, const value_type&);
+  template const value_type& clamp(const value_type&,
+				   const value_type&, const value_type&,
+				   compare_type);
+}
Index: testsuite/25_algorithms/clamp/requirements/explicit_instantiation/pod.cc
===================================================================
--- testsuite/25_algorithms/clamp/requirements/explicit_instantiation/pod.cc	(nonexistent)
+++ testsuite/25_algorithms/clamp/requirements/explicit_instantiation/pod.cc	(working copy)
@@ -0,0 +1,38 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+
+#include <algorithm>
+#include <testsuite_character.h>
+
+namespace std
+{
+  using __gnu_test::pod_int;
+
+  typedef pod_int 		value_type;
+  typedef value_type* 		iterator_type;
+  typedef std::less<value_type> compare_type;
+
+  template const value_type& clamp(const value_type&,
+				   const value_type&, const value_type&);
+  template const value_type& clamp(const value_type&,
+				   const value_type&, const value_type&,
+				   compare_type);
+}

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [libstdc++] Add C++17clamp
  2016-07-14 23:50 [libstdc++] Add C++17clamp Ed Smith-Rowland
@ 2016-07-15  7:34 ` Jonathan Wakely
  2016-07-15 17:35   ` Ed Smith-Rowland
  2016-07-21 23:38 ` NightStrike
  1 sibling, 1 reply; 11+ messages in thread
From: Jonathan Wakely @ 2016-07-15  7:34 UTC (permalink / raw)
  To: Ed Smith-Rowland; +Cc: libstdc++, gcc-patches

On 14/07/16 19:50 -0400, Ed Smith-Rowland wrote:
>Here is an implementation of P0025
>An algorithm to "clamp" a value between a pair of boundary values.
>
>Testing is almost finished - looks good so far.
>
>OK if testing passes?

OK for trunk, thanks.

>I didn't see a feature test in any of the SD-6 papers or P0025.

p0096r3 proposes __cpp_lib_clamp = 201603.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [libstdc++] Add C++17clamp
  2016-07-15  7:34 ` Jonathan Wakely
@ 2016-07-15 17:35   ` Ed Smith-Rowland
  2016-07-21 18:24     ` Jonathan Wakely
  0 siblings, 1 reply; 11+ messages in thread
From: Ed Smith-Rowland @ 2016-07-15 17:35 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 219 bytes --]


> OK for trunk, thanks.
>
>> I didn't see a feature test in any of the SD-6 papers or P0025.
>
> p0096r3 proposes __cpp_lib_clamp = 201603.
I added the feature macro and committed the attached as 238383.

Thanks,

Ed


[-- Attachment #2: CL_clamp2 --]
[-- Type: text/plain, Size: 546 bytes --]

2016-07-15  Edward Smith-Rowland  <3dw4rd@verizon.net>

	Implement C++17 P0025 clamp.
	* include/bits/algorithmfwd.h: Declare clamp overloads.
	* include/bits/stl_algo.h: Implement clamp.  Feature __cpp_lib_clamp.
	* testsuite/25_algorithms/clamp/1.cc: New test.
	* testsuite/25_algorithms/clamp/2.cc: New test.
	* testsuite/25_algorithms/clamp/constexpr.cc: New test.
	* testsuite/25_algorithms/clamp/requirements/explicit_instantiation/
	1.cc: New test.
	* testsuite/25_algorithms/clamp/requirements/explicit_instantiation/
	pod.cc: New test.


[-- Attachment #3: patch_clamp2 --]
[-- Type: text/plain, Size: 13868 bytes --]

Index: include/bits/algorithmfwd.h
===================================================================
--- include/bits/algorithmfwd.h	(revision 238382)
+++ include/bits/algorithmfwd.h	(revision 238383)
@@ -48,6 +48,7 @@
     all_of (C++0x)
     any_of (C++0x)
     binary_search
+    clamp (C++17)
     copy
     copy_backward
     copy_if (C++0x)
@@ -208,6 +209,18 @@
     bool 
     binary_search(_FIter, _FIter, const _Tp&, _Compare);
 
+#if __cplusplus > 201402L
+  template<typename _Tp>
+    _GLIBCXX14_CONSTEXPR
+    const _Tp&
+    clamp(const _Tp&, const _Tp&, const _Tp&);
+
+  template<typename _Tp, typename _Compare>
+    _GLIBCXX14_CONSTEXPR
+    const _Tp&
+    clamp(const _Tp&, const _Tp&, const _Tp&, _Compare);
+#endif
+
   template<typename _IIter, typename _OIter>
     _OIter 
     copy(_IIter, _IIter, _OIter);
Index: include/bits/stl_algo.h
===================================================================
--- include/bits/stl_algo.h	(revision 238382)
+++ include/bits/stl_algo.h	(revision 238383)
@@ -3698,8 +3698,47 @@
       return std::__is_permutation(__first1, __last1, __first2, __last2,
 				   __gnu_cxx::__ops::__iter_comp_iter(__pred));
     }
-#endif
 
+#if __cplusplus > 201402L
+
+#define __cpp_lib_clamp 201603
+
+  /**
+   *  @brief  Returns the value clamped between lo and hi.
+   *  @ingroup sorting_algorithms
+   *  @param  __val  A value of arbitrary type.
+   *  @param  __lo   A lower limit of arbitrary type.
+   *  @param  __hi   An upper limit of arbitrary type.
+   *  @return max(__val, __lo) if __val < __hi or min(__val, __hi) otherwise.
+   */
+  template<typename _Tp>
+    constexpr const _Tp&
+    clamp(const _Tp& __val, const _Tp& __lo, const _Tp& __hi)
+    {
+      __glibcxx_assert(!(__hi < __lo));
+      return (__val < __lo) ? __lo : (__hi < __val) ? __hi : __val;
+    }
+
+  /**
+   *  @brief  Returns the value clamped between lo and hi.
+   *  @ingroup sorting_algorithms
+   *  @param  __val   A value of arbitrary type.
+   *  @param  __lo    A lower limit of arbitrary type.
+   *  @param  __hi    An upper limit of arbitrary type.
+   *  @param  __comp  A comparison functor.
+   *  @return max(__val, __lo, __comp) if __comp(__val, __hi)
+   *	      or min(__val, __hi, __comp) otherwise.
+   */
+  template<typename _Tp, typename _Compare>
+    constexpr const _Tp&
+    clamp(const _Tp& __val, const _Tp& __lo, const _Tp& __hi, _Compare __comp)
+    {
+      __glibcxx_assert(!__comp(__hi, __lo));
+      return __comp(__val, __lo) ? __lo : __comp(__hi, __val) ? __hi : __val;
+    }
+#endif // C++17
+#endif // C++14
+
 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
   /**
    *  @brief Shuffle the elements of a sequence using a uniform random
Index: testsuite/25_algorithms/clamp/1.cc
===================================================================
--- testsuite/25_algorithms/clamp/1.cc	(nonexistent)
+++ testsuite/25_algorithms/clamp/1.cc	(revision 238383)
@@ -0,0 +1,48 @@
+// { dg-options "-std=gnu++17" }
+
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <algorithm>
+#include <functional>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  const int x = std::clamp(1, 2, 4);
+  const int y = std::clamp(3, 2, 4);
+  const int z = std::clamp(5, 2, 4);
+  VERIFY( x == 2 );
+  VERIFY( y == 3 );
+  VERIFY( z == 4 );
+
+  const int xc = std::clamp(1, 2, 4, std::greater<int>());
+  const int yc = std::clamp(3, 2, 4, std::greater<int>());
+  const int zc = std::clamp(5, 2, 4, std::greater<int>());
+  VERIFY( xc == 4 );
+  VERIFY( yc == 2 );
+  VERIFY( zc == 2 );
+}
+
+int
+main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/25_algorithms/clamp/2.cc
===================================================================
--- testsuite/25_algorithms/clamp/2.cc	(nonexistent)
+++ testsuite/25_algorithms/clamp/2.cc	(revision 238383)
@@ -0,0 +1,102 @@
+// { dg-options "-std=gnu++17" }
+
+// Copyright (C) 2000-2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <algorithm>
+#include <functional>
+#include <testsuite_hooks.h>
+
+template<typename T>
+  struct A { static const T a; };
+
+template<typename T>
+const T A<T>::a = T(3);
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+
+  VERIFY( 3 == std::clamp(A<int>::a, 2, 4) );
+  VERIFY( 2 == std::clamp(A<int>::a, 1, 2) );
+  VERIFY( 4 == std::clamp(A<int>::a, 4, 6) );
+
+  VERIFY( 3u == std::clamp(A<unsigned int>::a, 2u, 4u) );
+  VERIFY( 2u == std::clamp(A<unsigned int>::a, 1u, 2u) );
+  VERIFY( 4u == std::clamp(A<unsigned int>::a, 4u, 6u) );
+
+  VERIFY( 3l == std::clamp(A<long>::a, 2l, 4l) );
+  VERIFY( 2l == std::clamp(A<long>::a, 1l, 2l) );
+  VERIFY( 4l == std::clamp(A<long>::a, 4l, 6l) );
+
+  VERIFY( 3ul == std::clamp(A<unsigned long>::a, 2ul, 4ul) );
+  VERIFY( 2ul == std::clamp(A<unsigned long>::a, 1ul, 2ul) );
+  VERIFY( 4ul == std::clamp(A<unsigned long>::a, 4ul, 6ul) );
+
+#ifdef _GLIBCXX_USE_LONG_LONG
+  VERIFY( 3ll == std::clamp(A<long long>::a, 2ll, 4ll) );
+  VERIFY( 2ll == std::clamp(A<long long>::a, 1ll, 2ll) );
+  VERIFY( 4ll == std::clamp(A<long long>::a, 4ll, 6ll) );
+
+  VERIFY( 3ull == std::clamp(A<unsigned long long>::a, 2ull, 4ull) );
+  VERIFY( 2ull == std::clamp(A<unsigned long long>::a, 1ull, 2ull) );
+  VERIFY( 4ull == std::clamp(A<unsigned long long>::a, 4ull, 6ull) );
+#endif
+
+  VERIFY( (short)3 == std::clamp(A<short>::a, (short)2, (short)4) );
+  VERIFY( (short)2 == std::clamp(A<short>::a, (short)1, (short)2) );
+  VERIFY( (short)4 == std::clamp(A<short>::a, (short)4, (short)6) );
+
+  VERIFY( (unsigned short)3 == std::clamp(A<unsigned short>::a, (unsigned short)2, (unsigned short)4) );
+  VERIFY( (unsigned short)2 == std::clamp(A<unsigned short>::a, (unsigned short)1, (unsigned short)2) );
+  VERIFY( (unsigned short)4 == std::clamp(A<unsigned short>::a, (unsigned short)4, (unsigned short)6) );
+
+  VERIFY( (char)3 == std::clamp(A<char>::a, (char)2, (char)4) );
+  VERIFY( (char)2 == std::clamp(A<char>::a, (char)1, (char)2) );
+  VERIFY( (char)4 == std::clamp(A<char>::a, (char)4, (char)6) );
+
+  VERIFY( (signed char)3 == std::clamp(A<signed char>::a, (signed char)2, (signed char)4) );
+  VERIFY( (signed char)2 == std::clamp(A<signed char>::a, (signed char)1, (signed char)2) );
+  VERIFY( (signed char)4 == std::clamp(A<signed char>::a, (signed char)4, (signed char)6) );
+
+  VERIFY( (unsigned char)3 == std::clamp(A<unsigned char>::a, (unsigned char)2, (unsigned char)4) );
+  VERIFY( (unsigned char)2 == std::clamp(A<unsigned char>::a, (unsigned char)1, (unsigned char)2) );
+  VERIFY( (unsigned char)4 == std::clamp(A<unsigned char>::a, (unsigned char)4, (unsigned char)6) );
+
+  VERIFY( (wchar_t)3 == std::clamp(A<wchar_t>::a, (wchar_t)2, (wchar_t)4) );
+  VERIFY( (wchar_t)2 == std::clamp(A<wchar_t>::a, (wchar_t)1, (wchar_t)2) );
+  VERIFY( (wchar_t)4 == std::clamp(A<wchar_t>::a, (wchar_t)4, (wchar_t)6) );
+
+  VERIFY( 3.0 == std::clamp(A<double>::a, 2.0, 4.0) );
+  VERIFY( 2.0 == std::clamp(A<double>::a, 1.0, 2.0) );
+  VERIFY( 4.0 == std::clamp(A<double>::a, 4.0, 6.0) );
+
+  VERIFY( 3.0f == std::clamp(A<float>::a, 2.0f, 4.0f) );
+  VERIFY( 2.0f == std::clamp(A<float>::a, 1.0f, 2.0f) );
+  VERIFY( 4.0f == std::clamp(A<float>::a, 4.0f, 6.0f) );
+
+  VERIFY( 3.0l == std::clamp(A<long double>::a, 2.0l, 4.0l) );
+  VERIFY( 2.0l == std::clamp(A<long double>::a, 1.0l, 2.0l) );
+  VERIFY( 4.0l == std::clamp(A<long double>::a, 4.0l, 6.0l) );
+}
+
+int
+main()
+{
+  test02();
+  return 0;
+}
Index: testsuite/25_algorithms/clamp/constexpr.cc
===================================================================
--- testsuite/25_algorithms/clamp/constexpr.cc	(nonexistent)
+++ testsuite/25_algorithms/clamp/constexpr.cc	(revision 238383)
@@ -0,0 +1,31 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <algorithm>
+#include <functional>
+
+#ifndef __cpp_lib_clamp
+# error "Feature-test macro for clamp missing"
+#elif __cpp_lib_clamp != 201603
+# error "Feature-test macro for clamp has wrong value"
+#endif
+
+static_assert(std::clamp(2, 0, 1) == 1, "");
+static_assert(std::clamp(2, 0, 1, std::greater<int>()) == 0, "");
Index: testsuite/25_algorithms/clamp/requirements/explicit_instantiation/1.cc
===================================================================
--- testsuite/25_algorithms/clamp/requirements/explicit_instantiation/1.cc	(nonexistent)
+++ testsuite/25_algorithms/clamp/requirements/explicit_instantiation/1.cc	(revision 238383)
@@ -0,0 +1,44 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <algorithm>
+#include <functional>
+#include <testsuite_api.h>
+
+#ifndef __cpp_lib_clamp
+# error "Feature-test macro for clamp missing"
+#elif __cpp_lib_clamp != 201603
+# error "Feature-test macro for clamp has wrong value"
+#endif
+
+namespace std
+{
+  using __gnu_test::NonDefaultConstructible;
+
+  typedef NonDefaultConstructible	value_type;
+  typedef value_type*			iterator_type;
+  typedef std::less<value_type>		compare_type;
+
+  template const value_type& clamp(const value_type&,
+				   const value_type&, const value_type&);
+  template const value_type& clamp(const value_type&,
+				   const value_type&, const value_type&,
+				   compare_type);
+}
Index: testsuite/25_algorithms/clamp/requirements/explicit_instantiation/pod.cc
===================================================================
--- testsuite/25_algorithms/clamp/requirements/explicit_instantiation/pod.cc	(nonexistent)
+++ testsuite/25_algorithms/clamp/requirements/explicit_instantiation/pod.cc	(revision 238383)
@@ -0,0 +1,38 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+
+#include <algorithm>
+#include <testsuite_character.h>
+
+namespace std
+{
+  using __gnu_test::pod_int;
+
+  typedef pod_int 		value_type;
+  typedef value_type* 		iterator_type;
+  typedef std::less<value_type> compare_type;
+
+  template const value_type& clamp(const value_type&,
+				   const value_type&, const value_type&);
+  template const value_type& clamp(const value_type&,
+				   const value_type&, const value_type&,
+				   compare_type);
+}

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [libstdc++] Add C++17clamp
  2016-07-15 17:35   ` Ed Smith-Rowland
@ 2016-07-21 18:24     ` Jonathan Wakely
  0 siblings, 0 replies; 11+ messages in thread
From: Jonathan Wakely @ 2016-07-21 18:24 UTC (permalink / raw)
  To: Ed Smith-Rowland; +Cc: libstdc++, gcc-patches

On 15/07/16 13:34 -0400, Ed Smith-Rowland wrote:
>
>>OK for trunk, thanks.
>>
>>>I didn't see a feature test in any of the SD-6 papers or P0025.
>>
>>p0096r3 proposes __cpp_lib_clamp = 201603.
>I added the feature macro and committed the attached as 238383.
>
>Thanks,
>
>Ed
>

>2016-07-15  Edward Smith-Rowland  <3dw4rd@verizon.net>
>
>	Implement C++17 P0025 clamp.
>	* include/bits/algorithmfwd.h: Declare clamp overloads.
>	* include/bits/stl_algo.h: Implement clamp.  Feature __cpp_lib_clamp.
>	* testsuite/25_algorithms/clamp/1.cc: New test.
>	* testsuite/25_algorithms/clamp/2.cc: New test.
>	* testsuite/25_algorithms/clamp/constexpr.cc: New test.
>	* testsuite/25_algorithms/clamp/requirements/explicit_instantiation/
>	1.cc: New test.
>	* testsuite/25_algorithms/clamp/requirements/explicit_instantiation/
>	pod.cc: New test.
>

>+  const int xc = std::clamp(1, 2, 4, std::greater<int>());
>+  const int yc = std::clamp(3, 2, 4, std::greater<int>());
>+  const int zc = std::clamp(5, 2, 4, std::greater<int>());

These all violate the precondition that !comp(hi, lo)
i.e. !greater<int>(1, 0)

The arguments need to be re-arranged, and then these are wrong:

>+  VERIFY( xc == 4 );
>+  VERIFY( yc == 2 );
>+  VERIFY( zc == 2 );


>+static_assert(std::clamp(2, 0, 1) == 1, "");
>+static_assert(std::clamp(2, 0, 1, std::greater<int>()) == 0, "");

Same here. If the arguments are clamp(2, 1, 0, greater<int>()) then it
returns 1.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [libstdc++] Add C++17clamp
  2016-07-14 23:50 [libstdc++] Add C++17clamp Ed Smith-Rowland
  2016-07-15  7:34 ` Jonathan Wakely
@ 2016-07-21 23:38 ` NightStrike
  2016-07-22  7:51   ` Jonathan Wakely
  1 sibling, 1 reply; 11+ messages in thread
From: NightStrike @ 2016-07-21 23:38 UTC (permalink / raw)
  To: Ed Smith-Rowland; +Cc: libstdc++, gcc-patches, Jonathan Wakely

On Thu, Jul 14, 2016 at 7:50 PM, Ed Smith-Rowland <3dw4rd@verizon.net> wrote:
> Here is an implementation of P0025
> An algorithm to "clamp" a value between a pair of boundary values.
>
> Testing is almost finished - looks good so far.
>
> OK if testing passes?
>
> I didn't see a feature test in any of the SD-6 papers or P0025.
>

This is not an efficient implementation.  See here:

https://gcc.gnu.org/ml/gcc-help/2014-10/msg00112.html

Which I derived from this SO answer (which is sadly not the accepted
answer at this time):

http://stackoverflow.com/a/16659263

I suggest using the very efficient method that requires a temporary.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [libstdc++] Add C++17clamp
  2016-07-21 23:38 ` NightStrike
@ 2016-07-22  7:51   ` Jonathan Wakely
  2016-07-22  7:55     ` Jonathan Wakely
  0 siblings, 1 reply; 11+ messages in thread
From: Jonathan Wakely @ 2016-07-22  7:51 UTC (permalink / raw)
  To: NightStrike; +Cc: Ed Smith-Rowland, libstdc++, gcc-patches

On 21/07/16 19:38 -0400, NightStrike wrote:
>On Thu, Jul 14, 2016 at 7:50 PM, Ed Smith-Rowland <3dw4rd@verizon.net> wrote:
>> Here is an implementation of P0025
>> An algorithm to "clamp" a value between a pair of boundary values.
>>
>> Testing is almost finished - looks good so far.
>>
>> OK if testing passes?
>>
>> I didn't see a feature test in any of the SD-6 papers or P0025.
>>
>
>This is not an efficient implementation.  See here:
>
>https://gcc.gnu.org/ml/gcc-help/2014-10/msg00112.html
>
>Which I derived from this SO answer (which is sadly not the accepted
>answer at this time):
>
>http://stackoverflow.com/a/16659263
>
>I suggest using the very efficient method that requires a temporary.

That isn't a valid implementation of std::clamp, since it performs a
copy. The template argument might not even be copyable.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [libstdc++] Add C++17clamp
  2016-07-22  7:51   ` Jonathan Wakely
@ 2016-07-22  7:55     ` Jonathan Wakely
  2016-07-22 17:38       ` Daniel Krügler
  2016-07-22 21:13       ` NightStrike
  0 siblings, 2 replies; 11+ messages in thread
From: Jonathan Wakely @ 2016-07-22  7:55 UTC (permalink / raw)
  To: NightStrike; +Cc: Ed Smith-Rowland, libstdc++, gcc-patches

On 22/07/16 08:51 +0100, Jonathan Wakely wrote:
>On 21/07/16 19:38 -0400, NightStrike wrote:
>>On Thu, Jul 14, 2016 at 7:50 PM, Ed Smith-Rowland <3dw4rd@verizon.net> wrote:
>>>Here is an implementation of P0025
>>>An algorithm to "clamp" a value between a pair of boundary values.
>>>
>>>Testing is almost finished - looks good so far.
>>>
>>>OK if testing passes?
>>>
>>>I didn't see a feature test in any of the SD-6 papers or P0025.
>>>
>>
>>This is not an efficient implementation.  See here:
>>
>>https://gcc.gnu.org/ml/gcc-help/2014-10/msg00112.html
>>
>>Which I derived from this SO answer (which is sadly not the accepted
>>answer at this time):
>>
>>http://stackoverflow.com/a/16659263
>>
>>I suggest using the very efficient method that requires a temporary.
>
>That isn't a valid implementation of std::clamp, since it performs a
>copy. The template argument might not even be copyable.


We could possibly dispatch to such an implementation for arithmetic
types, but we wouldn't want to do it for all copyable types. There's
no way you can know whether making that local copy is expensive for an
arbitrary type, and making a copy isn't allowed anyway.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [libstdc++] Add C++17clamp
  2016-07-22  7:55     ` Jonathan Wakely
@ 2016-07-22 17:38       ` Daniel Krügler
  2016-07-22 18:22         ` Jonathan Wakely
  2016-07-22 21:13       ` NightStrike
  1 sibling, 1 reply; 11+ messages in thread
From: Daniel Krügler @ 2016-07-22 17:38 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: NightStrike, Ed Smith-Rowland, libstdc++, gcc-patches

2016-07-22 9:55 GMT+02:00 Jonathan Wakely <jwakely@redhat.com>:
> On 22/07/16 08:51 +0100, Jonathan Wakely wrote:
>>
>> On 21/07/16 19:38 -0400, NightStrike wrote:
>>>
>>> On Thu, Jul 14, 2016 at 7:50 PM, Ed Smith-Rowland <3dw4rd@verizon.net>
>>> wrote:
>>>>
>>>> Here is an implementation of P0025
>>>> An algorithm to "clamp" a value between a pair of boundary values.
>>>>
>>>> Testing is almost finished - looks good so far.
>>>>
>>>> OK if testing passes?
>>>>
>>>> I didn't see a feature test in any of the SD-6 papers or P0025.
>>>>
>>>
>>> This is not an efficient implementation.  See here:
>>>
>>> https://gcc.gnu.org/ml/gcc-help/2014-10/msg00112.html
>>>
>>> Which I derived from this SO answer (which is sadly not the accepted
>>> answer at this time):
>>>
>>> http://stackoverflow.com/a/16659263
>>>
>>> I suggest using the very efficient method that requires a temporary.
>>
>>
>> That isn't a valid implementation of std::clamp, since it performs a
>> copy. The template argument might not even be copyable.
>
> We could possibly dispatch to such an implementation for arithmetic
> types, but we wouldn't want to do it for all copyable types. There's
> no way you can know whether making that local copy is expensive for an
> arbitrary type, and making a copy isn't allowed anyway.

But given that clamp is required not even to *return* copies of any of
it's arguments, it doesn't seem to be possible to do that for
arithmetic types either, unless I'm misunderstanding something very
fundamentally here. Or are you interpolating that the same performance
will result out of (ignoring constexpr) the following transformation

const float& clamp(const float& x, const float& min, const max) {
  const float& t = x < min ? min : x;
  return t > max ? max : t;
}

?

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [libstdc++] Add C++17clamp
  2016-07-22 17:38       ` Daniel Krügler
@ 2016-07-22 18:22         ` Jonathan Wakely
  0 siblings, 0 replies; 11+ messages in thread
From: Jonathan Wakely @ 2016-07-22 18:22 UTC (permalink / raw)
  To: Daniel Krügler; +Cc: NightStrike, Ed Smith-Rowland, libstdc++, gcc-patches

On 22/07/16 19:38 +0200, Daniel Krügler wrote:
>2016-07-22 9:55 GMT+02:00 Jonathan Wakely <jwakely@redhat.com>:
>> On 22/07/16 08:51 +0100, Jonathan Wakely wrote:
>>>
>>> On 21/07/16 19:38 -0400, NightStrike wrote:
>>>>
>>>> On Thu, Jul 14, 2016 at 7:50 PM, Ed Smith-Rowland <3dw4rd@verizon.net>
>>>> wrote:
>>>>>
>>>>> Here is an implementation of P0025
>>>>> An algorithm to "clamp" a value between a pair of boundary values.
>>>>>
>>>>> Testing is almost finished - looks good so far.
>>>>>
>>>>> OK if testing passes?
>>>>>
>>>>> I didn't see a feature test in any of the SD-6 papers or P0025.
>>>>>
>>>>
>>>> This is not an efficient implementation.  See here:
>>>>
>>>> https://gcc.gnu.org/ml/gcc-help/2014-10/msg00112.html
>>>>
>>>> Which I derived from this SO answer (which is sadly not the accepted
>>>> answer at this time):
>>>>
>>>> http://stackoverflow.com/a/16659263
>>>>
>>>> I suggest using the very efficient method that requires a temporary.
>>>
>>>
>>> That isn't a valid implementation of std::clamp, since it performs a
>>> copy. The template argument might not even be copyable.
>>
>> We could possibly dispatch to such an implementation for arithmetic
>> types, but we wouldn't want to do it for all copyable types. There's
>> no way you can know whether making that local copy is expensive for an
>> arbitrary type, and making a copy isn't allowed anyway.
>
>But given that clamp is required not even to *return* copies of any of
>it's arguments, it doesn't seem to be possible to do that for
>arithmetic types either, unless I'm misunderstanding something very
>fundamentally here. Or are you interpolating that the same performance
>will result out of (ignoring constexpr) the following transformation
>
>const float& clamp(const float& x, const float& min, const max) {
>  const float& t = x < min ? min : x;
>  return t > max ? max : t;
>}
>
>?

No, I was just overlooking the fact that of course we can't make a
copy if we have to return a reference to one of the arguments.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [libstdc++] Add C++17clamp
  2016-07-22  7:55     ` Jonathan Wakely
  2016-07-22 17:38       ` Daniel Krügler
@ 2016-07-22 21:13       ` NightStrike
  2016-07-22 23:59         ` Jonathan Wakely
  1 sibling, 1 reply; 11+ messages in thread
From: NightStrike @ 2016-07-22 21:13 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: Ed Smith-Rowland, libstdc++, gcc-patches

Would it be possible to fix the missed optimization to give the better
asm without having to do -ffast-math as mentioned here:

https://gcc.gnu.org/ml/gcc-help/2014-11/msg00034.html

If so, then the proposed implementation would be optimized for the simple case.


On Fri, Jul 22, 2016 at 3:55 AM, Jonathan Wakely <jwakely@redhat.com> wrote:
> On 22/07/16 08:51 +0100, Jonathan Wakely wrote:
>>
>> On 21/07/16 19:38 -0400, NightStrike wrote:
>>>
>>> On Thu, Jul 14, 2016 at 7:50 PM, Ed Smith-Rowland <3dw4rd@verizon.net>
>>> wrote:
>>>>
>>>> Here is an implementation of P0025
>>>> An algorithm to "clamp" a value between a pair of boundary values.
>>>>
>>>> Testing is almost finished - looks good so far.
>>>>
>>>> OK if testing passes?
>>>>
>>>> I didn't see a feature test in any of the SD-6 papers or P0025.
>>>>
>>>
>>> This is not an efficient implementation.  See here:
>>>
>>> https://gcc.gnu.org/ml/gcc-help/2014-10/msg00112.html
>>>
>>> Which I derived from this SO answer (which is sadly not the accepted
>>> answer at this time):
>>>
>>> http://stackoverflow.com/a/16659263
>>>
>>> I suggest using the very efficient method that requires a temporary.
>>
>>
>> That isn't a valid implementation of std::clamp, since it performs a
>> copy. The template argument might not even be copyable.
>
>
>
> We could possibly dispatch to such an implementation for arithmetic
> types, but we wouldn't want to do it for all copyable types. There's
> no way you can know whether making that local copy is expensive for an
> arbitrary type, and making a copy isn't allowed anyway.
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [libstdc++] Add C++17clamp
  2016-07-22 21:13       ` NightStrike
@ 2016-07-22 23:59         ` Jonathan Wakely
  0 siblings, 0 replies; 11+ messages in thread
From: Jonathan Wakely @ 2016-07-22 23:59 UTC (permalink / raw)
  To: NightStrike; +Cc: Ed Smith-Rowland, libstdc++, gcc-patches

On 22/07/16 17:12 -0400, NightStrike wrote:
>Would it be possible to fix the missed optimization to give the better
>asm without having to do -ffast-math as mentioned here:
>
>https://gcc.gnu.org/ml/gcc-help/2014-11/msg00034.html
>
>If so, then the proposed implementation would be optimized for the simple case.

If you want a missed optimization fixed then you should report it to
bugzilla, not on these lists.


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2016-07-22 23:59 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-14 23:50 [libstdc++] Add C++17clamp Ed Smith-Rowland
2016-07-15  7:34 ` Jonathan Wakely
2016-07-15 17:35   ` Ed Smith-Rowland
2016-07-21 18:24     ` Jonathan Wakely
2016-07-21 23:38 ` NightStrike
2016-07-22  7:51   ` Jonathan Wakely
2016-07-22  7:55     ` Jonathan Wakely
2016-07-22 17:38       ` Daniel Krügler
2016-07-22 18:22         ` Jonathan Wakely
2016-07-22 21:13       ` NightStrike
2016-07-22 23:59         ` Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).