diff mbox

Replace non-constexpr decrement in std::chrono::floor

Message ID 20161013142459.GA22865@redhat.com
State New
Headers show

Commit Message

Jonathan Wakely Oct. 13, 2016, 2:24 p.m. UTC
Decrementing a duration is not constexpr (yet ... I made an NB comment
about it).

I'm not sure if these functions are correct for floating-point
durations, because we could end up with a duration which is very very
slightly lower of higher than the desired value, but then we subtract
1.0 from it. That's what the reference implementation in Howard's
proposal does, so I'll worry about it another day.

	* include/std/chrono (floor): Replace non-constexpr operation.
	* testsuite/20_util/duration_cast/rounding.cc: Test conversion to
	durations with floating pointer representations.

Tested powerpc64le-linux, committed to trunk.
commit 7f55016a186e4df17ab3ab4fd6dd1821508e540e
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu Oct 13 14:03:57 2016 +0100

    Replace non-constexpr decrement in std::chrono::floor
    
    	* include/std/chrono (floor): Replace non-constexpr operation.
    	* testsuite/20_util/duration_cast/rounding.cc: Test conversion to
    	durations with floating pointer representations.

Comments

Jonathan Wakely Oct. 13, 2016, 2:33 p.m. UTC | #1
On 13/10/16 15:24 +0100, Jonathan Wakely wrote:
>Decrementing a duration is not constexpr (yet ... I made an NB comment
>about it).
>
>I'm not sure if these functions are correct for floating-point
>durations, because we could end up with a duration which is very very
>slightly lower of higher than the desired value, but then we subtract
>1.0 from it. That's what the reference implementation in Howard's
>proposal does, so I'll worry about it another day.
>
>	* include/std/chrono (floor): Replace non-constexpr operation.
>	* testsuite/20_util/duration_cast/rounding.cc: Test conversion to
>	durations with floating pointer representations.
>
>Tested powerpc64le-linux, committed to trunk.

Not actually committed yet because I'm stuck at:

  Committing to svn+ssh://redi@gcc.gnu.org/svn/gcc/trunk ...


It should finish eventually.
diff mbox

Patch

diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono
index cb8c876..ceae7f8 100644
--- a/libstdc++-v3/include/std/chrono
+++ b/libstdc++-v3/include/std/chrono
@@ -224,7 +224,7 @@  _GLIBCXX_END_NAMESPACE_VERSION
       {
 	auto __to = chrono::duration_cast<_ToDur>(__d);
 	if (__to > __d)
-	  --__to;
+	  return __to - _ToDur{1};
 	return __to;
       }
 
diff --git a/libstdc++-v3/testsuite/20_util/duration_cast/rounding.cc b/libstdc++-v3/testsuite/20_util/duration_cast/rounding.cc
index a753323..2a1df74 100644
--- a/libstdc++-v3/testsuite/20_util/duration_cast/rounding.cc
+++ b/libstdc++-v3/testsuite/20_util/duration_cast/rounding.cc
@@ -27,6 +27,8 @@ 
 using namespace std::chrono_literals;
 using std::chrono::seconds;
 
+using fp_seconds = std::chrono::duration<float>;
+
 static_assert( std::chrono::floor<seconds>(1000ms) == 1s );
 static_assert( std::chrono::floor<seconds>(1001ms) == 1s );
 static_assert( std::chrono::floor<seconds>(1500ms) == 1s );
@@ -34,6 +36,7 @@  static_assert( std::chrono::floor<seconds>(1999ms) == 1s );
 static_assert( std::chrono::floor<seconds>(2000ms) == 2s );
 static_assert( std::chrono::floor<seconds>(2001ms) == 2s );
 static_assert( std::chrono::floor<seconds>(2500ms) == 2s );
+static_assert( std::chrono::floor<fp_seconds>(500ms) == fp_seconds{0.5f} );
 
 static_assert( std::chrono::ceil<seconds>(1000ms) == 1s );
 static_assert( std::chrono::ceil<seconds>(1001ms) == 2s );
@@ -42,6 +45,7 @@  static_assert( std::chrono::ceil<seconds>(1999ms) == 2s );
 static_assert( std::chrono::ceil<seconds>(2000ms) == 2s );
 static_assert( std::chrono::ceil<seconds>(2001ms) == 3s );
 static_assert( std::chrono::ceil<seconds>(2500ms) == 3s );
+static_assert( std::chrono::ceil<fp_seconds>(500ms) == fp_seconds{0.5f} );
 
 static_assert( std::chrono::round<seconds>(1000ms) == 1s );
 static_assert( std::chrono::round<seconds>(1001ms) == 1s );