136ac495dSmrg // Safe sequence implementation -*- C++ -*- 236ac495dSmrg 3*8feb0f0bSmrg // Copyright (C) 2003-2020 Free Software Foundation, Inc. 436ac495dSmrg // 536ac495dSmrg // This file is part of the GNU ISO C++ Library. This library is free 636ac495dSmrg // software; you can redistribute it and/or modify it under the 736ac495dSmrg // terms of the GNU General Public License as published by the 836ac495dSmrg // Free Software Foundation; either version 3, or (at your option) 936ac495dSmrg // any later version. 1036ac495dSmrg 1136ac495dSmrg // This library is distributed in the hope that it will be useful, 1236ac495dSmrg // but WITHOUT ANY WARRANTY; without even the implied warranty of 1336ac495dSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1436ac495dSmrg // GNU General Public License for more details. 1536ac495dSmrg 1636ac495dSmrg // Under Section 7 of GPL version 3, you are granted additional 1736ac495dSmrg // permissions described in the GCC Runtime Library Exception, version 1836ac495dSmrg // 3.1, as published by the Free Software Foundation. 1936ac495dSmrg 2036ac495dSmrg // You should have received a copy of the GNU General Public License and 2136ac495dSmrg // a copy of the GCC Runtime Library Exception along with this program; 2236ac495dSmrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 2336ac495dSmrg // <http://www.gnu.org/licenses/>. 2436ac495dSmrg 2536ac495dSmrg /** @file debug/safe_sequence.h 2636ac495dSmrg * This file is a GNU debug extension to the Standard C++ Library. 2736ac495dSmrg */ 2836ac495dSmrg 2936ac495dSmrg #ifndef _GLIBCXX_DEBUG_SAFE_SEQUENCE_H 3036ac495dSmrg #define _GLIBCXX_DEBUG_SAFE_SEQUENCE_H 1 3136ac495dSmrg 3236ac495dSmrg #include <debug/assertions.h> 3336ac495dSmrg #include <debug/macros.h> 3436ac495dSmrg #include <debug/functions.h> 3536ac495dSmrg #include <debug/safe_base.h> 3636ac495dSmrg 3736ac495dSmrg namespace __gnu_debug 3836ac495dSmrg { 3936ac495dSmrg /** A simple function object that returns true if the passed-in 4036ac495dSmrg * value is not equal to the stored value. It saves typing over 4136ac495dSmrg * using both bind1st and not_equal. 4236ac495dSmrg */ 4336ac495dSmrg template<typename _Type> 4436ac495dSmrg class _Not_equal_to 4536ac495dSmrg { 4636ac495dSmrg _Type __value; 4736ac495dSmrg 4836ac495dSmrg public: _Not_equal_to(const _Type & __v)4936ac495dSmrg explicit _Not_equal_to(const _Type& __v) : __value(__v) { } 5036ac495dSmrg 5136ac495dSmrg bool operator()5236ac495dSmrg operator()(const _Type& __x) const 5336ac495dSmrg { return __value != __x; } 5436ac495dSmrg }; 5536ac495dSmrg 5636ac495dSmrg /** A simple function object that returns true if the passed-in 5736ac495dSmrg * value is equal to the stored value. */ 5836ac495dSmrg template <typename _Type> 5936ac495dSmrg class _Equal_to 6036ac495dSmrg { 6136ac495dSmrg _Type __value; 6236ac495dSmrg 6336ac495dSmrg public: _Equal_to(const _Type & __v)6436ac495dSmrg explicit _Equal_to(const _Type& __v) : __value(__v) { } 6536ac495dSmrg 6636ac495dSmrg bool operator()6736ac495dSmrg operator()(const _Type& __x) const 6836ac495dSmrg { return __value == __x; } 6936ac495dSmrg }; 7036ac495dSmrg 7136ac495dSmrg /** A function object that returns true when the given random access 7236ac495dSmrg iterator is at least @c n steps away from the given iterator. */ 7336ac495dSmrg template<typename _Iterator> 7436ac495dSmrg class _After_nth_from 7536ac495dSmrg { 7636ac495dSmrg typedef typename std::iterator_traits<_Iterator>::difference_type 7736ac495dSmrg difference_type; 7836ac495dSmrg 7936ac495dSmrg _Iterator _M_base; 8036ac495dSmrg difference_type _M_n; 8136ac495dSmrg 8236ac495dSmrg public: _After_nth_from(const difference_type & __n,const _Iterator & __base)8336ac495dSmrg _After_nth_from(const difference_type& __n, const _Iterator& __base) 8436ac495dSmrg : _M_base(__base), _M_n(__n) { } 8536ac495dSmrg 8636ac495dSmrg bool operator()8736ac495dSmrg operator()(const _Iterator& __x) const 8836ac495dSmrg { return __x - _M_base >= _M_n; } 8936ac495dSmrg }; 9036ac495dSmrg 9136ac495dSmrg /** 9236ac495dSmrg * @brief Base class for constructing a @a safe sequence type that 9336ac495dSmrg * tracks iterators that reference it. 9436ac495dSmrg * 9536ac495dSmrg * The class template %_Safe_sequence simplifies the construction of 9636ac495dSmrg * @a safe sequences that track the iterators that reference the 9736ac495dSmrg * sequence, so that the iterators are notified of changes in the 9836ac495dSmrg * sequence that may affect their operation, e.g., if the container 9936ac495dSmrg * invalidates its iterators or is destructed. This class template 10036ac495dSmrg * may only be used by deriving from it and passing the name of the 10136ac495dSmrg * derived class as its template parameter via the curiously 10236ac495dSmrg * recurring template pattern. The derived class must have @c 10336ac495dSmrg * iterator and @c const_iterator types that are instantiations of 10436ac495dSmrg * class template _Safe_iterator for this sequence. Iterators will 10536ac495dSmrg * then be tracked automatically. 10636ac495dSmrg */ 10736ac495dSmrg template<typename _Sequence> 10836ac495dSmrg class _Safe_sequence : public _Safe_sequence_base 10936ac495dSmrg { 11036ac495dSmrg public: 11136ac495dSmrg /** Invalidates all iterators @c x that reference this sequence, 11236ac495dSmrg are not singular, and for which @c __pred(x) returns @c 11336ac495dSmrg true. @c __pred will be invoked with the normal iterators nested 11436ac495dSmrg in the safe ones. */ 11536ac495dSmrg template<typename _Predicate> 11636ac495dSmrg void 11736ac495dSmrg _M_invalidate_if(_Predicate __pred); 11836ac495dSmrg 11936ac495dSmrg /** Transfers all iterators @c x that reference @c from sequence, 12036ac495dSmrg are not singular, and for which @c __pred(x) returns @c 12136ac495dSmrg true. @c __pred will be invoked with the normal iterators nested 12236ac495dSmrg in the safe ones. */ 12336ac495dSmrg template<typename _Predicate> 12436ac495dSmrg void 12536ac495dSmrg _M_transfer_from_if(_Safe_sequence& __from, _Predicate __pred); 12636ac495dSmrg }; 12736ac495dSmrg 12836ac495dSmrg /// Like _Safe_sequence but with a special _M_invalidate_all implementation 12936ac495dSmrg /// not invalidating past-the-end iterators. Used by node based sequence. 13036ac495dSmrg template<typename _Sequence> 13136ac495dSmrg class _Safe_node_sequence 13236ac495dSmrg : public _Safe_sequence<_Sequence> 13336ac495dSmrg { 13436ac495dSmrg protected: 13536ac495dSmrg void _M_invalidate_all()13636ac495dSmrg _M_invalidate_all() 13736ac495dSmrg { 13836ac495dSmrg typedef typename _Sequence::const_iterator _Const_iterator; 13936ac495dSmrg typedef typename _Const_iterator::iterator_type _Base_const_iterator; 14036ac495dSmrg typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; 14136ac495dSmrg const _Sequence& __seq = *static_cast<_Sequence*>(this); 14236ac495dSmrg this->_M_invalidate_if(_Not_equal(__seq._M_base().end())); 14336ac495dSmrg } 14436ac495dSmrg }; 14536ac495dSmrg 14636ac495dSmrg } // namespace __gnu_debug 14736ac495dSmrg 14836ac495dSmrg #include <debug/safe_sequence.tcc> 14936ac495dSmrg 15036ac495dSmrg #endif 151