[gcc/devel/c++-coroutines] libstdc++: Add comparison operators to <chrono> types

Iain D Sandoe iains@gcc.gnu.org
Sat Apr 18 20:02:46 GMT 2020


https://gcc.gnu.org/g:27c171775abb943d59e2b3fb6fbc0b3680fc7a39

commit 27c171775abb943d59e2b3fb6fbc0b3680fc7a39
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Sat Apr 18 00:47:45 2020 +0100

    libstdc++: Add comparison operators to <chrono> types
    
    Some more C++20 changes from P1614R2, "The Mothership has Landed".
    
            * include/std/chrono (duration, time_point): Define operator<=> and
            remove redundant operator!= for C++20.
            * testsuite/20_util/duration/comparison_operators/three_way.cc: New
            test.
            * testsuite/20_util/time_point/comparison_operators/three_way.cc: New
            test.

Diff:
---
 libstdc++-v3/ChangeLog                             |  7 +++
 libstdc++-v3/include/std/chrono                    | 24 +++++++++
 .../duration/comparison_operators/three_way.cc     | 62 ++++++++++++++++++++++
 .../time_point/comparison_operators/three_way.cc   | 41 ++++++++++++++
 4 files changed, 134 insertions(+)

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 64c862c1d03..40345cc7044 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,12 @@
 2020-04-18  Jonathan Wakely  <jwakely@redhat.com>
 
+	* include/std/chrono (duration, time_point): Define operator<=> and
+	remove redundant operator!= for C++20.
+	* testsuite/20_util/duration/comparison_operators/three_way.cc: New
+	test.
+	* testsuite/20_util/time_point/comparison_operators/three_way.cc: New
+	test.
+
 	* testsuite/util/native_type/native_priority_queue.hpp: Use
 	allocator_traits to rebind allocator.
 
diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono
index 514926c5c05..6d78f32ac78 100644
--- a/libstdc++-v3/include/std/chrono
+++ b/libstdc++-v3/include/std/chrono
@@ -43,6 +43,7 @@
 #include <bits/parse_numbers.h> // for literals support.
 #if __cplusplus > 201703L
 # include <concepts>
+# include <compare>
 #endif
 
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -668,12 +669,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	return __ct(__lhs).count() < __ct(__rhs).count();
       }
 
+#if __cpp_lib_three_way_comparison
+    template<typename _Rep1, typename _Period1,
+	     typename _Rep2, typename _Period2>
+      requires three_way_comparable<common_type_t<_Rep1, _Rep2>>
+      constexpr auto
+      operator<=>(const duration<_Rep1, _Period1>& __lhs,
+		  const duration<_Rep2, _Period2>& __rhs)
+      {
+	using __ct = common_type_t<duration<_Rep1, _Period1>,
+				   duration<_Rep2, _Period2>>;
+	return __ct(__lhs).count() <=> __ct(__rhs).count();
+      }
+#else
     template<typename _Rep1, typename _Period1,
 	     typename _Rep2, typename _Period2>
       constexpr bool
       operator!=(const duration<_Rep1, _Period1>& __lhs,
 		 const duration<_Rep2, _Period2>& __rhs)
       { return !(__lhs == __rhs); }
+#endif
 
     template<typename _Rep1, typename _Period1,
 	     typename _Rep2, typename _Period2>
@@ -903,11 +918,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 		 const time_point<_Clock, _Dur2>& __rhs)
       { return __lhs.time_since_epoch() == __rhs.time_since_epoch(); }
 
+#if __cpp_lib_three_way_comparison
+    template<typename _Clock, typename _Dur1,
+	     three_way_comparable_with<_Dur1> _Dur2>
+      constexpr auto
+      operator<=>(const time_point<_Clock, _Dur1>& __lhs,
+		  const time_point<_Clock, _Dur2>& __rhs)
+      { return __lhs.time_since_epoch() <=> __rhs.time_since_epoch(); }
+#else
     template<typename _Clock, typename _Dur1, typename _Dur2>
       constexpr bool
       operator!=(const time_point<_Clock, _Dur1>& __lhs,
 		 const time_point<_Clock, _Dur2>& __rhs)
       { return !(__lhs == __rhs); }
+#endif
 
     template<typename _Clock, typename _Dur1, typename _Dur2>
       constexpr bool
diff --git a/libstdc++-v3/testsuite/20_util/duration/comparison_operators/three_way.cc b/libstdc++-v3/testsuite/20_util/duration/comparison_operators/three_way.cc
new file mode 100644
index 00000000000..12c20f82811
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/duration/comparison_operators/three_way.cc
@@ -0,0 +1,62 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+
+// Copyright (C) 2020 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/>.
+
+// 20.8.3 Class template duration [time.duration]
+
+#include <chrono>
+#include <testsuite_hooks.h>
+
+// C++20 27.5.6 Comparisons [time.duration.comparisons]
+
+void
+test01()
+{
+  using namespace std::chrono;
+
+  duration<int> d0(12);
+  duration<int> d1(3);
+  duration<long> d2(3);
+
+  VERIFY(d1 < d0);
+  VERIFY(d0 > d1);
+  VERIFY( std::is_lt(d1 <=> d0) );
+  VERIFY( std::is_gt(d0 <=> d1) );
+
+  VERIFY(d0 != d1);
+  VERIFY(d1 == d2);
+  VERIFY( std::is_neq(d0 <=> d1) );
+  VERIFY( std::is_eq(d1 <=> d2) );
+
+  VERIFY(d1 <= d2);
+  VERIFY(d1 >= d2);
+  VERIFY( std::is_lteq(d1 <=> d2) );
+  VERIFY( std::is_gteq(d1 <=> d2) );
+
+  VERIFY(d1 <= d0);
+  VERIFY(d0 >= d1);
+  VERIFY( std::is_lteq(d1 <=> d0) );
+  VERIFY( std::is_gteq(d0 <=> d1) );
+}
+
+int
+main()
+{
+  test01();
+}
diff --git a/libstdc++-v3/testsuite/20_util/time_point/comparison_operators/three_way.cc b/libstdc++-v3/testsuite/20_util/time_point/comparison_operators/three_way.cc
new file mode 100644
index 00000000000..b753bcf253e
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/time_point/comparison_operators/three_way.cc
@@ -0,0 +1,41 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+
+// Copyright (C) 2020 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 <chrono>
+#include <testsuite_hooks.h>
+
+// C++20 27.6.6 Comparisons [time.point.comparisons]
+
+void
+test01()
+{
+  using namespace std::chrono;
+
+  auto ns = system_clock::now();
+  auto s = time_point_cast<seconds>(ns + seconds(2));
+
+  VERIFY( s != ns );
+  VERIFY( std::is_lt(ns <=> s) );
+}
+
+int main()
+{
+  test01();
+}


More information about the Libstdc++-cvs mailing list