diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index eb9936f423b..ab12fae5382 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,15 @@ +2012-04-13 Paolo Carlini + + * include/debug/safe_iterator.h (_BeforeBeginHelper<>:: + _S_Is_Beginnest): Add. + * include/debug/forward_list (_BeforeBeginHelper<>:: + _S_Is_Beginnest): Likewise. + (_Safe_iterator<>::_M_is_beginnest): Add. + * include/debug/safe_iterator.tcc (_Safe_iterator<>::_M_valid_range): + Use the latter. + * testsuite/23_containers/forward_list/debug/splice_after.cc: + Add test. + 2012-04-12 Benjamin Kosnik * include/bits/unordered_map.h (__unordered_map): Remove. diff --git a/libstdc++-v3/include/debug/forward_list b/libstdc++-v3/include/debug/forward_list index e21eb4a703a..f4a7ee96df0 100644 --- a/libstdc++-v3/include/debug/forward_list +++ b/libstdc++-v3/include/debug/forward_list @@ -760,8 +760,12 @@ namespace __gnu_debug typedef typename _It::iterator_type _BaseIt; static bool - _M_Is(_BaseIt __it, const _Sequence* __seq) + _S_Is(_BaseIt __it, const _Sequence* __seq) { return __it == __seq->_M_base().cbefore_begin(); } + + static bool + _S_Is_Beginnest(_BaseIt __it, const _Sequence* __seq) + { return _S_Is(__it, __seq); } }; } diff --git a/libstdc++-v3/include/debug/safe_iterator.h b/libstdc++-v3/include/debug/safe_iterator.h index b02fa7ab8ff..3cab2d7d8a2 100644 --- a/libstdc++-v3/include/debug/safe_iterator.h +++ b/libstdc++-v3/include/debug/safe_iterator.h @@ -50,8 +50,12 @@ namespace __gnu_debug typedef typename _It::iterator_type _BaseIt; static bool - _M_Is(_BaseIt __it, const _Sequence* __seq) + _S_Is(_BaseIt, const _Sequence*) { return false; } + + static bool + _S_Is_Beginnest(_BaseIt __it, const _Sequence* __seq) + { return __it == __seq->_M_base().begin(); } }; /** Iterators that derive from _Safe_iterator_base but that aren't @@ -465,7 +469,15 @@ namespace __gnu_debug /// any? bool _M_is_before_begin() const { - return _BeforeBeginHelper<_Sequence>::_M_Is(base(), _M_get_sequence()); + return _BeforeBeginHelper<_Sequence>::_S_Is(base(), _M_get_sequence()); + } + + /// Is this iterator equal to the sequence's before_begin() iterator if + /// any or begin() otherwise? + bool _M_is_beginnest() const + { + return _BeforeBeginHelper<_Sequence>::_S_Is_Beginnest(base(), + _M_get_sequence()); } }; diff --git a/libstdc++-v3/include/debug/safe_iterator.tcc b/libstdc++-v3/include/debug/safe_iterator.tcc index 777a707e7f3..f01252bf6c2 100644 --- a/libstdc++-v3/include/debug/safe_iterator.tcc +++ b/libstdc++-v3/include/debug/safe_iterator.tcc @@ -1,6 +1,6 @@ // Debugging iterator implementation (out of line) -*- C++ -*- -// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011 +// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011, 2012 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -91,10 +91,11 @@ namespace __gnu_debug /* We can only test for equality, but check if one of the iterators is at an extreme. */ /* Optim for classic [begin, it) or [it, end) ranges, limit checks - * when code is valid. */ - if (_M_is_begin() || __rhs._M_is_end()) + * when code is valid. Note, for the special case of forward_list, + * before_begin replaces the role of begin. */ + if (_M_is_beginnest() || __rhs._M_is_end()) return true; - if (_M_is_end() || __rhs._M_is_begin()) + if (_M_is_end() || __rhs._M_is_beginnest()) return false; // Assume that this is a valid range; we can't check anything else diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/debug/splice_after.cc b/libstdc++-v3/testsuite/23_containers/forward_list/debug/splice_after.cc index 60297551dcd..4cc1cfcf78d 100644 --- a/libstdc++-v3/testsuite/23_containers/forward_list/debug/splice_after.cc +++ b/libstdc++-v3/testsuite/23_containers/forward_list/debug/splice_after.cc @@ -1,6 +1,6 @@ // { dg-options "-std=gnu++0x" } -// Copyright (C) 2010 Free Software Foundation, Inc. +// Copyright (C) 2010, 2012 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 @@ -34,6 +34,10 @@ test01() VERIFY( before == fl1.before_begin() ); VERIFY( end == fl1.end() ); + + // no-op just to check that debug mode does not see any problem with it. + fl1.splice_after(fl1.before_begin(), std::move(fl2), + fl2.before_begin(), fl2.begin()); } int