public inbox for libstdc++-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-2337] libstdc++: Optimize array traits
@ 2022-09-01  9:28 Jonathan Wakely
  0 siblings, 0 replies; only message in thread
From: Jonathan Wakely @ 2022-09-01  9:28 UTC (permalink / raw)
  To: gcc-cvs, libstdc++-cvs

https://gcc.gnu.org/g:0e1b1222af5e5346df9431df817f2e7dca01bee6

commit r13-2337-g0e1b1222af5e5346df9431df817f2e7dca01bee6
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Aug 31 15:00:07 2022 +0100

    libstdc++: Optimize array traits
    
    Improve compile times by avoiding unnecessary class template
    instantiations.
    
    __is_array_known_bounds and __is_array_unknown_bounds can be defined
    without instantiating extent, by providing partial specializations for
    the true cases.
    
    std::extent can avoid recursing down through a multidimensional array,
    so it stops after providing the result. Previously extent<T[n][m], 0>
    would instantiate extent<T[n], -1u> and extent<T, -2u> as well.
    
    std::is_array_v can use partial specializations to avoid instantiating
    std::is_array, and similarly for std::rank_v and std::extent_v.
    
    std::is_bounded_array_v and std::is_unbounded_array_v can also use
    partial specializations, and then the class templates can be defined in
    terms of the variable templates. This makes sense for these traits,
    because they are new in C++20 and so the variable templates are always
    available, which isn't true in general for C++11 and C++14 traits.
    
    libstdc++-v3/ChangeLog:
    
            * include/std/type_traits (__is_array_known_bounds): Add partial
            specialization instead of using std::extent.
            (__is_array_unknown_bounds): Likewise.
            (extent): Add partial specializations to stop recursion after
            the result is found.
            (is_array_v): Add partial specializations instead of
            instantiating the class template.
            (rank_v, extent_v): Likewise.
            (is_bounded_array_v, is_unbounded_array_v): Likewise.
            (is_bounded_array, is_unbounded_array): Define in terms of the
            variable templates.

Diff:
---
 libstdc++-v3/include/std/type_traits | 98 ++++++++++++++++++++++++------------
 1 file changed, 67 insertions(+), 31 deletions(-)

diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index c2f5cb9c806..5984442c0aa 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -867,21 +867,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Tp>
     auto declval() noexcept -> decltype(__declval<_Tp>(0));
 
-  template<typename, unsigned = 0>
-    struct extent;
-
   template<typename>
     struct remove_all_extents;
 
   /// @cond undocumented
   template<typename _Tp>
     struct __is_array_known_bounds
-    : public integral_constant<bool, (extent<_Tp>::value > 0)>
+    : public false_type
+    { };
+
+  template<typename _Tp, size_t _Size>
+    struct __is_array_known_bounds<_Tp[_Size]>
+    : public true_type
     { };
 
   template<typename _Tp>
     struct __is_array_unknown_bounds
-    : public __and_<is_array<_Tp>, __not_<extent<_Tp>>>
+    : public false_type
+    { };
+
+  template<typename _Tp>
+    struct __is_array_unknown_bounds<_Tp[]>
+    : public true_type
     { };
 
   // Destructible and constructible type properties.
@@ -1430,23 +1437,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
 
   /// extent
-  template<typename, unsigned _Uint>
+  template<typename, unsigned _Uint = 0>
     struct extent
-    : public integral_constant<std::size_t, 0> { };
+    : public integral_constant<size_t, 0> { };
 
-  template<typename _Tp, unsigned _Uint, std::size_t _Size>
+  template<typename _Tp, size_t _Size>
+    struct extent<_Tp[_Size], 0>
+    : public integral_constant<size_t, _Size> { };
+
+  template<typename _Tp, unsigned _Uint, size_t _Size>
     struct extent<_Tp[_Size], _Uint>
-    : public integral_constant<std::size_t,
-			       _Uint == 0 ? _Size : extent<_Tp,
-							   _Uint - 1>::value>
-    { };
+    : public extent<_Tp, _Uint - 1>::type { };
+
+  template<typename _Tp>
+    struct extent<_Tp[], 0>
+    : public integral_constant<size_t, 0> { };
 
   template<typename _Tp, unsigned _Uint>
     struct extent<_Tp[], _Uint>
-    : public integral_constant<std::size_t,
-			       _Uint == 0 ? 0 : extent<_Tp,
-						       _Uint - 1>::value>
-    { };
+    : public extent<_Tp, _Uint - 1>::type { };
 
 
   // Type relations.
