re PR libstdc++/61347 (std::distance(list.first(),list.end()) in O(1))
2015-04-14 Marc Glisse <marc.glisse@inria.fr> PR libstdc++/61347 * include/bits/stl_iterator_base_funcs.h (_List_iterator, _List_const_iterator): Declare. (__distance): Declare new overloads for _List_iterator and _List_const_iterator. * include/bits/stl_list.h (__distance): New overloads for _List_iterator and _List_const_iterator. * testsuite/23_containers/list/61347.cc: New testcase. From-SVN: r222082
This commit is contained in:
parent
453e2916ce
commit
194571f10e
|
@ -1,3 +1,14 @@
|
||||||
|
2015-04-14 Marc Glisse <marc.glisse@inria.fr>
|
||||||
|
|
||||||
|
PR libstdc++/61347
|
||||||
|
* include/bits/stl_iterator_base_funcs.h (_List_iterator,
|
||||||
|
_List_const_iterator): Declare.
|
||||||
|
(__distance): Declare new overloads for _List_iterator and
|
||||||
|
_List_const_iterator.
|
||||||
|
* include/bits/stl_list.h (__distance): New overloads for
|
||||||
|
_List_iterator and _List_const_iterator.
|
||||||
|
* testsuite/23_containers/list/61347.cc: New testcase.
|
||||||
|
|
||||||
2015-04-14 Jonathan Wakely <jwakely@redhat.com>
|
2015-04-14 Jonathan Wakely <jwakely@redhat.com>
|
||||||
|
|
||||||
* doc/xml/manual/evolution.xml: Fix typos.
|
* doc/xml/manual/evolution.xml: Fix typos.
|
||||||
|
|
|
@ -66,6 +66,12 @@
|
||||||
|
|
||||||
namespace std _GLIBCXX_VISIBILITY(default)
|
namespace std _GLIBCXX_VISIBILITY(default)
|
||||||
{
|
{
|
||||||
|
_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||||
|
// Forward declaration for the overloads of __distance.
|
||||||
|
template <typename> struct _List_iterator;
|
||||||
|
template <typename> struct _List_const_iterator;
|
||||||
|
_GLIBCXX_END_NAMESPACE_CONTAINER
|
||||||
|
|
||||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
|
|
||||||
template<typename _InputIterator>
|
template<typename _InputIterator>
|
||||||
|
@ -96,6 +102,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
return __last - __first;
|
return __last - __first;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if _GLIBCXX_USE_CXX11_ABI
|
||||||
|
// Forward declaration because of the qualified call in distance.
|
||||||
|
template<typename _Tp>
|
||||||
|
ptrdiff_t
|
||||||
|
__distance(_GLIBCXX_STD_C::_List_iterator<_Tp>,
|
||||||
|
_GLIBCXX_STD_C::_List_iterator<_Tp>,
|
||||||
|
input_iterator_tag);
|
||||||
|
|
||||||
|
template<typename _Tp>
|
||||||
|
ptrdiff_t
|
||||||
|
__distance(_GLIBCXX_STD_C::_List_const_iterator<_Tp>,
|
||||||
|
_GLIBCXX_STD_C::_List_const_iterator<_Tp>,
|
||||||
|
input_iterator_tag);
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A generalization of pointer arithmetic.
|
* @brief A generalization of pointer arithmetic.
|
||||||
* @param __first An input iterator.
|
* @param __first An input iterator.
|
||||||
|
|
|
@ -1868,6 +1868,45 @@ _GLIBCXX_END_NAMESPACE_CXX11
|
||||||
{ __x.swap(__y); }
|
{ __x.swap(__y); }
|
||||||
|
|
||||||
_GLIBCXX_END_NAMESPACE_CONTAINER
|
_GLIBCXX_END_NAMESPACE_CONTAINER
|
||||||
|
|
||||||
|
#if _GLIBCXX_USE_CXX11_ABI
|
||||||
|
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
|
|
||||||
|
// Detect when distance is used to compute the size of the whole list.
|
||||||
|
template<typename _Tp>
|
||||||
|
inline ptrdiff_t
|
||||||
|
__distance(_GLIBCXX_STD_C::_List_iterator<_Tp> __first,
|
||||||
|
_GLIBCXX_STD_C::_List_iterator<_Tp> __last,
|
||||||
|
input_iterator_tag __tag)
|
||||||
|
{
|
||||||
|
typedef _GLIBCXX_STD_C::_List_const_iterator<_Tp> _CIter;
|
||||||
|
return std::__distance(_CIter(__first), _CIter(__last), __tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename _Tp>
|
||||||
|
inline ptrdiff_t
|
||||||
|
__distance(_GLIBCXX_STD_C::_List_const_iterator<_Tp> __first,
|
||||||
|
_GLIBCXX_STD_C::_List_const_iterator<_Tp> __last,
|
||||||
|
input_iterator_tag)
|
||||||
|
{
|
||||||
|
typedef _GLIBCXX_STD_C::_List_node<size_t> _Sentinel;
|
||||||
|
_GLIBCXX_STD_C::_List_const_iterator<_Tp> __beyond = __last;
|
||||||
|
++__beyond;
|
||||||
|
bool __whole = __first == __beyond;
|
||||||
|
if (__builtin_constant_p (__whole) && __whole)
|
||||||
|
return static_cast<const _Sentinel*>(__last._M_node)->_M_data;
|
||||||
|
|
||||||
|
ptrdiff_t __n = 0;
|
||||||
|
while (__first != __last)
|
||||||
|
{
|
||||||
|
++__first;
|
||||||
|
++__n;
|
||||||
|
}
|
||||||
|
return __n;
|
||||||
|
}
|
||||||
|
|
||||||
|
_GLIBCXX_END_NAMESPACE_VERSION
|
||||||
|
#endif
|
||||||
} // namespace std
|
} // namespace std
|
||||||
|
|
||||||
#endif /* _STL_LIST_H */
|
#endif /* _STL_LIST_H */
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
// { dg-options "-std=gnu++11 -O2 -D_GLIBCXX_USE_CXX11_ABI" }
|
||||||
|
|
||||||
|
// Copyright (C) 2015 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/>.
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <iterator>
|
||||||
|
#include <testsuite_hooks.h>
|
||||||
|
|
||||||
|
__attribute__((__noinline__, __noclone__))
|
||||||
|
void testm(std::list<short>& l)
|
||||||
|
{
|
||||||
|
bool b = std::distance(l.begin(), l.end()) == l.size();
|
||||||
|
VERIFY( __builtin_constant_p(b) );
|
||||||
|
VERIFY( b );
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((__noinline__, __noclone__))
|
||||||
|
void testc(const std::list<short>& l)
|
||||||
|
{
|
||||||
|
bool b = std::distance(l.begin(), l.end()) == l.size();
|
||||||
|
VERIFY( __builtin_constant_p(b) );
|
||||||
|
VERIFY( b );
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
bool test __attribute__((unused)) = true;
|
||||||
|
|
||||||
|
#if _GLIBCXX_USE_DUAL_ABI
|
||||||
|
std::list<short> l;
|
||||||
|
testm(l);
|
||||||
|
testc(l);
|
||||||
|
#endif
|
||||||
|
}
|
Loading…
Reference in New Issue