Commit b101633f by François Dumont

2018-09-02 François Dumont <fdumont@gcc.gnu.org>

	* include/debug/safe_iterator.h
	(_Safe_iterator<_It, _Seq, _Cat>::_Self): New.
	(_Safe_iterator<_It, _Seq, std::random_access_iterator_tag>::_Self):
	New.
	(_Safe_iterator<_It, _Seq, std::random_access_iterator_tag>
	::_OtherSelf): New.
	(_GLIBCXX_DEBUG_VERIFY_OPERANDS, _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS)
	(_GLIBCXX_DEBUG_VERIFY_REL_OPERANDS)
	(_GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS): Define macros.
	(_Safe_iterator<_It, _Seq, std::random_access_iterator_tag>
	::operator+(difference_type)): Use latters, inline as friend.
	(_Safe_iterator<_It, _Seq, std::random_access_iterator_tag>
	::operator-(difference_type)): Likewise.
	(operator==(const _Safe_iterator<>&, const _Safe_iterator<>&)):
	Likewise.
	(operator!=(const _Safe_iterator<>&, const _Safe_iterator<>&)):
	Likewise.
	(operator<(const _Safe_iterator<>&, const _Safe_iterator<>&)): Likewise.
	(operator<=(const _Safe_iterator<>&, const _Safe_iterator<>&)):
	Likewise.
	(operator>(const _Safe_iterator<>&, const _Safe_iterator<>&)): Likewise.
	(operator>=(const _Safe_iterator<>&, const _Safe_iterator<>&)):
	Likewise.
	(operator-(const _Safe_iterator<>&, const _Safe_iterator<>&)): Likewise.
	(operator+(difference_type, const _Safe_iterator<>&)): Likewise.
	(operator-(const _Safe_iterator<>&, difference_type)): Likewise.
	* include/debug/safe_iterator.tcc
	(_Safe_iterator<>::_M_can_advance(difference_type)): Take parameter by
	copy.
	* include/debug/safe_local_iterator.h
	(_Safe_local_iterator<_It, _Seq>::_Self): New.
	(_Safe_local_iterator<_It, _Seq>::_OtherSelf): New.
	(_GLIBCXX_DEBUG_VERIFY_OPERANDS): Define macro.
	(operator==(const _Safe_local_iterator<>&,
	const _Safe_local_iterator<>&)): Use latter, inline as friend.
	(operator!=(const _Safe_local_iterator<>&,
	const _Safe_local_iterator<>&)): Likewise.
	* testsuite/util/testsuite_containers.h: Include utility.
	(struct forward_members_unordered<_Tp, bool>): Remove 2nd template
	parameter.
	(forward_members_unordered<>::forward_members_unordered(value_type&)):
	Add using namespace std::rel_ops.
	Add iterator_concept_checks on local_iterator and const_local_iterator.
	Add asserts on comparison between const_local_iterator and
	local_iterator.
	(struct forward_members_unordered<_Tp, false>): Remove partial
	specialization.
	* testsuite/23_containers/forward_list/types/1.cc: New.
	* testsuite/23_containers/list/types/1.cc: New.

