OSDN Git Service

PR libstdc++/52433
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / debug / safe_iterator.h
index 4bcca09..6bb3cd2 100644 (file)
@@ -1,6 +1,6 @@
 // Safe iterator implementation  -*- C++ -*-
 
-// Copyright (C) 2003, 2004, 2005, 2006, 2009, 2010
+// Copyright (C) 2003, 2004, 2005, 2006, 2009, 2010, 2011, 2012
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -47,9 +47,10 @@ namespace __gnu_debug
     struct _BeforeBeginHelper
     {
       typedef typename _Sequence::const_iterator _It;
+      typedef typename _It::iterator_type _BaseIt;
 
       static bool
-      _M_Is(_It __it, const _Sequence* __seq)
+      _M_Is(_BaseIt __it, const _Sequence* __seq)
       { return false; }
     };
 
@@ -61,6 +62,43 @@ namespace __gnu_debug
   __check_singular_aux(const _Safe_iterator_base* __x)
   { return __x->_M_singular(); }
 
+  /** The precision to which we can calculate the distance between
+   *  two iterators.
+   */
+  enum _Distance_precision
+    {
+      __dp_equality, //< Can compare iterator equality, only
+      __dp_sign,     //< Can determine equality and ordering
+      __dp_exact     //< Can determine distance precisely
+    };
+
+  /** Determine the distance between two iterators with some known
+   *   precision.
+  */
+  template<typename _Iterator1, typename _Iterator2>
+    inline std::pair<typename std::iterator_traits<_Iterator1>::difference_type,
+                    _Distance_precision>
+    __get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
+                  std::random_access_iterator_tag)
+    { return std::make_pair(__rhs - __lhs, __dp_exact); }
+
+  template<typename _Iterator1, typename _Iterator2>
+    inline std::pair<typename std::iterator_traits<_Iterator1>::difference_type,
+                    _Distance_precision>
+    __get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
+                  std::forward_iterator_tag)
+    { return std::make_pair(__lhs == __rhs? 0 : 1, __dp_equality); }
+
+  template<typename _Iterator1, typename _Iterator2>
+    inline std::pair<typename std::iterator_traits<_Iterator1>::difference_type,
+                    _Distance_precision>
+    __get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs)
+    {
+      typedef typename std::iterator_traits<_Iterator1>::iterator_category
+         _Category;
+      return __get_distance(__lhs, __rhs, _Category());
+    }
+
   /** \brief Safe iterator wrapper.
    *
    *  The class template %_Safe_iterator is a wrapper around an
@@ -77,16 +115,6 @@ namespace __gnu_debug
     {
       typedef _Safe_iterator _Self;
 
-      /** The precision to which we can calculate the distance between
-       *  two iterators.
-       */
-      enum _Distance_precision
-       {
-         __dp_equality, //< Can compare iterator equality, only
-         __dp_sign,     //< Can determine equality and ordering
-         __dp_exact     //< Can determine distance precisely
-       };
-
       /// The underlying iterator
       _Iterator _M_current;
 
@@ -141,6 +169,24 @@ namespace __gnu_debug
                              ._M_iterator(__x, "other"));
       }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      /**
+       * @brief Move construction.
+       * @post __x is singular and unattached
+       */
+      _Safe_iterator(_Safe_iterator&& __x) : _M_current()
+      {
+       _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
+                             || __x._M_current == _Iterator(),
+                             _M_message(__msg_init_copy_singular)
+                             ._M_iterator(*this, "this")
+                             ._M_iterator(__x, "other"));
+       std::swap(_M_current, __x._M_current);
+       this->_M_attach(__x._M_sequence);
+       __x._M_detach();
+      }
+#endif
+
       /**
        *  @brief Converting constructor from a mutable iterator to a
        *  constant iterator.
@@ -176,10 +222,31 @@ namespace __gnu_debug
                              ._M_iterator(*this, "this")
                              ._M_iterator(__x, "other"));
        _M_current = __x._M_current;
-       this->_M_attach(static_cast<_Sequence*>(__x._M_sequence));
+       this->_M_attach(__x._M_sequence);
        return *this;
       }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      /**
+       * @brief Move assignment.
+       * @post __x is singular and unattached
+       */
+      _Safe_iterator&
+      operator=(_Safe_iterator&& __x)
+      {
+       _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
+                             || __x._M_current == _Iterator(),
+                             _M_message(__msg_copy_singular)
+                             ._M_iterator(*this, "this")
+                             ._M_iterator(__x, "other"));
+       _M_current = __x._M_current;
+       _M_attach(__x._M_sequence);
+       __x._M_detach();
+       __x._M_current = _Iterator();
+       return *this;
+      }
+#endif
+
       /**
        *  @brief Iterator dereference.
        *  @pre iterator is dereferenceable
@@ -331,28 +398,18 @@ namespace __gnu_debug
 
       /** Attach iterator to the given sequence. */
       void
