]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - libstdc++-v3/include/debug/safe_sequence.h
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / include / debug / safe_sequence.h
index a1577b4b4ee8eb71cf3b64c6b310728f1c5d4fe4..73a5afdb97f1e95ec1242273f6366ba3f9cbfc08 100644 (file)
@@ -1,12 +1,11 @@
 // Safe sequence implementation  -*- C++ -*-
 
-// Copyright (C) 2003, 2004, 2005
-// Free Software Foundation, Inc.
+// Copyright (C) 2003-2020 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 2, or (at your option)
+// 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,
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 // GNU General Public License for more details.
 
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING.  If not, write to the Free
-// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-// USA.
+// 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.
 
-// As a special exception, you may use this file as part of a free software
-// library without restriction.  Specifically, if other files instantiate
-// templates or use macros or inline functions from this file, or you compile
-// this file and link it with other files to produce an executable, this
-// file does not by itself cause the resulting executable to be covered by
-// the GNU General Public License.  This exception does not however
-// invalidate any other reasons why the executable file might be covered by
-// the GNU General Public License.
+// 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/debug.h>
+#include <debug/assertions.h>
 #include <debug/macros.h>
 #include <debug/functions.h>
 #include <debug/safe_base.h>
 
 namespace __gnu_debug
 {
-  template<typename _Iterator, typename _Sequence>
-    class _Safe_iterator;
-
   /** 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.
@@ -58,6 +53,21 @@ namespace __gnu_debug
       { 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>
@@ -79,18 +89,18 @@ namespace __gnu_debug
     };
 
   /**
-   * @brief Base class for constructing a "safe" sequence type that
+   * @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
-   * "safe" sequences that track the iterators that reference the
+   * @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 @const_iterator types that are instantiations of
+   * iterator and @c const_iterator types that are instantiations of
    * class template _Safe_iterator for this sequence. Iterators will
    * then be tracked automatically.
    */
@@ -99,84 +109,42 @@ namespace __gnu_debug
     {
     public:
       /** Invalidates all iterators @c x that reference this sequence,
-         are not singular, and for which @c pred(x) returns @c
-         true. The user of this routine should be careful not to make
-         copies of the iterators passed to @p pred, as the copies may
-         interfere with the invalidation. */
+         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);
+
+      /** 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_invalidate_if(_Predicate __pred);
-
-      /** Transfers all iterators that reference this memory location
-         to this sequence from whatever sequence they are attached
-         to. */
-      template<typename _Iterator>
-        void
-        _M_transfer_iter(const _Safe_iterator<_Iterator, _Sequence>& __x);
+       void
+       _M_transfer_from_if(_Safe_sequence& __from, _Predicate __pred);
     };
 
+  /// 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>
-    template<typename _Predicate>
+    class _Safe_node_sequence
+    : public _Safe_sequence<_Sequence>
+    {
+    protected:
       void
-      _Safe_sequence<_Sequence>::
-      _M_invalidate_if(_Predicate __pred)
+      _M_invalidate_all()
       {
-        typedef typename _Sequence::iterator iterator;
-        typedef typename _Sequence::const_iterator const_iterator;
-
-        for (_Safe_iterator_base* __iter = _M_iterators; __iter; )
-        {
-          iterator* __victim = static_cast<iterator*>(__iter);
-          __iter = __iter->_M_next;
-          if (!__victim->_M_singular())
-          {
-           if (__pred(__victim->base()))
-             __victim->_M_invalidate();
-          }
-        }
-
-        for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2; )
-        {
-          const_iterator* __victim = static_cast<const_iterator*>(__iter2);
-          __iter2 = __iter2->_M_next;
-          if (!__victim->_M_singular())
-          {
-           if (__pred(__victim->base()))
-             __victim->_M_invalidate();
-          }
-        }
+       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<_Sequence*>(this);
+       this->_M_invalidate_if(_Not_equal(__seq._M_base().end()));
       }
+    };
 
-  template<typename _Sequence>
-    template<typename _Iterator>
-      void
-      _Safe_sequence<_Sequence>::
-      _M_transfer_iter(const _Safe_iterator<_Iterator, _Sequence>& __x)
-      {
-       _Safe_sequence_base* __from = __x._M_sequence;
-       if (!__from)
-         return;
-
-        typedef typename _Sequence::iterator iterator;
-        typedef typename _Sequence::const_iterator const_iterator;
-
-        for (_Safe_iterator_base* __iter = __from->_M_iterators; __iter; )
-        {
-          iterator* __victim = static_cast<iterator*>(__iter);
-          __iter = __iter->_M_next;
-          if (!__victim->_M_singular() && __victim->base() == __x.base())
-           __victim->_M_attach(static_cast<_Sequence*>(this));
-        }
-
-        for (_Safe_iterator_base* __iter2 = __from->_M_const_iterators; 
-            __iter2;)
-        {
-          const_iterator* __victim = static_cast<const_iterator*>(__iter2);
-          __iter2 = __iter2->_M_next;
-          if (!__victim->_M_singular() && __victim->base() == __x.base())
-           __victim->_M_attach(static_cast<_Sequence*>(this));
-        }
-      }
 } // namespace __gnu_debug
 
+#include <debug/safe_sequence.tcc>
+
 #endif