OSDN Git Service

PR libstdc++/52433
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / debug / safe_iterator.h
index 733a2c6..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
@@ -62,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
@@ -78,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;
 
@@ -142,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.
@@ -181,6 +226,27 @@ namespace __gnu_debug
        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
@@ -353,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?
@@ -380,30 +450,6 @@ 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 - __lhs, __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 == __rhs? 0 : 1, __dp_equality); }
-
       /// Is this iterator equal to the sequence's begin() iterator?
       bool _M_is_begin() const
       { return base() == _M_get_sequence()->_M_base().begin(); }
@@ -415,7 +461,9 @@ namespace __gnu_debug
       /// Is this iterator equal to the sequence's before_begin() iterator if
       /// any?
       bool _M_is_before_begin() const
-      { return _BeforeBeginHelper<_Sequence>::_M_Is(base(), _M_get_sequence()); }
+      {
+       return _BeforeBeginHelper<_Sequence>::_M_Is(base(), _M_get_sequence());
+      }
     };
 
   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
@@ -684,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