X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=libstdc%2B%2B-v3%2Finclude%2Fdebug%2Fsafe_iterator.h;h=6bb3cd24ed2700ea4b0b12cba37f14fb079d164d;hp=733a2c6a0a7c4b88264b9e052923eb4dc9a1dbb9;hb=41e73ea4e3b0e4c1bab8dc86322f61f7621a1cee;hpb=8e9bca591d9307979fde531663fb4d34da242aae diff --git a/libstdc++-v3/include/debug/safe_iterator.h b/libstdc++-v3/include/debug/safe_iterator.h index 733a2c6a0a7..6bb3cd24ed2 100644 --- a/libstdc++-v3/include/debug/safe_iterator.h +++ b/libstdc++-v3/include/debug/safe_iterator.h @@ -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 + inline std::pair::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 + inline std::pair::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 + inline std::pair::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(_M_sequence); } - /** Determine the distance between two iterators with some known - * precision. - */ - template - static std::pair - _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 - static std::pair - _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs, - std::random_access_iterator_tag) - { return std::make_pair(__rhs - __lhs, __dp_exact); } - - template - static std::pair - _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 @@ -684,8 +732,6 @@ namespace __gnu_debug { return _Siter_base<_Iterator>::_S_base(__it); } } // namespace __gnu_debug -#ifndef _GLIBCXX_EXPORT_TEMPLATE -# include -#endif +#include #endif