From-SVN: r264039
parent 2b35b704
2018-09-02 François Dumont <fdumont@gcc.gnu.org>
* include/debug/safe_iterator.h
(_Safe_iterator<_It, _Seq, _Cat>::_Self): New.
(_Safe_iterator<_It, _Seq, std::random_access_iterator_tag>::_Self):
New.
(_Safe_iterator<_It, _Seq, std::random_access_iterator_tag>
::_OtherSelf): New.
(_GLIBCXX_DEBUG_VERIFY_OPERANDS, _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS)
(_GLIBCXX_DEBUG_VERIFY_REL_OPERANDS)
(_GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS): Define macros.
(_Safe_iterator<_It, _Seq, std::random_access_iterator_tag>
::operator+(difference_type)): Use latters, inline as friend.
(_Safe_iterator<_It, _Seq, std::random_access_iterator_tag>
::operator-(difference_type)): Likewise.
(operator==(const _Safe_iterator<>&, const _Safe_iterator<>&)):
Likewise.
(operator!=(const _Safe_iterator<>&, const _Safe_iterator<>&)):
Likewise.
(operator<(const _Safe_iterator<>&, const _Safe_iterator<>&)): Likewise.
(operator<=(const _Safe_iterator<>&, const _Safe_iterator<>&)):
Likewise.
(operator>(const _Safe_iterator<>&, const _Safe_iterator<>&)): Likewise.
(operator>=(const _Safe_iterator<>&, const _Safe_iterator<>&)):
Likewise.
(operator-(const _Safe_iterator<>&, const _Safe_iterator<>&)): Likewise.
(operator+(difference_type, const _Safe_iterator<>&)): Likewise.
(operator-(const _Safe_iterator<>&, difference_type)): Likewise.
* include/debug/safe_iterator.tcc
(_Safe_iterator<>::_M_can_advance(difference_type)): Take parameter by
copy.
* include/debug/safe_local_iterator.h
(_Safe_local_iterator<_It, _Seq>::_Self): New.
(_Safe_local_iterator<_It, _Seq>::_OtherSelf): New.
(_GLIBCXX_DEBUG_VERIFY_OPERANDS): Define macro.
(operator==(const _Safe_local_iterator<>&,
const _Safe_local_iterator<>&)): Use latter, inline as friend.
(operator!=(const _Safe_local_iterator<>&,
const _Safe_local_iterator<>&)): Likewise.
* testsuite/util/testsuite_containers.h: Include utility.
(struct forward_members_unordered<_Tp, bool>): Remove 2nd template
parameter.
(forward_members_unordered<>::forward_members_unordered(value_type&)):
Add using namespace std::rel_ops.
Add iterator_concept_checks on local_iterator and const_local_iterator.
Add asserts on comparison between const_local_iterator and
local_iterator.
(struct forward_members_unordered<_Tp, false>): Remove partial
specialization.
* testsuite/23_containers/forward_list/types/1.cc: New.
* testsuite/23_containers/list/types/1.cc: New.
2018-09-01 Gerald Pfeifer <gerald@pfeifer.com>
* doc/xml/manual/profile_mode.xml: Update three ieeexplore.ieee.org
......
......@@ -82,7 +82,7 @@ namespace __gnu_debug
template<typename _Iterator, typename _Sequence, typename _Category>
bool
_Safe_iterator<_Iterator, _Sequence, _Category>::
_M_can_advance(const difference_type& __n) const
_M_can_advance(difference_type __n) const
{
if (this->_M_singular())
return false;
......
......@@ -31,6 +31,20 @@
#include <debug/safe_unordered_base.h>
#define _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs) \
_GLIBCXX_DEBUG_VERIFY(!_Lhs._M_singular() && !_Rhs._M_singular(), \
_M_message(__msg_iter_compare_bad) \
._M_iterator(_Lhs, "lhs") \
._M_iterator(_Rhs, "rhs")); \
_GLIBCXX_DEBUG_VERIFY(_Lhs._M_can_compare(_Rhs), \
_M_message(__msg_compare_different) \
._M_iterator(_Lhs, "lhs") \
._M_iterator(_Rhs, "rhs")); \
_GLIBCXX_DEBUG_VERIFY(_Lhs._M_in_same_bucket(_Rhs), \
_M_message(__msg_local_iter_compare_bad) \
._M_iterator(_Lhs, "lhs") \
._M_iterator(_Rhs, "rhs"))
namespace __gnu_debug
{
/** \brief Safe iterator wrapper.
......@@ -65,6 +79,9 @@ namespace __gnu_debug
typename _Sequence::_Base::const_local_iterator>::__type
_OtherIterator;
typedef _Safe_local_iterator _Self;
typedef _Safe_local_iterator<_OtherIterator, _Sequence> _OtherSelf;
struct _Attach_single
{ };
......@@ -354,87 +371,35 @@ namespace __gnu_debug
_M_in_same_bucket(const _Safe_local_iterator<_Other,
_Sequence>& __other) const
{ return bucket() == __other.bucket(); }
};
template<typename _IteratorL, typename _IteratorR, typename _Sequence>
inline bool
operator==(const _Safe_local_iterator<_IteratorL, _Sequence>& __lhs,
const _Safe_local_iterator<_IteratorR, _Sequence>& __rhs)
friend inline bool
operator==(const _Self& __lhs, const _OtherSelf& __rhs) noexcept
{
_GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
_M_message(__msg_iter_compare_bad)
._M_iterator(__lhs, "lhs")
._M_iterator(__rhs, "rhs"));
_GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
_M_message(__msg_compare_different)
._M_iterator(__lhs, "lhs")
._M_iterator(__rhs, "rhs"));
_GLIBCXX_DEBUG_VERIFY(__lhs._M_in_same_bucket(__rhs),
_M_message(__msg_local_iter_compare_bad)
._M_iterator(__lhs, "lhs")
._M_iterator(__rhs, "rhs"));
_GLIBCXX_DEBUG_VERIFY_OPERANDS(__lhs, __rhs);
return __lhs.base() == __rhs.base();
}
template<typename _Iterator, typename _Sequence>
inline bool
operator==(const _Safe_local_iterator<_Iterator, _Sequence>& __lhs,
const _Safe_local_iterator<_Iterator, _Sequence>& __rhs)
friend inline bool
operator==(const _Self& __lhs, const _Self& __rhs) noexcept
{
_GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
_M_message(__msg_iter_compare_bad)
._M_iterator(__lhs, "lhs")
._M_iterator(__rhs, "rhs"));
_GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
_M_message(__msg_compare_different)
._M_iterator(__lhs, "lhs")
._M_iterator(__rhs, "rhs"));
_GLIBCXX_DEBUG_VERIFY(__lhs._M_in_same_bucket(__rhs),
_M_message(__msg_local_iter_compare_bad)
._M_iterator(__lhs, "lhs")
._M_iterator(__rhs, "rhs"));
_GLIBCXX_DEBUG_VERIFY_OPERANDS(__lhs, __rhs);
return __lhs.base() == __rhs.base();
}
template<typename _IteratorL, typename _IteratorR, typename _Sequence>
inline bool
operator!=(const _Safe_local_iterator<_IteratorL, _Sequence>& __lhs,
const _Safe_local_iterator<_IteratorR, _Sequence>& __rhs)
friend inline bool
operator!=(const _Self& __lhs, const _OtherSelf& __rhs) noexcept
{
_GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
_M_message(__msg_iter_compare_bad)
._M_iterator(__lhs, "lhs")
._M_iterator(__rhs, "rhs"));
_GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
_M_message(__msg_compare_different)
._M_iterator(__lhs, "lhs")
._M_iterator(__rhs, "rhs"));
_GLIBCXX_DEBUG_VERIFY(__lhs._M_in_same_bucket(__rhs),
_M_message(__msg_local_iter_compare_bad)
._M_iterator(__lhs, "lhs")
._M_iterator(__rhs, "rhs"));
_GLIBCXX_DEBUG_VERIFY_OPERANDS(__lhs, __rhs);
return __lhs.base() != __rhs.base();
}
template<typename _Iterator, typename _Sequence>
inline bool
operator!=(const _Safe_local_iterator<_Iterator, _Sequence>& __lhs,
const _Safe_local_iterator<_Iterator, _Sequence>& __rhs)
friend inline bool
operator!=(const _Self& __lhs, const _Self& __rhs) noexcept
{
_GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
_M_message(__msg_iter_compare_bad)
._M_iterator(__lhs, "lhs")
._M_iterator(__rhs, "rhs"));
_GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
_M_message(__msg_compare_different)
._M_iterator(__lhs, "lhs")
._M_iterator(__rhs, "rhs"));
_GLIBCXX_DEBUG_VERIFY(__lhs._M_in_same_bucket(__rhs),
_M_message(__msg_local_iter_compare_bad)
._M_iterator(__lhs, "lhs")
._M_iterator(__rhs, "rhs"));
_GLIBCXX_DEBUG_VERIFY_OPERANDS(__lhs, __rhs);
return __lhs.base() != __rhs.base();
}
};
/** Safe local iterators know how to check if they form a valid range. */
template<typename _Iterator, typename _Sequence>
......@@ -466,6 +431,8 @@ namespace __gnu_debug
} // namespace __gnu_debug
#undef _GLIBCXX_DEBUG_VERIFY_OPERANDS
#include <debug/safe_local_iterator.tcc>
#endif
// Copyright (C) 2018 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-do compile { target c++11 } }
#include <forward_list>
#include <testsuite_greedy_ops.h>
int main()
{
std::forward_list<greedy_ops::X> fl;
const std::forward_list<greedy_ops::X> cfl;
fl.insert_after(fl.before_begin(), greedy_ops::X());
fl.insert_after(fl.before_begin(), 1, greedy_ops::X());
fl.insert_after(fl.before_begin(), cfl.begin(), cfl.end());
fl = cfl;
return 0;
}
// Copyright (C) 2018 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-do compile }
#include <list>
#include <testsuite_greedy_ops.h>
int main()
{
std::list<greedy_ops::X> l;
const std::list<greedy_ops::X> cl;
l.size();
l.insert(l.begin(), greedy_ops::X());
l.insert(l.begin(), 1, greedy_ops::X());
l.insert(l.begin(), cl.begin(), cl.end());
l = cl;
return 0;
}
......@@ -23,6 +23,7 @@
#include <bits/boost_concept_check.h>
#include <cassert>
#include <testsuite_container_traits.h>
#include <utility> // for rel_ops.
// Container requirement testing.
namespace __gnu_test
......@@ -170,33 +171,38 @@ namespace __gnu_test
reverse_members(_Tp& container) { }
};
template<typename _Iterator,
bool _Mutable,
typename = typename std::iterator_traits<_Iterator>::iterator_category>
struct iterator_concept_checks;
// DR 691.
template<typename _Tp, bool = traits<_Tp>::is_unordered::value>
template<typename _Tp>
struct forward_members_unordered
{
forward_members_unordered(typename _Tp::value_type& v)
{
// Make sure that even if rel_ops is injected there is no ambiguity
// when comparing iterators.
using namespace std::rel_ops;
typedef _Tp test_type;
test_type container;
container.insert(v);
iterator_concept_checks<typename _Tp::local_iterator, false> cc;
iterator_concept_checks<typename _Tp::const_local_iterator,
false> ccc;
assert( container.cbegin(0) == container.begin(0) );
assert( container.cend(0) == container.end(0) );
const typename test_type::size_type bn = container.bucket(1);
assert( container.cbegin(bn) != container.cend(bn) );
assert( container.cbegin(bn) != container.end(bn) );
assert( container.begin(bn) != container.cend(bn) );
}
};
template<typename _Tp>
struct forward_members_unordered<_Tp, false>
{
forward_members_unordered(_Tp& container) { }
};
template<typename _Iterator,
bool _Mutable,
typename = typename std::iterator_traits<_Iterator>::iterator_category>
struct iterator_concept_checks;
template<typename _Iterator>
struct iterator_concept_checks<_Iterator, false,
std::forward_iterator_tag>
......@@ -264,6 +270,82 @@ namespace __gnu_test
};
template<typename _Tp>
struct forward_members
{
forward_members(_Tp& container)
{
// Make sure that even if rel_ops is injected there is no ambiguity
// when comparing iterators.
using namespace std::rel_ops;
typedef traits<_Tp> traits_type;
iterator_concept_checks<typename _Tp::iterator,
!(traits_type::is_associative::value
|| traits_type::is_unordered::value)> cc;
iterator_concept_checks<typename _Tp::const_iterator, false> ccc;
assert( container.cbegin() == container.begin() );
assert( container.end() == container.cend() );
assert( container.cbegin() != container.cend() );
assert( container.cbegin() != container.end() );
assert( container.begin() != container.cend() );
}
};
template<typename _Tp,
typename
= typename std::iterator_traits<typename _Tp::iterator>::iterator_category>
struct category_members : forward_members<_Tp>
{
category_members(_Tp& container)
: forward_members<_Tp>(container)
{ };
};
template<typename _Tp>
struct category_members<_Tp, std::random_access_iterator_tag>
: forward_members<_Tp>
{
category_members(_Tp& container)
: forward_members<_Tp>(container)
{
// Make sure that even if rel_ops is injected there is no ambiguity
// when comparing iterators.
using namespace std::rel_ops;
assert( !(container.begin() < container.begin()) );
assert( !(container.cbegin() < container.cbegin()) );
assert( !(container.cbegin() < container.begin()) );
assert( !(container.begin() < container.cbegin()) );
assert( container.begin() <= container.begin() );
assert( container.cbegin() <= container.cbegin() );
assert( container.cbegin() <= container.begin() );
assert( container.begin() <= container.cbegin() );
assert( !(container.begin() > container.begin()) );
assert( !(container.cbegin() > container.cbegin()) );
assert( !(container.cbegin() > container.begin()) );
assert( !(container.begin() > container.cbegin()) );
assert( container.begin() >= container.begin() );
assert( container.cbegin() >= container.cbegin() );
assert( container.cbegin() >= container.begin() );
assert( container.begin() >= container.cbegin() );
assert( container.begin() - container.begin() == 0 );
assert( container.cbegin() - container.cbegin() == 0 );
assert( container.cbegin() - container.begin() == 0 );
assert( container.begin() - container.cbegin() == 0 );
assert( container.begin() + 0 == container.begin() );
assert( container.cbegin() + 0 == container.cbegin() );
assert( 0 + container.begin() == container.begin() );
assert( 0 + container.cbegin() == container.cbegin() );
assert( container.begin() - 0 == container.begin() );
assert( container.cbegin() - 0 == container.cbegin() );
}
};
template<typename _Tp>
struct citerator
{
typedef _Tp test_type;
......@@ -273,21 +355,17 @@ namespace __gnu_test
static test_type _S_container;
// Unconditional.
struct forward_members
struct members : category_members<_Tp>
{
forward_members()
{
assert( _S_container.cbegin() == _S_container.begin() );
assert( _S_container.cend() == _S_container.end() );
assert( _S_container.cbegin() != _S_container.cend() );
}
members() : category_members<_Tp>(_S_container)
{ }
};
// Run test.
citerator()
{
populate<test_type> p(_S_container);
forward_members m1;
members m1;
reverse_members<test_type> m2(_S_container);
}
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment