This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[Patch] ADL issues: vector
- From: Paolo Carlini <pcarlini at suse dot de>
- To: libstdc++ <libstdc++ at gcc dot gnu dot org>
- Date: Thu, 01 Dec 2005 17:26:05 +0100
- Subject: [Patch] ADL issues: vector
Hi again,
as expected, a longer patch, but nothing particularly interesting.
Forgot to mention together with the string bits that the new testcases
are fine also in debug mode (that's why I added consistently the
operator- also for _Safe_iterator). Tested x86-linux.
Time to start porting older and newer improvements to mainline...
Paolo.
////////////////
2005-12-01 Paolo Carlini <pcarlini@suse.de>
* include/bits/stl_vector.h (vector<>::size, resize, capacity,
operator[]): Avoid troubles with ADL, user defined operators
and __normal_iterator.
(_M_erase_at_end): Fix to take a pointer.
(clear): Adjust call.
* include/bits/vector.tcc (vector<>::insert(iterator, const
value_type&), erase(iterator, iterator), operator=(const
vector<>&), _M_assign_aux(input_iterator_tag), _M_insert_aux,
_M_fill_insert, _M_range_insert): Likewise.
(_M_fill_assign, _M_assign_aux(forward_iterator_tag)): Adjust
_M_erase_at_end call.
* testsuite/23_containers/vector/types/1.cc: New.
Index: include/bits/stl_vector.h
===================================================================
--- include/bits/stl_vector.h (revision 107718)
+++ include/bits/stl_vector.h (working copy)
@@ -363,7 +363,7 @@
*/
iterator
begin()
- { return iterator (this->_M_impl._M_start); }
+ { return iterator(this->_M_impl._M_start); }
/**
* Returns a read-only (constant) iterator that points to the
@@ -372,7 +372,7 @@
*/
const_iterator
begin() const
- { return const_iterator (this->_M_impl._M_start); }
+ { return const_iterator(this->_M_impl._M_start); }
/**
* Returns a read/write iterator that points one past the last
@@ -381,7 +381,7 @@
*/
iterator
end()
- { return iterator (this->_M_impl._M_finish); }
+ { return iterator(this->_M_impl._M_finish); }
/**
* Returns a read-only (constant) iterator that points one past
@@ -390,7 +390,7 @@
*/
const_iterator
end() const
- { return const_iterator (this->_M_impl._M_finish); }
+ { return const_iterator(this->_M_impl._M_finish); }
/**
* Returns a read/write reverse iterator that points to the
@@ -432,7 +432,7 @@
/** Returns the number of elements in the %vector. */
size_type
size() const
- { return size_type(end() - begin()); }
+ { return size_type(this->_M_impl._M_finish - this->_M_impl._M_start); }
/** Returns the size() of the largest possible %vector. */
size_type
@@ -454,7 +454,7 @@
resize(size_type __new_size, value_type __x = value_type())
{
if (__new_size < size())
- _M_erase_at_end(begin() + __new_size);
+ _M_erase_at_end(this->_M_impl._M_start + __new_size);
else
insert(end(), __new_size - size(), __x);
}
@@ -465,8 +465,8 @@
*/
size_type
capacity() const
- { return size_type(const_iterator(this->_M_impl._M_end_of_storage)
- - begin()); }
+ { return size_type(this->_M_impl._M_end_of_storage
+ - this->_M_impl._M_start); }
/**
* Returns true if the %vector is empty. (Thus begin() would
@@ -510,7 +510,7 @@
*/
reference
operator[](size_type __n)
- { return *(begin() + __n); }
+ { return *(this->_M_impl._M_start + __n); }
/**
* @brief Subscript access to the data contained in the %vector.
@@ -525,7 +525,7 @@
*/
const_reference
operator[](size_type __n) const
- { return *(begin() + __n); }
+ { return *(this->_M_impl._M_start + __n); }
protected:
/// @if maint Safety check used only from at(). @endif
@@ -803,7 +803,7 @@
*/
void
clear()
- { _M_erase_at_end(begin()); }
+ { _M_erase_at_end(this->_M_impl._M_start); }
protected:
/**
@@ -999,11 +999,10 @@
// Called by erase(q1,q2), clear(), resize(), _M_fill_assign,
// _M_assign_aux.
void
- _M_erase_at_end(iterator __pos)
+ _M_erase_at_end(pointer __pos)
{
- std::_Destroy(__pos.base(), this->_M_impl._M_finish,
- _M_get_Tp_allocator());
- this->_M_impl._M_finish = __pos.base();
+ std::_Destroy(__pos, this->_M_impl._M_finish, _M_get_Tp_allocator());
+ this->_M_impl._M_finish = __pos;
}
};
Index: include/bits/vector.tcc
===================================================================
--- include/bits/vector.tcc (revision 106945)
+++ include/bits/vector.tcc (working copy)
@@ -73,8 +73,7 @@
if (this->capacity() < __n)
{
const size_type __old_size = size();
- pointer __tmp = _M_allocate_and_move(__n,
- this->_M_impl._M_start,
+ pointer __tmp = _M_allocate_and_move(__n, this->_M_impl._M_start,
this->_M_impl._M_finish);
std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
_M_get_Tp_allocator());
@@ -101,7 +100,7 @@
}
else
_M_insert_aux(__position, __x);
- return begin() + __n;
+ return iterator(this->_M_impl._M_start + __n);
}
template<typename _Tp, typename _Alloc>
@@ -123,7 +122,7 @@
{
if (__last != end())
std::__move(__last, end(), __first);
- _M_erase_at_end(__first + (end() - __last));
+ _M_erase_at_end(__first.base() + (end() - __last));
return __first;
}
@@ -149,15 +148,16 @@
}
else if (size() >= __xlen)
{
- iterator __i(std::copy(__x.begin(), __x.end(), begin()));
- std::_Destroy(__i, end(), _M_get_Tp_allocator());
+ std::_Destroy(std::copy(__x.begin(), __x.end(), begin()),
+ end(), _M_get_Tp_allocator());
}
else
{
- std::copy(__x.begin(), __x.begin() + size(),
+ std::copy(__x._M_impl._M_start, __x._M_impl._M_start + size(),
this->_M_impl._M_start);
- std::__uninitialized_copy_a(__x.begin() + size(),
- __x.end(), this->_M_impl._M_finish,
+ std::__uninitialized_copy_a(__x._M_impl._M_start + size(),
+ __x._M_impl._M_finish,
+ this->_M_impl._M_finish,
_M_get_Tp_allocator());
}
this->_M_impl._M_finish = this->_M_impl._M_start + __xlen;
@@ -184,7 +184,7 @@
this->_M_impl._M_finish += __n - size();
}
else
- _M_erase_at_end(std::fill_n(begin(), __n, __val));
+ _M_erase_at_end(std::fill_n(this->_M_impl._M_start, __n, __val));
}
template<typename _Tp, typename _Alloc>
@@ -194,8 +194,9 @@
_M_assign_aux(_InputIterator __first, _InputIterator __last,
std::input_iterator_tag)
{
- iterator __cur(begin());
- for (; __first != __last && __cur != end(); ++__cur, ++__first)
+ pointer __cur(this->_M_impl._M_start);
+ for (; __first != __last && __cur != this->_M_impl._M_finish;
+ ++__cur, ++__first)
*__cur = *__first;
if (__first == __last)
_M_erase_at_end(__cur);
@@ -225,11 +226,7 @@
this->_M_impl._M_end_of_storage = this->_M_impl._M_finish;
}
else if (size() >= __len)
- {
- iterator __new_finish(std::copy(__first, __last,
- this->_M_impl._M_start));
- _M_erase_at_end(__new_finish);
- }
+ _M_erase_at_end(std::copy(__first, __last, this->_M_impl._M_start));
else
{
_ForwardIterator __mid = __first;
@@ -256,9 +253,9 @@
- 1)),
_M_get_Tp_allocator());
++this->_M_impl._M_finish;
- std::__move_backward(__position,
- iterator(this->_M_impl._M_finish-2),
- iterator(this->_M_impl._M_finish-1));
+ std::__move_backward(__position.base(),
+ this->_M_impl._M_finish - 2,
+ this->_M_impl._M_finish - 1);
*__position = __gnu_cxx::__move(__x_copy);
}
else
@@ -274,36 +271,37 @@
if (__len < __old_size)
__len = this->max_size();
- iterator __new_start(this->_M_allocate(__len));
- iterator __new_finish(__new_start);
+ pointer __new_start(this->_M_allocate(__len));
+ pointer __new_finish(__new_start);
try
{
__new_finish =
- std::__uninitialized_move_a(iterator(this->_M_impl._M_start),
- __position, __new_start,
+ std::__uninitialized_move_a(this->_M_impl._M_start,
+ __position.base(), __new_start,
_M_get_Tp_allocator());
- _Construct_a(__new_finish.base(), __gnu_cxx::__move(__x_copy),
+ _Construct_a(__new_finish, __gnu_cxx::__move(__x_copy),
_M_get_Tp_allocator());
++__new_finish;
__new_finish =
- std::__uninitialized_move_a(__position,
- iterator(this->_M_impl._M_finish),
+ std::__uninitialized_move_a(__position.base(),
+ this->_M_impl._M_finish,
__new_finish,
_M_get_Tp_allocator());
}
catch(...)
{
std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator());
- _M_deallocate(__new_start.base(),__len);
+ _M_deallocate(__new_start, __len);
__throw_exception_again;
}
- std::_Destroy(begin(), end(), _M_get_Tp_allocator());
+ std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
+ _M_get_Tp_allocator());
_M_deallocate(this->_M_impl._M_start,
this->_M_impl._M_end_of_storage
- this->_M_impl._M_start);
- this->_M_impl._M_start = __new_start.base();
- this->_M_impl._M_finish = __new_finish.base();
- this->_M_impl._M_end_of_storage = __new_start.base() + __len;
+ this->_M_impl._M_start = __new_start;
+ this->_M_impl._M_finish = __new_finish;
+ this->_M_impl._M_end_of_storage = __new_start + __len;
}
}
@@ -319,7 +317,7 @@
{
value_type __x_copy = __x;
const size_type __elems_after = end() - __position;
- iterator __old_finish(this->_M_impl._M_finish);
+ pointer __old_finish(this->_M_impl._M_finish);
if (__elems_after > __n)
{
std::__uninitialized_move_a(this->_M_impl._M_finish - __n,
@@ -327,9 +325,10 @@
this->_M_impl._M_finish,
_M_get_Tp_allocator());
this->_M_impl._M_finish += __n;
- std::__move_backward(__position, __old_finish - __n,
- __old_finish);
- std::fill(__position, __position + __n, __x_copy);
+ std::__move_backward(__position.base(), __old_finish - __n,
+ __old_finish);
+ std::fill(__position.base(), __position.base() + __n,
+ __x_copy);
}
else
{
@@ -338,11 +337,11 @@
__x_copy,
_M_get_Tp_allocator());
this->_M_impl._M_finish += __n - __elems_after;
- std::__uninitialized_move_a(__position, __old_finish,
+ std::__uninitialized_move_a(__position.base(), __old_finish,
this->_M_impl._M_finish,
_M_get_Tp_allocator());
this->_M_impl._M_finish += __elems_after;
- std::fill(__position, __old_finish, __x_copy);
+ std::fill(__position.base(), __old_finish, __x_copy);
}
}
else
@@ -357,26 +356,29 @@
if (__len < __old_size)
__len = this->max_size();
- iterator __new_start(this->_M_allocate(__len));
- iterator __new_finish(__new_start);
+ pointer __new_start(this->_M_allocate(__len));
+ pointer __new_finish(__new_start);
try
{
__new_finish =
- std::__uninitialized_move_a(begin(), __position,
+ std::__uninitialized_move_a(this->_M_impl._M_start,
+ __position.base(),
__new_start,
_M_get_Tp_allocator());
std::__uninitialized_fill_n_a(__new_finish, __n, __x_copy,
_M_get_Tp_allocator());
__new_finish += __n;
__new_finish =
- std::__uninitialized_move_a(__position, end(), __new_finish,
+ std::__uninitialized_move_a(__position.base(),
+ this->_M_impl._M_finish,
+ __new_finish,
_M_get_Tp_allocator());
}
catch(...)
{
std::_Destroy(__new_start, __new_finish,
_M_get_Tp_allocator());
- _M_deallocate(__new_start.base(), __len);
+ _M_deallocate(__new_start, __len);
__throw_exception_again;
}
std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
@@ -384,9 +386,9 @@
_M_deallocate(this->_M_impl._M_start,
this->_M_impl._M_end_of_storage
- this->_M_impl._M_start);
- this->_M_impl._M_start = __new_start.base();
- this->_M_impl._M_finish = __new_finish.base();
- this->_M_impl._M_end_of_storage = __new_start.base() + __len;
+ this->_M_impl._M_start = __new_start;
+ this->_M_impl._M_finish = __new_finish;
+ this->_M_impl._M_end_of_storage = __new_start + __len;
}
}
}
@@ -418,7 +420,7 @@
- this->_M_impl._M_finish) >= __n)
{
const size_type __elems_after = end() - __position;
- iterator __old_finish(this->_M_impl._M_finish);
+ pointer __old_finish(this->_M_impl._M_finish);
if (__elems_after > __n)
{
std::__uninitialized_move_a(this->_M_impl._M_finish - __n,
@@ -426,7 +428,7 @@
this->_M_impl._M_finish,
_M_get_Tp_allocator());
this->_M_impl._M_finish += __n;
- std::__move_backward(__position, __old_finish - __n,
+ std::__move_backward(__position.base(), __old_finish - __n,
__old_finish);
std::copy(__first, __last, __position);
}
@@ -438,7 +440,8 @@
this->_M_impl._M_finish,
_M_get_Tp_allocator());
this->_M_impl._M_finish += __n - __elems_after;
- std::__uninitialized_move_a(__position, __old_finish,
+ std::__uninitialized_move_a(__position.base(),
+ __old_finish,
this->_M_impl._M_finish,
_M_get_Tp_allocator());
this->_M_impl._M_finish += __elems_after;
@@ -456,30 +459,29 @@
if (__len < __old_size)
__len = this->max_size();
- iterator __new_start(this->_M_allocate(__len));
- iterator __new_finish(__new_start);
+ pointer __new_start(this->_M_allocate(__len));
+ pointer __new_finish(__new_start);
try
{
__new_finish =
- std::__uninitialized_move_a(iterator(this->
- _M_impl._M_start),
- __position, __new_start,
+ std::__uninitialized_move_a(this->_M_impl._M_start,
+ __position.base(),
+ __new_start,
_M_get_Tp_allocator());
__new_finish =
std::__uninitialized_copy_a(__first, __last, __new_finish,
_M_get_Tp_allocator());
__new_finish =
- std::__uninitialized_move_a(__position,
- iterator(this->
- _M_impl._M_finish),
+ std::__uninitialized_move_a(__position.base(),
+ this->_M_impl._M_finish,
__new_finish,
_M_get_Tp_allocator());
}
catch(...)
{
- std::_Destroy(__new_start,__new_finish,
+ std::_Destroy(__new_start, __new_finish,
_M_get_Tp_allocator());
- _M_deallocate(__new_start.base(), __len);
+ _M_deallocate(__new_start, __len);
__throw_exception_again;
}
std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
@@ -487,9 +489,9 @@
_M_deallocate(this->_M_impl._M_start,
this->_M_impl._M_end_of_storage
- this->_M_impl._M_start);
- this->_M_impl._M_start = __new_start.base();
- this->_M_impl._M_finish = __new_finish.base();
- this->_M_impl._M_end_of_storage = __new_start.base() + __len;
+ this->_M_impl._M_start = __new_start;
+ this->_M_impl._M_finish = __new_finish;
+ this->_M_impl._M_end_of_storage = __new_start + __len;
}
}
}
Index: testsuite/23_containers/vector/types/1.cc
===================================================================
--- testsuite/23_containers/vector/types/1.cc (revision 0)
+++ testsuite/23_containers/vector/types/1.cc (revision 0)
@@ -0,0 +1,54 @@
+// 2005-12-01 Paolo Carlini <pcarlini@suse.de>
+
+// Copyright (C) 2005 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// { dg-do compile }
+
+#include <vector>
+
+namespace N
+{
+ struct X { };
+
+ template<typename T>
+ X operator+(T, std::size_t)
+ { return X(); }
+
+ template<typename T>
+ X operator-(T, T)
+ { return X(); }
+}
+
+int main()
+{
+ std::vector<N::X> v(5);
+ const std::vector<N::X> w(1);
+
+ v[0];
+ w[0];
+ v.size();
+ v.capacity();
+ v.resize(1);
+ v.insert(v.begin(), N::X());
+ v.insert(v.begin(), 1, N::X());
+ v.insert(v.begin(), w.begin(), w.end());
+ v = w;
+
+ return 0;
+}