mirror of
https://github.com/gcc-mirror/gcc.git
synced 2025-08-01 16:38:48 +00:00

In revision a35dd276cb
the debug sequence
have been made mutable to allow attach iterators to const containers.
This change completes this fix by also declaring debug unordered container
members mutable.
Additionally the debug iterator sequence is now a pointer-to-const and so
_Safe_sequence_base _M_attach and all other methods are const qualified.
Not-const methods exported are preserved for abi backward compatibility.
libstdc++-v3/ChangeLog:
PR c++/116369
* config/abi/pre/gnu-versioned-namespace.ver: Use new const qualified symbols.
* config/abi/pre/gnu.ver: Add new const qualified symbols.
* include/debug/safe_base.h
(_Safe_iterator_base::_M_sequence): Declare as pointer-to-const.
(_Safe_iterator_base::_M_attach, _M_attach_single): New, take pointer-to-const
_Safe_sequence_base.
(_Safe_sequence_base::_M_detach_all, _M_detach_singular, _M_revalidate_singular)
(_M_swap, _M_get_mutex): New, const qualified.
(_Safe_sequence_base::_M_attach, _M_attach_single, _M_detach, _M_detach_single):
const qualify.
* include/debug/safe_container.h (_Safe_container<>::_M_cont): Add const qualifier.
(_Safe_container<>::_M_swap_base): New.
(_Safe_container(_Safe_container&&, const _Alloc&, std::false_type)):
Adapt to use latter.
(_Safe_container<>::operator=(_Safe_container&&)): Likewise.
(_Safe_container<>::_M_swap): Likewise and take parameter as const reference.
* include/debug/safe_unordered_base.h
(_Safe_local_iterator_base::_M_safe_container): New.
(_Safe_local_iterator_base::_Safe_local_iterator_base): Take
_Safe_unordered_container_base as pointer-to-const.
(_Safe_unordered_container_base::_M_attach, _M_attach_single): New, take
container as _Safe_unordered_container_base pointer-to-const.
(_Safe_unordered_container_base::_M_local_iterators, _M_const_local_iterators):
Add mutable.
(_Safe_unordered_container_base::_M_detach_all, _M_swap): New, const qualify.
(_Safe_unordered_container_base::_M_attach_local, _M_attach_local_single)
(_M_detach_local, _M_detach_local_single): Add const qualifier.
* include/debug/safe_unordered_container.h (_Safe_unordered_container::_M_self()): New.
* include/debug/safe_unordered_container.tcc
(_Safe_unordered_container::_M_invalidate_if, _M_invalidated_local_if): Use latter.
* include/debug/safe_iterator.h (_Safe_iterator<>::_M_attach, _M_attach_single):
Take _Safe_sequence_base as pointer-to-const.
(_Safe_iterator<>::_M_get_sequence): Add const_cast and comment about it.
* include/debug/safe_local_iterator.h (_Safe_local_iterator<>): Replace usages
of _M_sequence member by _M_safe_container().
(_Safe_local_iterator<>::_M_attach, _M_attach_single): Take
_Safe_unordered_container_base as pointer-to-const.
(_Safe_local_iterator<>::_M_get_sequence): Rename into...
(_Safe_local_iterator<>::_M_get_ucontainer): ...this. Add necessary const_cast and
comment to explain it.
(_Safe_local_iterator<>::_M_is_begin, _M_is_end): Adapt.
* include/debug/safe_local_iterator.tcc: Adapt.
* include/debug/safe_sequence.h
(_Safe_sequence<>::_M_invalidate_if, _M_transfer_from_if): Add const qualifier.
* include/debug/safe_sequence.tcc: Adapt.
* include/debug/deque (std::__debug::deque::erase): Adapt to use new const
qualified methods.
* include/debug/formatter.h: Adapt.
* include/debug/forward_list (_Safe_forward_list::_M_this): Add const
qualification and return pointer for consistency with 'this' keyword.
(_Safe_forward_list::_M_swap_aux): Rename into...
(_Safe_forward_list::_S_swap_aux): ...this and take sequence as const reference.
(forward_list<>::resize): Adapt to use const methods.
* include/debug/list (list<>::resize): Likewise.
* src/c++11/debug.cc: Adapt to const qualification.
* testsuite/util/testsuite_containers.h
(forward_members_unordered::forward_members_unordered): Add check on local_iterator
conversion to const_local_iterator.
(forward_members::forward_members): Add check on iterator conversion to
const_iterator.
* testsuite/23_containers/unordered_map/const_container.cc: New test case.
* testsuite/23_containers/unordered_multimap/const_container.cc: New test case.
* testsuite/23_containers/unordered_multiset/const_container.cc: New test case.
* testsuite/23_containers/unordered_set/const_container.cc: New test case.
* testsuite/23_containers/vector/debug/mutex_association.cc: Adapt.
152 lines
5.0 KiB
C++
152 lines
5.0 KiB
C++
// Safe sequence implementation -*- C++ -*-
|
|
|
|
// Copyright (C) 2003-2025 Free Software Foundation, Inc.
|
|
//
|
|
// This file is part of the GNU ISO C++ Library. This library is free
|
|
// software; you can redistribute it and/or modify it under the
|
|
// terms of the GNU General Public License as published by the
|
|
// Free Software Foundation; either version 3, or (at your option)
|
|
// any later version.
|
|
|
|
// This library is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
|
|
// Under Section 7 of GPL version 3, you are granted additional
|
|
// permissions described in the GCC Runtime Library Exception, version
|
|
// 3.1, as published by the Free Software Foundation.
|
|
|
|
// You should have received a copy of the GNU General Public License and
|
|
// a copy of the GCC Runtime Library Exception along with this program;
|
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
// <http://www.gnu.org/licenses/>.
|
|
|
|
/** @file debug/safe_sequence.h
|
|
* This file is a GNU debug extension to the Standard C++ Library.
|
|
*/
|
|
|
|
#ifndef _GLIBCXX_DEBUG_SAFE_SEQUENCE_H
|
|
#define _GLIBCXX_DEBUG_SAFE_SEQUENCE_H 1
|
|
|
|
#include <debug/assertions.h>
|
|
#include <debug/macros.h>
|
|
#include <debug/functions.h>
|
|
#include <debug/safe_base.h>
|
|
|
|
namespace __gnu_debug
|
|
{
|
|
/** A simple function object that returns true if the passed-in
|
|
* value is not equal to the stored value. It saves typing over
|
|
* using both bind1st and not_equal.
|
|
*/
|
|
template<typename _Type>
|
|
class _Not_equal_to
|
|
{
|
|
_Type __value;
|
|
|
|
public:
|
|
explicit _Not_equal_to(const _Type& __v) : __value(__v) { }
|
|
|
|
bool
|
|
operator()(const _Type& __x) const
|
|
{ return __value != __x; }
|
|
};
|
|
|
|
/** A simple function object that returns true if the passed-in
|
|
* value is equal to the stored value. */
|
|
template <typename _Type>
|
|
class _Equal_to
|
|
{
|
|
_Type __value;
|
|
|
|
public:
|
|
explicit _Equal_to(const _Type& __v) : __value(__v) { }
|
|
|
|
bool
|
|
operator()(const _Type& __x) const
|
|
{ return __value == __x; }
|
|
};
|
|
|
|
/** A function object that returns true when the given random access
|
|
iterator is at least @c n steps away from the given iterator. */
|
|
template<typename _Iterator>
|
|
class _After_nth_from
|
|
{
|
|
typedef typename std::iterator_traits<_Iterator>::difference_type
|
|
difference_type;
|
|
|
|
_Iterator _M_base;
|
|
difference_type _M_n;
|
|
|
|
public:
|
|
_After_nth_from(const difference_type& __n, const _Iterator& __base)
|
|
: _M_base(__base), _M_n(__n) { }
|
|
|
|
bool
|
|
operator()(const _Iterator& __x) const
|
|
{ return __x - _M_base >= _M_n; }
|
|
};
|
|
|
|
/**
|
|
* @brief Base class for constructing a @a safe sequence type that
|
|
* tracks iterators that reference it.
|
|
*
|
|
* The class template %_Safe_sequence simplifies the construction of
|
|
* @a safe sequences that track the iterators that reference the
|
|
* sequence, so that the iterators are notified of changes in the
|
|
* sequence that may affect their operation, e.g., if the container
|
|
* invalidates its iterators or is destructed. This class template
|
|
* may only be used by deriving from it and passing the name of the
|
|
* derived class as its template parameter via the curiously
|
|
* recurring template pattern. The derived class must have @c
|
|
* iterator and @c const_iterator types that are instantiations of
|
|
* class template _Safe_iterator for this sequence. Iterators will
|
|
* then be tracked automatically.
|
|
*/
|
|
template<typename _Sequence>
|
|
class _Safe_sequence : public _Safe_sequence_base
|
|
{
|
|
public:
|
|
/** Invalidates all iterators @c x that reference this sequence,
|
|
are not singular, and for which @c __pred(x) returns @c
|
|
true. @c __pred will be invoked with the normal iterators nested
|
|
in the safe ones. */
|
|
template<typename _Predicate>
|
|
void
|
|
_M_invalidate_if(_Predicate __pred) const;
|
|
|
|
/** Transfers all iterators @c x that reference @c from sequence,
|
|
are not singular, and for which @c __pred(x) returns @c
|
|
true. @c __pred will be invoked with the normal iterators nested
|
|
in the safe ones. */
|
|
template<typename _Predicate>
|
|
void
|
|
_M_transfer_from_if(const _Safe_sequence& __from,
|
|
_Predicate __pred) const;
|
|
};
|
|
|
|
/// Like _Safe_sequence but with a special _M_invalidate_all implementation
|
|
/// not invalidating past-the-end iterators. Used by node based sequence.
|
|
template<typename _Sequence>
|
|
class _Safe_node_sequence
|
|
: public _Safe_sequence<_Sequence>
|
|
{
|
|
protected:
|
|
void
|
|
_M_invalidate_all() const
|
|
{
|
|
typedef typename _Sequence::const_iterator _Const_iterator;
|
|
typedef typename _Const_iterator::iterator_type _Base_const_iterator;
|
|
typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
|
|
const _Sequence& __seq = *static_cast<const _Sequence*>(this);
|
|
this->_M_invalidate_if(_Not_equal(__seq._M_base().end()));
|
|
}
|
|
};
|
|
|
|
} // namespace __gnu_debug
|
|
|
|
#include <debug/safe_sequence.tcc>
|
|
|
|
#endif
|