[gcc r16-7918] libstdc++: [_GLIBCXX_DEBUG] Hide _Safe_unordered_container methods

Francois Dumont fdumont@gcc.gnu.org
Thu Mar 5 18:12:41 GMT 2026


https://gcc.gnu.org/g:dae387d2c81eace093f3c9a2e6e3f027a615e23f

commit r16-7918-gdae387d2c81eace093f3c9a2e6e3f027a615e23f
Author: François Dumont <frs.dumont@gmail.com>
Date:   Thu Mar 5 06:40:23 2026 +0100

    libstdc++: [_GLIBCXX_DEBUG] Hide _Safe_unordered_container methods
    
    In _Safe_unordered_container the _M_invalidate_all and _M_invalidate_all_if
    are made public to be used in nested struct _UContMergeGuard.
    
    Thanks to friend declaration we can avoid those method to be accessible from
    user code.
    
    libstdc++-v3/ChangeLog:
    
            * include/debug/safe_unordered_container.h
            (_Safe_unordered_container::_UContInvalidatePred): Move outside class, at
            namespace scope. Declare friend.
            (_Safe_unordered_container::_UMContInvalidatePred): Likewise.
            (_Safe_unordered_container::_UContMergeGuard): Likewise.
            (_Safe_unordered_container::_M_invalidate_all): Make protected.
            (_Safe_unordered_container::_M_invalidate_all_if): Likewise.
    
    Reviewed-by: Jonathan Wakely <jwakely@redhat.com>

Diff:
---
 .../include/debug/safe_unordered_container.h       | 150 +++++++++++----------
 1 file changed, 81 insertions(+), 69 deletions(-)

