diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index b99cbe708fd..f094251003c 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,25 @@ +2007-04-30 Paolo Carlini + + PR libstdc++/30449 (equal) + * include/bits/stl_algobase.h (struct __niter_base): Add. + (copy(_II, _II, _OI), copy_backward(_BI1, _BI1, _BI2), + fill(_ForwardIterator, _ForwardIterator, const _Tp&), + fill_n(_OI, _Size, const _Tp&), equal(_II1, _II1, _II2)): + Use it. + (struct __copy_normal, __copy_backward_normal, + struct __fill_normal, struct __fill_n_normal): Remove. + (struct __equal, struct __equal_aux): Add. + * include/bits/stl_iterator.h: Add _Iterator_type typedef. + + * include/bits/stl_algobase.h (__fill_aux(wchar_t*, + wchar_t*, wchar_t), __fill_n_aux(wchar_t*, _Size, wchar_t)): + Remove. + + * testsuite/23_containers/requirements/sequences/dr438/vector/ + constructor_1_neg.cc: Adjust dg-error line number. + * testsuite/23_containers/requirements/sequences/dr438/vector/ + constructor_2_neg.cc: Likewise. + 2007-04-30 Paolo Carlini * include/tr1/type_traits (is_pod): Use __is_pod. diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h index 52d09883699..6be1eb123e1 100644 --- a/libstdc++-v3/include/bits/stl_algobase.h +++ b/libstdc++-v3/include/bits/stl_algobase.h @@ -64,7 +64,6 @@ #include #include -#include #include #include #include @@ -161,9 +160,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std) _ReferenceType1; typedef typename iterator_traits<_ForwardIterator2>::reference _ReferenceType2; - std::__iter_swap<__are_same<_ValueType1, _ValueType2>::__value && - __are_same<_ValueType1 &, _ReferenceType1>::__value && - __are_same<_ValueType2 &, _ReferenceType2>::__value>:: + std::__iter_swap<__are_same<_ValueType1, _ValueType2>::__value + && __are_same<_ValueType1&, _ReferenceType1>::__value + && __are_same<_ValueType2&, _ReferenceType2>::__value>:: iter_swap(__a, __b); } @@ -285,6 +284,26 @@ _GLIBCXX_BEGIN_NAMESPACE(std) return __a; } + + // If _Iterator is a __normal_iterator return its base (a plain pointer, + // normally) otherwise return it untouched. See copy, fill, ... + template::__value> + struct __niter_base + { + static const _Iterator& + __b(const _Iterator& __it) + { return __it; } + }; + + template + struct __niter_base<_Iterator, true> + { + static const typename _Iterator::_Iterator_type& + __b(const _Iterator& __it) + { return __it.base(); } + }; + // All of these auxiliary structs serve two purposes. (1) Replace // calls to copy with memmove whenever possible. (Memmove, not memcpy, // because the input and output ranges are permitted to overlap.) @@ -378,43 +397,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std) __copy_aux(istreambuf_iterator<_CharT, char_traits<_CharT> >, istreambuf_iterator<_CharT, char_traits<_CharT> >, _CharT*); - template - struct __copy_normal - { - template - static _OI - __copy_n(_II __first, _II __last, _OI __result) - { return std::__copy_aux(__first, __last, __result); } - }; - - template<> - struct __copy_normal - { - template - static _OI - __copy_n(_II __first, _II __last, _OI __result) - { return std::__copy_aux(__first.base(), __last.base(), __result); } - }; - - template<> - struct __copy_normal - { - template - static _OI - __copy_n(_II __first, _II __last, _OI __result) - { return _OI(std::__copy_aux(__first, __last, __result.base())); } - }; - - template<> - struct __copy_normal - { - template - static _OI - __copy_n(_II __first, _II __last, _OI __result) - { return _OI(std::__copy_aux(__first.base(), __last.base(), - __result.base())); } - }; - /** * @brief Copies the range [first,last) into result. * @param first An input iterator. @@ -431,23 +413,22 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * Note that the end of the output range is permitted to be contained * within [first,last). */ - template - inline _OutputIterator - copy(_InputIterator __first, _InputIterator __last, - _OutputIterator __result) + template + inline _OI + copy(_II __first, _II __last, _OI __result) { // concept requirements - __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) - __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, - typename iterator_traits<_InputIterator>::value_type>) + __glibcxx_function_requires(_InputIteratorConcept<_II>) + __glibcxx_function_requires(_OutputIteratorConcept<_OI, + typename iterator_traits<_II>::value_type>) __glibcxx_requires_valid_range(__first, __last); - const bool __in = __is_normal_iterator<_InputIterator>::__value; - const bool __out = __is_normal_iterator<_OutputIterator>::__value; - return std::__copy_normal<__in, __out>::__copy_n(__first, __last, - __result); + return _OI(std::__copy_aux(__niter_base<_II>::__b(__first), + __niter_base<_II>::__b(__last), + __niter_base<_OI>::__b(__result))); } + template struct __copy_backward { @@ -505,45 +486,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std) __result); } - template - struct __copy_backward_normal - { - template - static _BI2 - __copy_b_n(_BI1 __first, _BI1 __last, _BI2 __result) - { return std::__copy_backward_aux(__first, __last, __result); } - }; - - template<> - struct __copy_backward_normal - { - template - static _BI2 - __copy_b_n(_BI1 __first, _BI1 __last, _BI2 __result) - { return std::__copy_backward_aux(__first.base(), __last.base(), - __result); } - }; - - template<> - struct __copy_backward_normal - { - template - static _BI2 - __copy_b_n(_BI1 __first, _BI1 __last, _BI2 __result) - { return _BI2(std::__copy_backward_aux(__first, __last, - __result.base())); } - }; - - template<> - struct __copy_backward_normal - { - template - static _BI2 - __copy_b_n(_BI1 __first, _BI1 __last, _BI2 __result) - { return _BI2(std::__copy_backward_aux(__first.base(), __last.base(), - __result.base())); } - }; - /** * @brief Copies the range [first,last) into result. * @param first A bidirectional iterator. @@ -573,11 +515,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std) typename iterator_traits<_BI2>::value_type>) __glibcxx_requires_valid_range(__first, __last); - const bool __bi1 = __is_normal_iterator<_BI1>::__value; - const bool __bi2 = __is_normal_iterator<_BI2>::__value; - return std::__copy_backward_normal<__bi1, __bi2>::__copy_b_n(__first, - __last, - __result); + return _BI2(std::__copy_backward_aux(__niter_base<_BI1>::__b(__first), + __niter_base<_BI1>::__b(__last), + __niter_base<_BI2>::__b(__result))); } @@ -617,7 +557,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) std::__fill<__scalar>::fill(__first, __last, __value); } - // Specialization: for char types we can use memset (wmemset). + // Specialization: for char types we can use memset. inline void __fill_aux(unsigned char* __first, unsigned char* __last, unsigned char __c) { std::memset(__first, __c, __last - __first); } @@ -630,32 +570,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std) __fill_aux(char* __first, char* __last, char __c) { std::memset(__first, static_cast(__c), __last - __first); } -#ifdef _GLIBCXX_USE_WCHAR_T - inline void - __fill_aux(wchar_t* __first, wchar_t* __last, wchar_t __c) - { std::wmemset(__first, __c, __last - __first); } -#endif - - template - struct __fill_normal - { - template - static void - __fill_n(_ForwardIterator __first, _ForwardIterator __last, - const _Tp& __value) - { std::__fill_aux(__first, __last, __value); } - }; - - template<> - struct __fill_normal - { - template - static void - __fill_n(_ForwardIterator __first, _ForwardIterator __last, - const _Tp& __value) - { std::__fill_aux(__first.base(), __last.base(), __value); } - }; - /** * @brief Fills the range [first,last) with copies of value. * @param first A forward iterator. @@ -676,8 +590,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std) _ForwardIterator>) __glibcxx_requires_valid_range(__first, __last); - const bool __fi = __is_normal_iterator<_ForwardIterator>::__value; - std::__fill_normal<__fi>::__fill_n(__first, __last, __value); + std::__fill_aux(__niter_base<_ForwardIterator>::__b(__first), + __niter_base<_ForwardIterator>::__b(__last), __value); } @@ -740,34 +654,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std) return __first + __n; } -#ifdef _GLIBCXX_USE_WCHAR_T - template - inline wchar_t* - __fill_n_aux(wchar_t* __first, _Size __n, wchar_t __c) - { - std::__fill_aux(__first, __first + __n, __c); - return __first + __n; - } -#endif - - template - struct __fill_n_normal - { - template - static _OI - __fill_n_n(_OI __first, _Size __n, const _Tp& __value) - { return std::__fill_n_aux(__first, __n, __value); } - }; - - template<> - struct __fill_n_normal - { - template - static _OI - __fill_n_n(_OI __first, _Size __n, const _Tp& __value) - { return _OI(std::__fill_n_aux(__first.base(), __n, __value)); } - }; - /** * @brief Fills the range [first,first+n) with copies of value. * @param first An output iterator. @@ -779,15 +665,15 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * types filling contiguous areas of memory, this becomes an inline call * to @c memset or @ wmemset. */ - template - inline _OutputIterator - fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) + template + inline _OI + fill_n(_OI __first, _Size __n, const _Tp& __value) { // concept requirements - __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, _Tp>) + __glibcxx_function_requires(_OutputIteratorConcept<_OI, _Tp>) - const bool __oi = __is_normal_iterator<_OutputIterator>::__value; - return std::__fill_n_normal<__oi>::__fill_n_n(__first, __n, __value); + return _OI(std::__fill_n_aux(__niter_base<_OI>::__b(__first), __n, + __value)); } /** @@ -856,6 +742,47 @@ _GLIBCXX_BEGIN_NAMESPACE(std) return pair<_InputIterator1, _InputIterator2>(__first1, __first2); } + + template + struct __equal + { + template + static bool + equal(_II1 __first1, _II1 __last1, _II2 __first2) + { + for (; __first1 != __last1; ++__first1, ++__first2) + if (!(*__first1 == *__first2)) + return false; + return true; + } + }; + + template<> + struct __equal + { + template + static bool + equal(const _Tp* __first1, const _Tp* __last1, const _Tp* __first2) + { + return !std::memcmp(__first1, __first2, sizeof(_Tp) + * (__last1 - __first1)); + } + }; + + template + inline bool + __equal_aux(_II1 __first1, _II1 __last1, _II2 __first2) + { + typedef typename iterator_traits<_II1>::value_type _ValueType1; + typedef typename iterator_traits<_II2>::value_type _ValueType2; + const bool __simple = (__is_integer<_ValueType1>::__value + && __is_pointer<_II1>::__value + && __is_pointer<_II2>::__value + && __are_same<_ValueType1, _ValueType2>::__value); + + return std::__equal<__simple>::equal(__first1, __last1, __first2); + } + /** * @brief Tests a range for element-wise equality. * @param first1 An input iterator. @@ -867,23 +794,21 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * false depending on whether all of the corresponding elements of the * ranges are equal. */ - template + template inline bool - equal(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2) + equal(_II1 __first1, _II1 __last1, _II2 __first2) { // concept requirements - __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) - __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) + __glibcxx_function_requires(_InputIteratorConcept<_II1>) + __glibcxx_function_requires(_InputIteratorConcept<_II2>) __glibcxx_function_requires(_EqualOpConcept< - typename iterator_traits<_InputIterator1>::value_type, - typename iterator_traits<_InputIterator2>::value_type>) + typename iterator_traits<_II1>::value_type, + typename iterator_traits<_II2>::value_type>) __glibcxx_requires_valid_range(__first1, __last1); - - for (; __first1 != __last1; ++__first1, ++__first2) - if (!(*__first1 == *__first2)) - return false; - return true; + + return std::__equal_aux(__niter_base<_II1>::__b(__first1), + __niter_base<_II1>::__b(__last1), + __niter_base<_II2>::__b(__first2)); } /** diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index f9425aa14bc..06aa105ece4 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -1,6 +1,6 @@ // Iterators -*- C++ -*- -// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -647,6 +647,8 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) typedef typename iterator_traits<_Iterator>::reference reference; typedef typename iterator_traits<_Iterator>::pointer pointer; + typedef _Iterator _Iterator_type; + __normal_iterator() : _M_current(_Iterator()) { } explicit diff --git a/libstdc++-v3/testsuite/23_containers/requirements/sequences/dr438/vector/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/requirements/sequences/dr438/vector/constructor_1_neg.cc index c66faaec941..b850c71cf84 100644 --- a/libstdc++-v3/testsuite/23_containers/requirements/sequences/dr438/vector/constructor_1_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/requirements/sequences/dr438/vector/constructor_1_neg.cc @@ -19,7 +19,7 @@ // USA. // { dg-do compile } -// { dg-error "no match" "" { target *-*-* } 706 } +// { dg-error "no match" "" { target *-*-* } 620 } // { dg-excess-errors "" } #include diff --git a/libstdc++-v3/testsuite/23_containers/requirements/sequences/dr438/vector/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/requirements/sequences/dr438/vector/constructor_2_neg.cc index 8e0130bc9cf..194da7342a4 100644 --- a/libstdc++-v3/testsuite/23_containers/requirements/sequences/dr438/vector/constructor_2_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/requirements/sequences/dr438/vector/constructor_2_neg.cc @@ -19,7 +19,7 @@ // USA. // { dg-do compile } -// { dg-error "no match" "" { target *-*-* } 706 } +// { dg-error "no match" "" { target *-*-* } 620 } // { dg-excess-errors "" } #include