public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
* [committed 1/2] libstdc++: Avoid instantiation of _Hash_node before it's needed
@ 2021-10-08 23:59 Jonathan Wakely
  2021-10-09  0:01 ` [committed 2/2] libstdc++: Access std::pair members without tuple-like helpers Jonathan Wakely
  0 siblings, 1 reply; 2+ messages in thread
From: Jonathan Wakely @ 2021-10-08 23:59 UTC (permalink / raw)
  To: libstdc++, gcc-patches

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

This is a step towards restoring support for incomplete types in
unordered containers (PR 53339).

We do not need to instantiate the node type to get its value_type
member, because we know that the value type is the first template
parameter. We can deduce that template argument using a custom trait and
a partial specialization for _Hash_node. If we wanted to support custom
hash node types we could still use typename _Tp::value_type in the
primary template of that trait, but that seems unnecessary.

The other change needed is to defer a static assert at class scope, so
that it is done when the types are complete. We must have a complete
type in the destructor, so we can do it there instead.

libstdc++-v3/ChangeLog:

	* include/bits/hashtable.h: Move static assertion to destructor.
	* include/bits/hashtable_policy.h: Deduce value type from node
	type without instantiating it.

Tested powerpc64le-linux. Committed to trunk.

This is the patch I referred to in:
https://gcc.gnu.org/pipermail/gcc-patches/2021-July/576028.html



[-- Attachment #2: patch.txt --]
[-- Type: text/plain, Size: 4011 bytes --]

commit 64acc43de1e33616e43b239887a260eb4a51fcc7
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Fri Oct 8 13:35:54 2021

    libstdc++: Avoid instantiation of _Hash_node before it's needed
    
    This is a step towards restoring support for incomplete types in
    unordered containers (PR 53339).
    
    We do not need to instantiate the node type to get its value_type
    member, because we know that the value type is the first template
    parameter. We can deduce that template argument using a custom trait and
    a partial specialization for _Hash_node. If we wanted to support custom
    hash node types we could still use typename _Tp::value_type in the
    primary template of that trait, but that seems unnecessary.
    
    The other change needed is to defer a static assert at class scope, so
    that it is done when the types are complete. We must have a complete
    type in the destructor, so we can do it there instead.
    
    libstdc++-v3/ChangeLog:
    
            * include/bits/hashtable.h: Move static assertion to destructor.
            * include/bits/hashtable_policy.h: Deduce value type from node
            type without instantiating it.

diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h
index 79a3096b62b..ff8af2201cd 100644
--- a/libstdc++-v3/include/bits/hashtable.h
+++ b/libstdc++-v3/include/bits/hashtable.h
@@ -329,14 +329,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       struct __hash_code_base_access : __hash_code_base
       { using __hash_code_base::_M_bucket_index; };
 
-      // Getting a bucket index from a node shall not throw because it is used
-      // in methods (erase, swap...) that shall not throw.
-      static_assert(noexcept(declval<const __hash_code_base_access&>()
-			._M_bucket_index(declval<const __node_value_type&>(),
-					 (std::size_t)0)),
-		    "Cache the hash code or qualify your functors involved"
-		    " in hash code and bucket index computation with noexcept");
-
       // To get bucket index we need _RangeHash not to throw.
       static_assert(is_nothrow_default_constructible<_RangeHash>::value,
 		    "Functor used to map hash code to bucket index"
@@ -1556,6 +1548,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	       _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
     ~_Hashtable() noexcept
     {
+      // Getting a bucket index from a node shall not throw because it is used
+      // in methods (erase, swap...) that shall not throw. Need a complete
+      // type to check this, so do it in the destructor not at class scope.
+      static_assert(noexcept(declval<const __hash_code_base_access&>()
+			._M_bucket_index(declval<const __node_value_type&>(),
+					 (std::size_t)0)),
+		    "Cache the hash code or qualify your functors involved"
+		    " in hash code and bucket index computation with noexcept");
+
       clear();
       _M_deallocate_buckets();
     }
diff --git a/libstdc++-v3/include/bits/hashtable_policy.h b/libstdc++-v3/include/bits/hashtable_policy.h
index 2f8502588f5..75488da13f7 100644
--- a/libstdc++-v3/include/bits/hashtable_policy.h
+++ b/libstdc++-v3/include/bits/hashtable_policy.h
@@ -1840,6 +1840,13 @@ namespace __detail
     {
     private:
       using __ebo_node_alloc = _Hashtable_ebo_helper<0, _NodeAlloc>;
+
+      template<typename>
+	struct __get_value_type;
+      template<typename _Val, bool _Cache_hash_code>
+	struct __get_value_type<_Hash_node<_Val, _Cache_hash_code>>
+	{ using type = _Val; };
+
     public:
       using __node_type = typename _NodeAlloc::value_type;
       using __node_alloc_type = _NodeAlloc;
@@ -1847,7 +1854,7 @@ namespace __detail
       using __node_alloc_traits = __gnu_cxx::__alloc_traits<__node_alloc_type>;
 
       using __value_alloc_traits = typename __node_alloc_traits::template
-	rebind_traits<typename __node_type::value_type>;
+	rebind_traits<typename __get_value_type<__node_type>::type>;
 
       using __node_ptr = __node_type*;
       using __node_base = _Hash_node_base;

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

end of thread, other threads:[~2021-10-09  0:01 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-08 23:59 [committed 1/2] libstdc++: Avoid instantiation of _Hash_node before it's needed Jonathan Wakely
2021-10-09  0:01 ` [committed 2/2] libstdc++: Access std::pair members without tuple-like helpers 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).