14fee23f9Smrg // Safe sequence implementation -*- C++ -*- 24fee23f9Smrg 3*b1e83836Smrg // Copyright (C) 2003-2022 Free Software Foundation, Inc. 44fee23f9Smrg // 54fee23f9Smrg // This file is part of the GNU ISO C++ Library. This library is free 64fee23f9Smrg // software; you can redistribute it and/or modify it under the 74fee23f9Smrg // terms of the GNU General Public License as published by the 84fee23f9Smrg // Free Software Foundation; either version 3, or (at your option) 94fee23f9Smrg // any later version. 104fee23f9Smrg 114fee23f9Smrg // This library is distributed in the hope that it will be useful, 124fee23f9Smrg // but WITHOUT ANY WARRANTY; without even the implied warranty of 134fee23f9Smrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 144fee23f9Smrg // GNU General Public License for more details. 154fee23f9Smrg 164fee23f9Smrg // Under Section 7 of GPL version 3, you are granted additional 174fee23f9Smrg // permissions described in the GCC Runtime Library Exception, version 184fee23f9Smrg // 3.1, as published by the Free Software Foundation. 194fee23f9Smrg 204fee23f9Smrg // You should have received a copy of the GNU General Public License and 214fee23f9Smrg // a copy of the GCC Runtime Library Exception along with this program; 224fee23f9Smrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 234fee23f9Smrg // <http://www.gnu.org/licenses/>. 244fee23f9Smrg 254fee23f9Smrg /** @file debug/safe_sequence.h 264fee23f9Smrg * This file is a GNU debug extension to the Standard C++ Library. 274fee23f9Smrg */ 284fee23f9Smrg 294fee23f9Smrg #ifndef _GLIBCXX_DEBUG_SAFE_SEQUENCE_H 304fee23f9Smrg #define _GLIBCXX_DEBUG_SAFE_SEQUENCE_H 1 314fee23f9Smrg 32f9a78e0eSmrg #include <debug/assertions.h> 334fee23f9Smrg #include <debug/macros.h> 344fee23f9Smrg #include <debug/functions.h> 354fee23f9Smrg #include <debug/safe_base.h> 364fee23f9Smrg 374fee23f9Smrg namespace __gnu_debug 384fee23f9Smrg { 394fee23f9Smrg /** A simple function object that returns true if the passed-in 404fee23f9Smrg * value is not equal to the stored value. It saves typing over 414fee23f9Smrg * using both bind1st and not_equal. 424fee23f9Smrg */ 434fee23f9Smrg template<typename _Type> 444fee23f9Smrg class _Not_equal_to 454fee23f9Smrg { 464fee23f9Smrg _Type __value; 474fee23f9Smrg 484fee23f9Smrg public: _Not_equal_to(const _Type & __v)494fee23f9Smrg explicit _Not_equal_to(const _Type& __v) : __value(__v) { } 504fee23f9Smrg 514fee23f9Smrg bool operator()524fee23f9Smrg operator()(const _Type& __x) const 534fee23f9Smrg { return __value != __x; } 544fee23f9Smrg }; 554fee23f9Smrg 5648fb7bfaSmrg /** A simple function object that returns true if the passed-in 5748fb7bfaSmrg * value is equal to the stored value. */ 5848fb7bfaSmrg template <typename _Type> 5948fb7bfaSmrg class _Equal_to 6048fb7bfaSmrg { 6148fb7bfaSmrg _Type __value; 6248fb7bfaSmrg 6348fb7bfaSmrg public: _Equal_to(const _Type & __v)6448fb7bfaSmrg explicit _Equal_to(const _Type& __v) : __value(__v) { } 6548fb7bfaSmrg 6648fb7bfaSmrg bool operator()6748fb7bfaSmrg operator()(const _Type& __x) const 6848fb7bfaSmrg { return __value == __x; } 6948fb7bfaSmrg }; 7048fb7bfaSmrg 714fee23f9Smrg /** A function object that returns true when the given random access 724fee23f9Smrg iterator is at least @c n steps away from the given iterator. */ 734fee23f9Smrg template<typename _Iterator> 744fee23f9Smrg class _After_nth_from 754fee23f9Smrg { 764fee23f9Smrg typedef typename std::iterator_traits<_Iterator>::difference_type 774fee23f9Smrg difference_type; 784fee23f9Smrg 794fee23f9Smrg _Iterator _M_base; 804fee23f9Smrg difference_type _M_n; 814fee23f9Smrg 824fee23f9Smrg public: _After_nth_from(const difference_type & __n,const _Iterator & __base)834fee23f9Smrg _After_nth_from(const difference_type& __n, const _Iterator& __base) 844fee23f9Smrg : _M_base(__base), _M_n(__n) { } 854fee23f9Smrg 864fee23f9Smrg bool operator()874fee23f9Smrg operator()(const _Iterator& __x) const 884fee23f9Smrg { return __x - _M_base >= _M_n; } 894fee23f9Smrg }; 904fee23f9Smrg 914fee23f9Smrg /** 924fee23f9Smrg * @brief Base class for constructing a @a safe sequence type that 934fee23f9Smrg * tracks iterators that reference it. 944fee23f9Smrg * 954fee23f9Smrg * The class template %_Safe_sequence simplifies the construction of 964fee23f9Smrg * @a safe sequences that track the iterators that reference the 974fee23f9Smrg * sequence, so that the iterators are notified of changes in the 984fee23f9Smrg * sequence that may affect their operation, e.g., if the container 994fee23f9Smrg * invalidates its iterators or is destructed. This class template 1004fee23f9Smrg * may only be used by deriving from it and passing the name of the 1014fee23f9Smrg * derived class as its template parameter via the curiously 1024fee23f9Smrg * recurring template pattern. The derived class must have @c 10348fb7bfaSmrg * iterator and @c const_iterator types that are instantiations of 1044fee23f9Smrg * class template _Safe_iterator for this sequence. Iterators will 1054fee23f9Smrg * then be tracked automatically. 1064fee23f9Smrg */ 1074fee23f9Smrg template<typename _Sequence> 1084fee23f9Smrg class _Safe_sequence : public _Safe_sequence_base 1094fee23f9Smrg { 1104fee23f9Smrg public: 1114fee23f9Smrg /** Invalidates all iterators @c x that reference this sequence, 11248fb7bfaSmrg are not singular, and for which @c __pred(x) returns @c 11348fb7bfaSmrg true. @c __pred will be invoked with the normal iterators nested 11448fb7bfaSmrg in the safe ones. */ 1154fee23f9Smrg template<typename _Predicate> 1164fee23f9Smrg void 1174fee23f9Smrg _M_invalidate_if(_Predicate __pred); 1184fee23f9Smrg 11948fb7bfaSmrg /** Transfers all iterators @c x that reference @c from sequence, 12048fb7bfaSmrg are not singular, and for which @c __pred(x) returns @c 12148fb7bfaSmrg true. @c __pred will be invoked with the normal iterators nested 12248fb7bfaSmrg in the safe ones. */ 1234fee23f9Smrg template<typename _Predicate> 1244fee23f9Smrg void 12548fb7bfaSmrg _M_transfer_from_if(_Safe_sequence& __from, _Predicate __pred); 12648fb7bfaSmrg }; 1274d5abbe8Smrg 1284d5abbe8Smrg /// Like _Safe_sequence but with a special _M_invalidate_all implementation 1294d5abbe8Smrg /// not invalidating past-the-end iterators. Used by node based sequence. 1304d5abbe8Smrg template<typename _Sequence> 1314d5abbe8Smrg class _Safe_node_sequence 1324d5abbe8Smrg : public _Safe_sequence<_Sequence> 1334d5abbe8Smrg { 1344d5abbe8Smrg protected: 1354d5abbe8Smrg void _M_invalidate_all()1364d5abbe8Smrg _M_invalidate_all() 1374d5abbe8Smrg { 1384d5abbe8Smrg typedef typename _Sequence::const_iterator _Const_iterator; 1394d5abbe8Smrg typedef typename _Const_iterator::iterator_type _Base_const_iterator; 1404d5abbe8Smrg typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; 1414d5abbe8Smrg const _Sequence& __seq = *static_cast<_Sequence*>(this); 1424d5abbe8Smrg this->_M_invalidate_if(_Not_equal(__seq._M_base().end())); 1434d5abbe8Smrg } 1444d5abbe8Smrg }; 1454d5abbe8Smrg 1464fee23f9Smrg } // namespace __gnu_debug 1474fee23f9Smrg 14848fb7bfaSmrg #include <debug/safe_sequence.tcc> 14948fb7bfaSmrg 1504fee23f9Smrg #endif 151