@@ -3133,8 +3142,14 @@ template <typename _Tp>
   inline constexpr bool is_integral_v = is_integral<_Tp>::value;
 template <typename _Tp>
   inline constexpr bool is_floating_point_v = is_floating_point<_Tp>::value;
+
+template <typename _Tp>
+  inline constexpr bool is_array_v = false;
 template <typename _Tp>
-  inline constexpr bool is_array_v = is_array<_Tp>::value;
+  inline constexpr bool is_array_v<_Tp[]> = true;
+template <typename _Tp, size_t _Num>
+  inline constexpr bool is_array_v<_Tp[_Num]> = true;
+
 template <typename _Tp>
   inline constexpr bool is_pointer_v = is_pointer<_Tp>::value;
 template <typename _Tp>
@@ -3276,10 +3291,25 @@ template <typename _Tp>
     has_virtual_destructor<_Tp>::value;
 template <typename _Tp>
   inline constexpr size_t alignment_of_v = alignment_of<_Tp>::value;
+
+template <typename _Tp>
+  inline constexpr size_t rank_v = 0;
+template <typename _Tp, size_t _Size>
+  inline constexpr size_t rank_v<_Tp[_Size]> = 1 + rank_v<_Tp>;
 template <typename _Tp>
-  inline constexpr size_t rank_v = rank<_Tp>::value;
+  inline constexpr size_t rank_v<_Tp[]> = 1 + rank_v<_Tp>;
+
 template <typename _Tp, unsigned _Idx = 0>
-  inline constexpr size_t extent_v = extent<_Tp, _Idx>::value;
+  inline constexpr size_t extent_v = 0;
+template <typename _Tp, size_t _Size>
+  inline constexpr size_t extent_v<_Tp[_Size], 0> = _Size;
+template <typename _Tp, unsigned _Idx, size_t _Size>
+  inline constexpr size_t extent_v<_Tp[_Size], _Idx> = extent_v<_Tp, _Idx - 1>;
+template <typename _Tp>
+  inline constexpr size_t extent_v<_Tp[], 0> = 0;
+template <typename _Tp, unsigned _Idx>
+  inline constexpr size_t extent_v<_Tp[], _Idx> = extent_v<_Tp, _Idx - 1>;
+
 #ifdef _GLIBCXX_HAVE_BUILTIN_IS_SAME
 template <typename _Tp, typename _Up>
   inline constexpr bool is_same_v = __is_same(_Tp, _Up);
@@ -3408,30 +3438,36 @@ template<typename _Ret, typename _Fn, typename... _Args>
 #define __cpp_lib_bounded_array_traits 201902L
 
   /// True for a type that is an array of known bound.
+  /// @ingroup variable_templates
   /// @since C++20
   template<typename _Tp>
-    struct is_bounded_array
-    : public __is_array_known_bounds<_Tp>
-    { };
+    inline constexpr bool is_bounded_array_v = false;
+
+  template<typename _Tp, size_t _Size>
+    inline constexpr bool is_bounded_array_v<_Tp[_Size]> = true;
 
   /// True for a type that is an array of unknown bound.
+  /// @ingroup variable_templates
   /// @since C++20
   template<typename _Tp>
-    struct is_unbounded_array
-    : public __is_array_unknown_bounds<_Tp>
-    { };
+    inline constexpr bool is_unbounded_array_v = false;
 
-  /// @ingroup variable_templates
+  template<typename _Tp>
+    inline constexpr bool is_unbounded_array_v<_Tp[]> = true;
+
+  /// True for a type that is an array of known bound.
   /// @since C++20
   template<typename _Tp>
-    inline constexpr bool is_bounded_array_v
-      = is_bounded_array<_Tp>::value;
+    struct is_bounded_array
+    : public bool_constant<is_bounded_array_v<_Tp>>
+    { };
 
-  /// @ingroup variable_templates
+  /// True for a type that is an array of unknown bound.
   /// @since C++20
   template<typename _Tp>
-    inline constexpr bool is_unbounded_array_v
-      = is_unbounded_array<_Tp>::value;
+    struct is_unbounded_array
+    : public bool_constant<is_unbounded_array_v<_Tp>>
+    { };
 
 #if __has_builtin(__is_layout_compatible)

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

only message in thread, other threads:[~2022-09-01  9:28 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-01  9:28 [gcc r13-2337] libstdc++: Optimize array traits 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).