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

commit r16-7918-gdae387d2c81eace093f3c9a2e6e3f027a615e23f
Author: François Dumont <[email protected]>
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 <[email protected]>

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)

Reply via email to