public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
* [committed] libstdc++: Define and use variable templates in <chrono>
@ 2022-12-22 10:15 Jonathan Wakely
  0 siblings, 0 replies; only message in thread
From: Jonathan Wakely @ 2022-12-22 10:15 UTC (permalink / raw)
  To: libstdc++, gcc-patches

Tested x86_64-linux. Pushed to trunk.

-- >8 --

Thi defines a variable template for the internal __is_duration helper
trait, defines a new __is_time_point_v variable template (to be used in
a subsequent commit), and adds explicit specializations of the standard
chrono::treat_as_floating_point trait for common types.

A fast path is added to chrono::duration_cast for the no-op case where
no conversion is needed.

Finally, some SFINAE constraints are simplified by using the
__enable_if_t alias, or by using variable templates.

libstdc++-v3/ChangeLog:

	* include/bits/chrono.h (__is_duration_v, __is_time_point_v):
	New variable templates.
	(duration_cast): Add simplified definition for noconv case.
	(treat_as_floating_point_v): Add explicit specializations.
	(duration::operator%=, floor, ceil, round): Simplify SFINAE
	constraints.
---
 libstdc++-v3/include/bits/chrono.h | 62 ++++++++++++++++++++++--------
 1 file changed, 45 insertions(+), 17 deletions(-)

diff --git a/libstdc++-v3/include/bits/chrono.h b/libstdc++-v3/include/bits/chrono.h
index 22c0be3fbe6..56751d1c3a0 100644
--- a/libstdc++-v3/include/bits/chrono.h
+++ b/libstdc++-v3/include/bits/chrono.h
@@ -244,6 +244,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       using __disable_if_is_duration
 	= typename enable_if<!__is_duration<_Tp>::value, _Tp>::type;
 
+#if __cpp_variable_templates
+    template<typename _Tp>
+      inline constexpr bool __is_duration_v = false;
+    template<typename _Rep, typename _Period>
+      inline constexpr bool __is_duration_v<duration<_Rep, _Period>> = true;
+    template<typename _Tp>
+      inline constexpr bool __is_time_point_v = false;
+    template<typename _Clock, typename _Dur>
+      inline constexpr bool __is_time_point_v<time_point<_Clock, _Dur>> = true;
+#endif
+
     /// @endcond
 
     /** Convert a `duration` to type `ToDur`.
@@ -261,13 +272,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       constexpr __enable_if_is_duration<_ToDur>
       duration_cast(const duration<_Rep, _Period>& __d)
       {
-	typedef typename _ToDur::period				__to_period;
-	typedef typename _ToDur::rep				__to_rep;
-	typedef ratio_divide<_Period, __to_period> 		__cf;
-	typedef typename common_type<__to_rep, _Rep, intmax_t>::type __cr;
-	typedef  __duration_cast_impl<_ToDur, __cf, __cr,
-				      __cf::num == 1, __cf::den == 1> __dc;
-	return __dc::__cast(__d);
+#if __cpp_inline_variables && __cpp_if_constexpr
+	if constexpr (is_same_v<_ToDur, duration<_Rep, _Period>>)
+	  return __d;
+	else
+#endif
+	{
+	  using __to_period = typename _ToDur::period;
+	  using __to_rep = typename _ToDur::rep;
+	  using __cf = ratio_divide<_Period, __to_period>;
+	  using __cr = typename common_type<__to_rep, _Rep, intmax_t>::type;
+	  using __dc = __duration_cast_impl<_ToDur, __cf, __cr,
+					    __cf::num == 1, __cf::den == 1>;
+	  return __dc::__cast(__d);
+	}
       }
 
     /** Trait indicating whether to treat a type as a floating-point type.
@@ -290,6 +308,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     template <typename _Rep>
       inline constexpr bool treat_as_floating_point_v =
 	treat_as_floating_point<_Rep>::value;
+
+    template<>
+      inline constexpr bool treat_as_floating_point_v<int> = false;
+    template<>
+      inline constexpr bool treat_as_floating_point_v<long> = false;
+    template<>
+      inline constexpr bool treat_as_floating_point_v<long long> = false;
+    template<>
+      inline constexpr bool treat_as_floating_point_v<float> = true;
+    template<>
+      inline constexpr bool treat_as_floating_point_v<double> = true;
+    template<>
+      inline constexpr bool treat_as_floating_point_v<long double> = true;
 #endif // C++17
 
 #if __cplusplus > 201703L
@@ -632,8 +663,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	// DR 934.
 	template<typename _Rep2 = rep>
 	  _GLIBCXX17_CONSTEXPR
-	  typename enable_if<!treat_as_floating_point<_Rep2>::value,
-			     duration&>::type
+	  __enable_if_t<!treat_as_floating_point<_Rep2>::value, duration&>
 	  operator%=(const rep& __rhs)
 	  {
 	    __r %= __rhs;
@@ -642,8 +672,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 	template<typename _Rep2 = rep>
 	  _GLIBCXX17_CONSTEXPR
-	  typename enable_if<!treat_as_floating_point<_Rep2>::value,
-			     duration&>::type
+	  __enable_if_t<!treat_as_floating_point<_Rep2>::value, duration&>
 	  operator%=(const duration& __d)
 	  {
 	    __r %= __d.count();
@@ -1019,7 +1048,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
      */
     template<typename _ToDur, typename _Clock, typename _Dur>
       [[nodiscard]] constexpr
-      enable_if_t<__is_duration<_ToDur>::value, time_point<_Clock, _ToDur>>
+      enable_if_t<__is_duration_v<_ToDur>, time_point<_Clock, _ToDur>>
       floor(const time_point<_Clock, _Dur>& __tp)
       {
 	return time_point<_Clock, _ToDur>{
@@ -1040,7 +1069,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
      */
     template<typename _ToDur, typename _Clock, typename _Dur>
       [[nodiscard]] constexpr
-      enable_if_t<__is_duration<_ToDur>::value, time_point<_Clock, _ToDur>>
+      enable_if_t<__is_duration_v<_ToDur>, time_point<_Clock, _ToDur>>
       ceil(const time_point<_Clock, _Dur>& __tp)
       {
 	return time_point<_Clock, _ToDur>{
@@ -1062,10 +1091,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
      */
     template<typename _ToDur, typename _Clock, typename _Dur>
       [[nodiscard]] constexpr
-      enable_if_t<
-	__and_<__is_duration<_ToDur>,
-	       __not_<treat_as_floating_point<typename _ToDur::rep>>>::value,
-	time_point<_Clock, _ToDur>>
+      enable_if_t<__is_duration_v<_ToDur>
+		    && !treat_as_floating_point_v<typename _ToDur::rep>,
+		  time_point<_Clock, _ToDur>>
       round(const time_point<_Clock, _Dur>& __tp)
       {
 	return time_point<_Clock, _ToDur>{
-- 
2.38.1


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-12-22 10:15 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-22 10:15 [committed] libstdc++: Define and use variable templates in <chrono> 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).