diff --git a/libstdc++-v3/include/debug/safe_unordered_container.h b/libstdc++-v3/include/debug/safe_unordered_container.h
index 3f8346acb3bd..ec4af0986b5d 100644
--- a/libstdc++-v3/include/debug/safe_unordered_container.h
+++ b/libstdc++-v3/include/debug/safe_unordered_container.h
@@ -36,6 +36,77 @@
 
 namespace __gnu_debug
 {
+  template<typename _Container>
+    class _Safe_unordered_container;
+
+#ifdef __glibcxx_node_extract // >= C++17 && HOSTED
+  template<typename _ExtractKey, typename _Source>
+    struct _UContInvalidatePred
+    {
+      template<typename _Iterator>
+	bool
+	operator()(_Iterator __it) const
+	{ return _M_source._M_cont().count(_ExtractKey{}(*__it)) == 0; }
+
+      const _Safe_unordered_container<_Source>& _M_source;
+    };
+
+  template<typename _ExtractKey, typename _Source>
+    struct _UMContInvalidatePred
+    {
+      template<typename _Iterator>
+	bool
+	operator()(_Iterator __it) const
+	{
+	  auto __rng =
+	    _M_source._M_cont()._M_base().equal_range(_ExtractKey{}(*__it));
+	  for (auto __rit = __rng.first;
+	       __rit != __rng.second; ++__rit)
+	    {
+	      if (__it == __rit)
+		return false;
+	    }
+
+	  return true;
+	}
+
+      const _Safe_unordered_container<_Source>& _M_source;
+    };
+
+  template<typename _Source, typename _InvalidatePred>
+    struct _UContMergeGuard
+    {
+      _UContMergeGuard(_Safe_unordered_container<_Source>& __src) noexcept
+      : _M_source(__src), _M_size(__src._M_cont().size()), _M_pred { __src }
+      { }
+
+      _UContMergeGuard(const _UContMergeGuard&) = delete;
+
+      ~_UContMergeGuard()
+      {
+	const std::size_t __size = _M_source._M_cont().size();
+	if (__size == _M_size)
+	  return;
+
+	__try
+	  {
+	    if (__size == 0)
+	      _M_source._M_invalidate_all();
+	    else
+	      _M_source._M_invalidate_all_if(_M_pred);
+	  }
+	__catch(...)
+	{
+	  _M_source._M_invalidate_all();
+	}
+      }
+
+      _Safe_unordered_container<_Source>& _M_source;
+      const std::size_t _M_size;
+      _InvalidatePred _M_pred;
+  };
+#endif // >= C++17 && HOSTED
+
   /**
    * @brief Base class for constructing a @a safe unordered container type
    * that tracks iterators that reference it.
@@ -57,86 +128,29 @@ namespace __gnu_debug
   template<typename _Container>
     class _Safe_unordered_container : public _Safe_unordered_container_base
     {
-      _Container&
-      _M_cont() noexcept
-      { return *static_cast<_Container*>(this); }
+      const _Container&
+      _M_cont() const noexcept
+      { return *static_cast<const _Container*>(this); }
 
       const _Safe_unordered_container*
       _M_self() const
       { return this; }
 
-#if __cplusplus > 201402L
     protected:
+#ifdef __glibcxx_node_extract // >= C++17 && HOSTED
       template<typename _ExtractKey, typename _Source>
-	struct _UContInvalidatePred
-	{
-	  template<typename _Iterator>
-	    bool
-	    operator()(_Iterator __it) const
-	    { return _M_source.count(_ExtractKey{}(*__it)) == 0; }
-
-	  const _Source& _M_source;
-	};
+	friend struct ::__gnu_debug::_UContInvalidatePred;
 
       template<typename _ExtractKey, typename _Source>
-	struct _UMContInvalidatePred
-	{
-	  template<typename _Iterator>
-	    bool
-	    operator()(_Iterator __it) const
-	    {
-	      auto __rng =
-		_M_source._M_base().equal_range(_ExtractKey{}(*__it));
-	      for (auto __rit = __rng.first;
-		   __rit != __rng.second; ++__rit)
-		{
-		  if (__it == __rit)
-		    return false;
-		}
-
-	      return true;
-	    }
-
-	  const _Source& _M_source;
-	};
+	friend struct ::__gnu_debug::_UMContInvalidatePred;
 
       template<typename _Source, typename _InvalidatePred>
-	struct _UContMergeGuard
-	{
-	  _UContMergeGuard(_Source& __src) noexcept
-	  : _M_source(__src), _M_size(__src.size()), _M_pred { __src }
-	  { }
-
-	  _UContMergeGuard(const _UContMergeGuard&) = delete;
-
-	  ~_UContMergeGuard()
-	  {
-	    const std::size_t __size = _M_source.size();
-	    if (__size == _M_size)
-	      return;
-
-	    __try
-	      {
-		if (__size == 0)
-		  _M_source._M_invalidate_all();
-		else
-		  _M_source._M_invalidate_all_if(_M_pred);
-	      }
-	    __catch(...)
-	      {
-		_M_source._M_invalidate_all();
-	      }
-	  }
-
-	  _Source& _M_source;
-	  const std::size_t _M_size;
-	  _InvalidatePred _M_pred;
-	};
+	friend struct ::__gnu_debug::_UContMergeGuard;
 
       template<typename _ExtractKey, typename _Source>
 	static _UContMergeGuard<_Source,
 				_UContInvalidatePred<_ExtractKey, _Source>>
-	_S_uc_guard(_ExtractKey, _Source& __src)
+	_S_uc_guard(_ExtractKey, _Safe_unordered_container<_Source>& __src)
 	{
 	  typedef _UContInvalidatePred<_ExtractKey, _Source> _InvalidatePred;
 	  return _UContMergeGuard<_Source, _InvalidatePred>(__src);
@@ -145,14 +159,13 @@ namespace __gnu_debug
       template<typename _ExtractKey, typename _Source>
 	static _UContMergeGuard<_Source,
 				_UMContInvalidatePred<_ExtractKey, _Source>>
-	_S_umc_guard(_ExtractKey, _Source& __src)
+	_S_umc_guard(_ExtractKey, _Safe_unordered_container<_Source>& __src)
 	{
 	  typedef _UMContInvalidatePred<_ExtractKey, _Source> _InvalidatePred;
 	  return _UContMergeGuard<_Source, _InvalidatePred>(__src);
 	}
-#endif // C++17
+#endif // >= C++17 && HOSTED
 
-    public:
       void
       _M_invalidate_all()
       {
@@ -179,7 +192,6 @@ namespace __gnu_debug
 	  _M_invalidate_local_if(__pred, sentry);
 	}
 
-    protected:
       template<typename _VictimIt>
 	void
 	_M_invalidate(_VictimIt __victim)


More information about the Libstdc++-cvs mailing list