formatter.h (__check_singular): Add const on iterator reference.

2013-10-25  François Dumont  <fdumont@gcc.gnu.org>

	* include/debug/formatter.h (__check_singular): Add const on
	iterator reference.
	* include/debug/functions.h (__check_singular): Likewise.
	(__check_singular(const _Safe_iterator<_Ite, _Seq>&)): Delete.
	(__check_dereferenceable(const _Ite&)): Add const on iterator
	reference.
	(__check_dereferenceable(const _Safe_local_iterator<>&)): New.
	* include/debug/safe_iterator.h (__check_singular_aux): Review
	comment.
	* testsuite/23_containers/vector/debug/debug_functions.cc: New.
	* testsuite/23_containers/unordered_set/debug/debug_functions.cc:
	New.

From-SVN: r204075
This commit is contained in:
François Dumont 2013-10-25 19:25:06 +00:00
parent f5d368b68d
commit 3ff4317f1c
6 changed files with 199 additions and 14 deletions

View File

@ -1,3 +1,18 @@
2013-10-25 François Dumont <fdumont@gcc.gnu.org>
* include/debug/formatter.h (__check_singular): Add const on
iterator reference.
* include/debug/functions.h (__check_singular): Likewise.
(__check_singular(const _Safe_iterator<_Ite, _Seq>&)): Delete.
(__check_dereferenceable(const _Ite&)): Add const on iterator
reference.
(__check_dereferenceable(const _Safe_local_iterator<>&)): New.
* include/debug/safe_iterator.h (__check_singular_aux): Review
comment.
* testsuite/23_containers/vector/debug/debug_functions.cc: New.
* testsuite/23_containers/unordered_set/debug/debug_functions.cc:
New.
2013-10-23 Chris Jefferson <chris@bubblescope.net>
Paolo Carlini <paolo.carlini@oracle.com>

View File

@ -38,7 +38,7 @@ namespace __gnu_debug
using std::type_info;
template<typename _Iterator>
bool __check_singular(_Iterator&);
bool __check_singular(const _Iterator&);
class _Safe_sequence_base;

View File

@ -45,6 +45,9 @@ namespace __gnu_debug
template<typename _Iterator, typename _Sequence>
class _Safe_iterator;
template<typename _Iterator, typename _Sequence>
class _Safe_local_iterator;
template<typename _Sequence>
struct _Insert_range_from_self_is_safe
{ enum { __value = 0 }; };
@ -57,7 +60,7 @@ namespace __gnu_debug
// a _Safe_iterator.
template<typename _Iterator>
inline bool
__check_singular(_Iterator& __x)
__check_singular(const _Iterator& __x)
{ return __check_singular_aux(&__x); }
/** Non-NULL pointers are nonsingular. */
@ -66,17 +69,11 @@ namespace __gnu_debug
__check_singular(const _Tp* __ptr)
{ return __ptr == 0; }
/** Safe iterators know if they are singular. */
template<typename _Iterator, typename _Sequence>
inline bool
__check_singular(const _Safe_iterator<_Iterator, _Sequence>& __x)
{ return __x._M_singular(); }
/** Assume that some arbitrary iterator is dereferenceable, because we
can't prove that it isn't. */
template<typename _Iterator>
inline bool
__check_dereferenceable(_Iterator&)
__check_dereferenceable(const _Iterator&)
{ return true; }
/** Non-NULL pointers are dereferenceable. */
@ -85,12 +82,19 @@ namespace __gnu_debug
__check_dereferenceable(const _Tp* __ptr)
{ return __ptr; }
/** Safe iterators know if they are singular. */
/** Safe iterators know if they are dereferenceable. */
template<typename _Iterator, typename _Sequence>
inline bool
__check_dereferenceable(const _Safe_iterator<_Iterator, _Sequence>& __x)
{ return __x._M_dereferenceable(); }
/** Safe local iterators know if they are dereferenceable. */
template<typename _Iterator, typename _Sequence>
inline bool
__check_dereferenceable(const _Safe_local_iterator<_Iterator,
_Sequence>& __x)
{ return __x._M_dereferenceable(); }
/** If the distance between two random access iterators is
* nonnegative, assume the range is valid.
*/