-      _M_attach(const _Sequence* __seq)
+      _M_attach(_Safe_sequence_base* __seq)
       {
-       _Safe_iterator_base::_M_attach(const_cast<_Sequence*>(__seq),
-                                      _M_constant());
+       _Safe_iterator_base::_M_attach(__seq, _M_constant());
       }
 
       /** Likewise, but not thread-safe. */
       void
-      _M_attach_single(const _Sequence* __seq)
+      _M_attach_single(_Safe_sequence_base* __seq)
       {
-       _Safe_iterator_base::_M_attach_single(const_cast<_Sequence*>(__seq),
-                                             _M_constant());
+       _Safe_iterator_base::_M_attach_single(__seq, _M_constant());
       }
 
-      /** Invalidate the iterator, making it singular. */
-      void
-      _M_invalidate();
-
-      /** Likewise, but not thread-safe. */
-      void
-      _M_invalidate_single();
-
       /// Is the iterator dereferenceable?
       bool
       _M_dereferenceable() const
@@ -362,8 +419,12 @@ namespace __gnu_debug
       bool
       _M_before_dereferenceable() const
       {
-       _Self __it = *this;
-       return __it._M_incrementable() && (++__it)._M_dereferenceable();
+       if (this->_M_incrementable())
+       {
+         _Iterator __base = base();
+         return ++__base != _M_get_sequence()->_M_base().end();
+       }
+       return false;
       }
 
       /// Is the iterator incrementable?
@@ -389,47 +450,20 @@ namespace __gnu_debug
       _M_get_sequence() const
       { return static_cast<const _Sequence*>(_M_sequence); }
 
-    /** Determine the distance between two iterators with some known
-     * precision.
-    */
-    template<typename _Iterator1, typename _Iterator2>
-      static std::pair<difference_type, _Distance_precision>
-      _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs)
-      {
-        typedef typename std::iterator_traits<_Iterator1>::iterator_category
-         _Category;
-        return _M_get_distance(__lhs, __rhs, _Category());
-      }
-
-    template<typename _Iterator1, typename _Iterator2>
-      static std::pair<difference_type, _Distance_precision>
-      _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
-                     std::random_access_iterator_tag)
-      {
-        return std::make_pair(__rhs.base() - __lhs.base(), __dp_exact);
-      }
-
-    template<typename _Iterator1, typename _Iterator2>
-      static std::pair<difference_type, _Distance_precision>
-      _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
-                   std::forward_iterator_tag)
-      {
-        return std::make_pair(__lhs.base() == __rhs.base()? 0 : 1,
-                             __dp_equality);
-      }
-
       /// Is this iterator equal to the sequence's begin() iterator?
       bool _M_is_begin() const
-      { return *this == _M_get_sequence()->begin(); }
+      { return base() == _M_get_sequence()->_M_base().begin(); }
 
       /// Is this iterator equal to the sequence's end() iterator?
       bool _M_is_end() const
-      { return *this == _M_get_sequence()->end(); }
+      { return base() == _M_get_sequence()->_M_base().end(); }
 
       /// Is this iterator equal to the sequence's before_begin() iterator if
       /// any?
       bool _M_is_before_begin() const
-      { return _BeforeBeginHelper<_Sequence>::_M_Is(*this, _M_get_sequence()); }
+      {
+       return _BeforeBeginHelper<_Sequence>::_M_Is(base(), _M_get_sequence());
+      }
     };
 
   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
@@ -698,8 +732,6 @@ namespace __gnu_debug
     { return _Siter_base<_Iterator>::_S_base(__it); }
 } // namespace __gnu_debug
 
-#ifndef _GLIBCXX_EXPORT_TEMPLATE
-#  include <debug/safe_iterator.tcc>
-#endif
+#include <debug/safe_iterator.tcc>
 
 #endif