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.
Tested under Linux x86_64.
Ok to commit ?
François
diff --git a/libstdc++-v3/include/debug/safe_unordered_container.h
b/libstdc++-v3/include/debug/safe_unordered_container.h
index 3f8346acb3b..66aa29eb84b 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;
+
+#if __cplusplus > 201402L
+ 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
+
/**
* @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:
+#if __cplusplus > 201402L
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
- 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)