xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/debug/safe_sequence.h (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
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