View File

@ -56,10 +56,9 @@ namespace __gnu_debug
{ return __it == __seq->_M_base().begin(); }
};
/** Iterators that derive from _Safe_iterator_base but that aren't
* _Safe_iterators can be determined singular or non-singular via
* _Safe_iterator_base.
*/
/** Iterators that derive from _Safe_iterator_base can be determined singular
* or non-singular.
**/
inline bool
__check_singular_aux(const _Safe_iterator_base* __x)
{ return __x->_M_singular(); }

View File

@ -0,0 +1,92 @@
// Copyright (C) 2013 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 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// 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 COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-options "-std=gnu++11" }
// { dg-require-debug-mode "" }
#include <unordered_set>
#include <testsuite_hooks.h>
void test01()
{
bool test __attribute__((unused)) = true;
using namespace __gnu_debug;
std::unordered_set<int> u = { 0, 1, 2 };
VERIFY( __check_dereferenceable(u.begin()) );
auto it = u.begin();
VERIFY( __check_dereferenceable(it) );
VERIFY( __check_dereferenceable(u.cbegin()) );
auto cit = u.begin();
VERIFY( __check_dereferenceable(cit) );
VERIFY( !__check_dereferenceable(u.end()) );
it = u.end();
VERIFY( !__check_dereferenceable(it) );
auto bucket = u.bucket(0);
VERIFY( __check_dereferenceable(u.begin(bucket)) );
auto lit = u.begin(bucket);
VERIFY( __check_dereferenceable(lit) );
VERIFY( !__check_dereferenceable(u.end(bucket)) );
}
void test02()
{
bool test __attribute__((unused)) = true;
using namespace __gnu_debug;
std::unordered_set<int> u = { 0, 1, 2 };
VERIFY( !__check_singular(u.end()) );
auto it = u.end();
VERIFY( !__check_singular(it) );
VERIFY( !__check_singular(u.begin()) );
it = u.begin();
VERIFY( !__check_singular(it) );
u.clear();
VERIFY( it._M_singular() );
VERIFY( __check_singular(it) );
it = u.end();
VERIFY( !it._M_singular() );
VERIFY( !__check_singular(it) );
u = { 0, 1, 2 };
auto bucket = u.bucket(0);
VERIFY( !__check_singular(u.begin(bucket)) );
auto lit = u.begin(bucket);
VERIFY( !__check_singular(lit) );
VERIFY( !__check_singular(u.end(bucket)) );
u.clear();
VERIFY( __check_singular(lit) );
}
int main()
{
test01();
test02();
return 0;
}

View File

@ -0,0 +1,75 @@
// Copyright (C) 2013 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 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// 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 COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-require-debug-mode "" }
#include <vector>
#include <testsuite_hooks.h>
void test01()
{
bool test __attribute__((unused)) = true;
using namespace __gnu_debug;
std::vector<int> v1(3, 1);
VERIFY( __check_dereferenceable(v1.begin()) );
std::vector<int>::iterator it = v1.begin();
VERIFY( __check_dereferenceable(it) );
VERIFY( !__check_dereferenceable(v1.end()) );
it = v1.end();
VERIFY( !__check_dereferenceable(it) );
const volatile int* pi = 0;
VERIFY( !__check_dereferenceable(pi) );
int i;
pi = &i;
VERIFY( __check_dereferenceable(pi) );
}
void test02()
{
bool test __attribute__((unused)) = true;
using namespace __gnu_debug;
std::vector<int> v1(3, 1);
VERIFY( !__check_singular(v1.begin()) );
std::vector<int>::iterator it = v1.begin();
VERIFY( !__check_singular(it) );
VERIFY( !__check_singular(v1.end()) );
it = v1.end();
VERIFY( !__check_singular(it) );
v1.clear();
VERIFY( it._M_singular() );
VERIFY( __check_singular(it) );
it = v1.end();
VERIFY( !it._M_singular() );
VERIFY( !__check_singular(it) );
}
int main()
{
test01();
test02();
return 0;
}