diff options
-rw-r--r-- | libstdc++-v3/ChangeLog | 51 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/deque.tcc | 294 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/list.tcc | 12 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/stl_deque.h | 154 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/stl_list.h | 45 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/stl_vector.h | 91 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/vector.tcc | 158 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/23_containers/deque/cons/clear_allocator.cc | 88 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/23_containers/list/cons/clear_allocator.cc | 88 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/23_containers/vector/cons/clear_allocator.cc | 88 |
10 files changed, 697 insertions, 372 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 0ab564104dc..162c8473a59 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,11 +1,50 @@ +2004-03-25 Dhruv Matani <dhruvbird@gmx.net> + + * include/bits/stl_list.h: Created a _List_impl class and made it + derive from the allocator, instead of the list deriving from the + allocator class, which was not conformant. Changed all references + from this->_M_node to this->_M_impl._M_node * bits/list.tcc: Same + as above (changed all references to the concerned variables). + +2004-03-25 Dhruv Matani <dhruvbird@gmx.net> + + * include/bits/stl_deque.h: Created a _Deque_impl class and made + it derive from the allocator, instead of the deque deriving from + the allocator class, which was not conformant. Changed all + references to the _M_start, _M_finish, _M_map, and _M_map_size to + _M_impl.*. + (_Deque_base<_Tp,_Alloc>::~_Deque_base()): Added this-> + qualification in 2 places where it was missing. + (_Deque_base<_Tp,_Alloc>::_M_initialize_map(size_t)): Same as + above. + * include/bits/deque.tcc: Same as above (changed all references to + the concerned variables). + +2004-03-25 Dhruv Matani <dhruvbird@gmx.net> + + * include/bits/stl_vector.h: Created a _Vector_impl class and made + it derive from the allocator, instead of the _Vector_base class, + deriving from the allocator which was not conformant. Changed all + references to the _M_start, _M_finish, and _M_end_of_storage to + _M_impl.*. + * include/bits/vector.tcc: Same as above (changed all references + to the concerned variables). + +2004-03-25 Dhruv Matani <dhruvbird@gmx.net> + + * testsuite/23_containers/deque/cons/clear_allocator.cc: New. + * testsuite/23_containers/list/cons/clear_allocator.cc: New. + * testsuite/23_containers/vector/cons/clear_allocator.cc: New. + 2004-03-24 Dhruv Matani <dhruvbird@gmx.net> - * ext/malloc_allocator.h: Fixed the construct function to call - global placement new instead of assignment. Added a check after - the return from malloc to check whether returned pointer is NULL, - and if so, throw std::bad_alloc(). - * ext/debug_allocator.h: Added a check in the deallocate function - to check whether the user has passed a NULL pointer or not. + * include/ext/malloc_allocator.h: Fixed the construct function to + call global placement new instead of assignment. Added a check + after the return from malloc to check whether returned pointer is + NULL, and if so, throw std::bad_alloc(). + * include/ext/debug_allocator.h: Added a check in the deallocate + function to check whether the user has passed a NULL pointer or + not. 2004-03-24 Benjamin Kosnik <bkoz@redhat.com> diff --git a/libstdc++-v3/include/bits/deque.tcc b/libstdc++-v3/include/bits/deque.tcc index a30c8516684..22fc573d9c0 100644 --- a/libstdc++-v3/include/bits/deque.tcc +++ b/libstdc++-v3/include/bits/deque.tcc @@ -72,13 +72,13 @@ namespace __gnu_norm if (&__x != this) { if (__len >= __x.size()) - erase(std::copy(__x.begin(), __x.end(), this->_M_start), - this->_M_finish); + erase(std::copy(__x.begin(), __x.end(), this->_M_impl._M_start), + this->_M_impl._M_finish); else { const_iterator __mid = __x.begin() + difference_type(__len); - std::copy(__x.begin(), __mid, this->_M_start); - insert(this->_M_finish, __mid, __x.end()); + std::copy(__x.begin(), __mid, this->_M_impl._M_start); + insert(this->_M_impl._M_finish, __mid, __x.end()); } } return *this; @@ -89,15 +89,15 @@ namespace __gnu_norm deque<_Tp,_Alloc>:: insert(iterator position, const value_type& __x) { - if (position._M_cur == this->_M_start._M_cur) + if (position._M_cur == this->_M_impl._M_start._M_cur) { push_front(__x); - return this->_M_start; + return this->_M_impl._M_start; } - else if (position._M_cur == this->_M_finish._M_cur) + else if (position._M_cur == this->_M_impl._M_finish._M_cur) { push_back(__x); - iterator __tmp = this->_M_finish; + iterator __tmp = this->_M_impl._M_finish; --__tmp; return __tmp; } @@ -112,18 +112,18 @@ namespace __gnu_norm { iterator __next = __position; ++__next; - size_type __index = __position - this->_M_start; + size_type __index = __position - this->_M_impl._M_start; if (__index < (size() >> 1)) { - std::copy_backward(this->_M_start, __position, __next); + std::copy_backward(this->_M_impl._M_start, __position, __next); pop_front(); } else { - std::copy(__next, this->_M_finish, __position); + std::copy(__next, this->_M_impl._M_finish, __position); pop_back(); } - return this->_M_start + __index; + return this->_M_impl._M_start + __index; } template <typename _Tp, typename _Alloc> @@ -131,33 +131,33 @@ namespace __gnu_norm deque<_Tp,_Alloc>:: erase(iterator __first, iterator __last) { - if (__first == this->_M_start && __last == this->_M_finish) + if (__first == this->_M_impl._M_start && __last == this->_M_impl._M_finish) { clear(); - return this->_M_finish; + return this->_M_impl._M_finish; } else { const difference_type __n = __last - __first; - const difference_type __elems_before = __first - this->_M_start; + const difference_type __elems_before = __first - this->_M_impl._M_start; if (static_cast<size_type>(__elems_before) < (size() - __n) / 2) { - std::copy_backward(this->_M_start, __first, __last); - iterator __new_start = this->_M_start + __n; - std::_Destroy(this->_M_start, __new_start); - _M_destroy_nodes(this->_M_start._M_node, __new_start._M_node); - this->_M_start = __new_start; + std::copy_backward(this->_M_impl._M_start, __first, __last); + iterator __new_start = this->_M_impl._M_start + __n; + std::_Destroy(this->_M_impl._M_start, __new_start); + _M_destroy_nodes(this->_M_impl._M_start._M_node, __new_start._M_node); + this->_M_impl._M_start = __new_start; } else { - std::copy(__last, this->_M_finish, __first); - iterator __new_finish = this->_M_finish - __n; - std::_Destroy(__new_finish, this->_M_finish); + std::copy(__last, this->_M_impl._M_finish, __first); + iterator __new_finish = this->_M_impl._M_finish - __n; + std::_Destroy(__new_finish, this->_M_impl._M_finish); _M_destroy_nodes(__new_finish._M_node + 1, - this->_M_finish._M_node + 1); - this->_M_finish = __new_finish; + this->_M_impl._M_finish._M_node + 1); + this->_M_impl._M_finish = __new_finish; } - return this->_M_start + __elems_before; + return this->_M_impl._M_start + __elems_before; } } @@ -166,24 +166,24 @@ namespace __gnu_norm deque<_Tp,_Alloc>:: clear() { - for (_Map_pointer __node = this->_M_start._M_node + 1; - __node < this->_M_finish._M_node; + for (_Map_pointer __node = this->_M_impl._M_start._M_node + 1; + __node < this->_M_impl._M_finish._M_node; ++__node) { std::_Destroy(*__node, *__node + _S_buffer_size()); _M_deallocate_node(*__node); } - if (this->_M_start._M_node != this->_M_finish._M_node) + if (this->_M_impl._M_start._M_node != this->_M_impl._M_finish._M_node) { - std::_Destroy(this->_M_start._M_cur, this->_M_start._M_last); - std::_Destroy(this->_M_finish._M_first, this->_M_finish._M_cur); - _M_deallocate_node(this->_M_finish._M_first); + std::_Destroy(this->_M_impl._M_start._M_cur, this->_M_impl._M_start._M_last); + std::_Destroy(this->_M_impl._M_finish._M_first, this->_M_impl._M_finish._M_cur); + _M_deallocate_node(this->_M_impl._M_finish._M_first); } else - std::_Destroy(this->_M_start._M_cur, this->_M_finish._M_cur); + std::_Destroy(this->_M_impl._M_start._M_cur, this->_M_impl._M_finish._M_cur); - this->_M_finish = this->_M_start; + this->_M_impl._M_finish = this->_M_impl._M_start; } template <typename _Tp, class _Alloc> @@ -207,31 +207,31 @@ namespace __gnu_norm deque<_Tp,_Alloc>:: _M_fill_insert(iterator __pos, size_type __n, const value_type& __x) { - if (__pos._M_cur == this->_M_start._M_cur) + if (__pos._M_cur == this->_M_impl._M_start._M_cur) { iterator __new_start = _M_reserve_elements_at_front(__n); try { - std::uninitialized_fill(__new_start, this->_M_start, __x); - this->_M_start = __new_start; + std::uninitialized_fill(__new_start, this->_M_impl._M_start, __x); + this->_M_impl._M_start = __new_start; } catch(...) { - _M_destroy_nodes(__new_start._M_node, this->_M_start._M_node); + _M_destroy_nodes(__new_start._M_node, this->_M_impl._M_start._M_node); __throw_exception_again; } } - else if (__pos._M_cur == this->_M_finish._M_cur) + else if (__pos._M_cur == this->_M_impl._M_finish._M_cur) { iterator __new_finish = _M_reserve_elements_at_back(__n); try { - std::uninitialized_fill(this->_M_finish, __new_finish, __x); - this->_M_finish = __new_finish; + std::uninitialized_fill(this->_M_impl._M_finish, __new_finish, __x); + this->_M_impl._M_finish = __new_finish; } catch(...) { - _M_destroy_nodes(this->_M_finish._M_node + 1, + _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, __new_finish._M_node + 1); __throw_exception_again; } @@ -248,17 +248,17 @@ namespace __gnu_norm _Map_pointer __cur; try { - for (__cur = this->_M_start._M_node; - __cur < this->_M_finish._M_node; + for (__cur = this->_M_impl._M_start._M_node; + __cur < this->_M_impl._M_finish._M_node; ++__cur) std::uninitialized_fill(*__cur, *__cur + _S_buffer_size(), __value); - std::uninitialized_fill(this->_M_finish._M_first, - this->_M_finish._M_cur, + std::uninitialized_fill(this->_M_impl._M_finish._M_first, + this->_M_impl._M_finish._M_cur, __value); } catch(...) { - std::_Destroy(this->_M_start, iterator(*__cur, __cur)); + std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur)); __throw_exception_again; } } @@ -296,8 +296,8 @@ namespace __gnu_norm _Map_pointer __cur_node; try { - for (__cur_node = this->_M_start._M_node; - __cur_node < this->_M_finish._M_node; + for (__cur_node = this->_M_impl._M_start._M_node; + __cur_node < this->_M_impl._M_finish._M_node; ++__cur_node) { _ForwardIterator __mid = __first; @@ -305,16 +305,16 @@ namespace __gnu_norm std::uninitialized_copy(__first, __mid, *__cur_node); __first = __mid; } - std::uninitialized_copy(__first, __last, this->_M_finish._M_first); + std::uninitialized_copy(__first, __last, this->_M_impl._M_finish._M_first); } catch(...) { - std::_Destroy(this->_M_start, iterator(*__cur_node, __cur_node)); + std::_Destroy(this->_M_impl._M_start, iterator(*__cur_node, __cur_node)); __throw_exception_again; } } - // Called only if _M_finish._M_cur == _M_finish._M_last - 1. + // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_last - 1. template <typename _Tp, typename _Alloc> void deque<_Tp,_Alloc>:: @@ -322,21 +322,21 @@ namespace __gnu_norm { value_type __t_copy = __t; _M_reserve_map_at_back(); - *(this->_M_finish._M_node + 1) = this->_M_allocate_node(); + *(this->_M_impl._M_finish._M_node + 1) = this->_M_allocate_node(); try { - std::_Construct(this->_M_finish._M_cur, __t_copy); - this->_M_finish._M_set_node(this->_M_finish._M_node + 1); - this->_M_finish._M_cur = this->_M_finish._M_first; + std::_Construct(this->_M_impl._M_finish._M_cur, __t_copy); + this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node + 1); + this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first; } catch(...) { - _M_deallocate_node(*(this->_M_finish._M_node + 1)); + _M_deallocate_node(*(this->_M_impl._M_finish._M_node + 1)); __throw_exception_again; } } - // Called only if _M_start._M_cur == _M_start._M_first. + // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_first. template <typename _Tp, typename _Alloc> void deque<_Tp,_Alloc>:: @@ -344,44 +344,44 @@ namespace __gnu_norm { value_type __t_copy = __t; _M_reserve_map_at_front(); - *(this->_M_start._M_node - 1) = this->_M_allocate_node(); + *(this->_M_impl._M_start._M_node - 1) = this->_M_allocate_node(); try { - this->_M_start._M_set_node(this->_M_start._M_node - 1); - this->_M_start._M_cur = this->_M_start._M_last - 1; - std::_Construct(this->_M_start._M_cur, __t_copy); + this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node - 1); + this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_last - 1; + std::_Construct(this->_M_impl._M_start._M_cur, __t_copy); } catch(...) { - ++this->_M_start; - _M_deallocate_node(*(this->_M_start._M_node - 1)); + ++this->_M_impl._M_start; + _M_deallocate_node(*(this->_M_impl._M_start._M_node - 1)); __throw_exception_again; } } - // Called only if _M_finish._M_cur == _M_finish._M_first. + // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_first. template <typename _Tp, typename _Alloc> void deque<_Tp,_Alloc>:: _M_pop_back_aux() { - _M_deallocate_node(this->_M_finish._M_first); - this->_M_finish._M_set_node(this->_M_finish._M_node - 1); - this->_M_finish._M_cur = this->_M_finish._M_last - 1; - std::_Destroy(this->_M_finish._M_cur); + _M_deallocate_node(this->_M_impl._M_finish._M_first); + this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node - 1); + this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_last - 1; + std::_Destroy(this->_M_impl._M_finish._M_cur); } - // Called only if _M_start._M_cur == _M_start._M_last - 1. Note that + // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_last - 1. Note that // if the deque has at least one element (a precondition for this member - // function), and if _M_start._M_cur == _M_start._M_last, then the deque + // function), and if _M_impl._M_start._M_cur == _M_impl._M_start._M_last, then the deque // must have at least two nodes. template <typename _Tp, typename _Alloc> void deque<_Tp,_Alloc>:: _M_pop_front_aux() { - std::_Destroy(this->_M_start._M_cur); - _M_deallocate_node(this->_M_start._M_first); - this->_M_start._M_set_node(this->_M_start._M_node + 1); - this->_M_start._M_cur = this->_M_start._M_first; + std::_Destroy(this->_M_impl._M_start._M_cur); + _M_deallocate_node(this->_M_impl._M_start._M_first); + this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node + 1); + this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_first; } template <typename _Tp, typename _Alloc> @@ -402,31 +402,31 @@ namespace __gnu_norm forward_iterator_tag) { size_type __n = std::distance(__first, __last); - if (__pos._M_cur == this->_M_start._M_cur) + if (__pos._M_cur == this->_M_impl._M_start._M_cur) { iterator __new_start = _M_reserve_elements_at_front(__n); try { std::uninitialized_copy(__first, __last, __new_start); - this->_M_start = __new_start; + this->_M_impl._M_start = __new_start; } catch(...) { - _M_destroy_nodes(__new_start._M_node, this->_M_start._M_node); + _M_destroy_nodes(__new_start._M_node, this->_M_impl._M_start._M_node); __throw_exception_again; } } - else if (__pos._M_cur == this->_M_finish._M_cur) + else if (__pos._M_cur == this->_M_impl._M_finish._M_cur) { iterator __new_finish = _M_reserve_elements_at_back(__n); try { - std::uninitialized_copy(__first, __last, this->_M_finish); - this->_M_finish = __new_finish; + std::uninitialized_copy(__first, __last, this->_M_impl._M_finish); + this->_M_impl._M_finish = __new_finish; } catch(...) { - _M_destroy_nodes(this->_M_finish._M_node + 1, + _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, __new_finish._M_node + 1); __throw_exception_again; } @@ -440,16 +440,16 @@ namespace __gnu_norm deque<_Tp,_Alloc>:: _M_insert_aux(iterator __pos, const value_type& __x) { - difference_type __index = __pos - this->_M_start; + difference_type __index = __pos - this->_M_impl._M_start; value_type __x_copy = __x; // XXX copy if (static_cast<size_type>(__index) < size() / 2) { push_front(front()); - iterator __front1 = this->_M_start; + iterator __front1 = this->_M_impl._M_start; ++__front1; iterator __front2 = __front1; ++__front2; - __pos = this->_M_start + __index; + __pos = this->_M_impl._M_start + __index; iterator __pos1 = __pos; ++__pos1; std::copy(__front2, __pos1, __front1); @@ -457,11 +457,11 @@ namespace __gnu_norm else { push_back(back()); - iterator __back1 = this->_M_finish; + iterator __back1 = this->_M_impl._M_finish; --__back1; iterator __back2 = __back1; --__back2; - __pos = this->_M_start + __index; + __pos = this->_M_impl._M_start + __index; std::copy_backward(__pos, __back2, __back1); } *__pos = __x_copy; @@ -473,71 +473,71 @@ namespace __gnu_norm deque<_Tp,_Alloc>:: _M_insert_aux(iterator __pos, size_type __n, const value_type& __x) { - const difference_type __elems_before = __pos - this->_M_start; + const difference_type __elems_before = __pos - this->_M_impl._M_start; size_type __length = this->size(); value_type __x_copy = __x; if (__elems_before < difference_type(__length / 2)) { iterator __new_start = _M_reserve_elements_at_front(__n); - iterator __old_start = this->_M_start; - __pos = this->_M_start + __elems_before; + iterator __old_start = this->_M_impl._M_start; + __pos = this->_M_impl._M_start + __elems_before; try { if (__elems_before >= difference_type(__n)) { - iterator __start_n = this->_M_start + difference_type(__n); - std::uninitialized_copy(this->_M_start, __start_n, + iterator __start_n = this->_M_impl._M_start + difference_type(__n); + std::uninitialized_copy(this->_M_impl._M_start, __start_n, __new_start); - this->_M_start = __new_start; + this->_M_impl._M_start = __new_start; std::copy(__start_n, __pos, __old_start); fill(__pos - difference_type(__n), __pos, __x_copy); } else { - std::__uninitialized_copy_fill(this->_M_start, __pos, + std::__uninitialized_copy_fill(this->_M_impl._M_start, __pos, __new_start, - this->_M_start, __x_copy); - this->_M_start = __new_start; + this->_M_impl._M_start, __x_copy); + this->_M_impl._M_start = __new_start; std::fill(__old_start, __pos, __x_copy); } } catch(...) { - _M_destroy_nodes(__new_start._M_node, this->_M_start._M_node); + _M_destroy_nodes(__new_start._M_node, this->_M_impl._M_start._M_node); __throw_exception_again; } } else { iterator __new_finish = _M_reserve_elements_at_back(__n); - iterator __old_finish = this->_M_finish; + iterator __old_finish = this->_M_impl._M_finish; const difference_type __elems_after = difference_type(__length) - __elems_before; - __pos = this->_M_finish - __elems_after; + __pos = this->_M_impl._M_finish - __elems_after; try { if (__elems_after > difference_type(__n)) { - iterator __finish_n = this->_M_finish - difference_type(__n); - std::uninitialized_copy(__finish_n, this->_M_finish, - this->_M_finish); - this->_M_finish = __new_finish; + iterator __finish_n = this->_M_impl._M_finish - difference_type(__n); + std::uninitialized_copy(__finish_n, this->_M_impl._M_finish, + this->_M_impl._M_finish); + this->_M_impl._M_finish = __new_finish; std::copy_backward(__pos, __finish_n, __old_finish); std::fill(__pos, __pos + difference_type(__n), __x_copy); } else { - std::__uninitialized_fill_copy(this->_M_finish, + std::__uninitialized_fill_copy(this->_M_impl._M_finish, __pos + difference_type(__n), __x_copy, __pos, - this->_M_finish); - this->_M_finish = __new_finish; + this->_M_impl._M_finish); + this->_M_impl._M_finish = __new_finish; std::fill(__pos, __old_finish, __x_copy); } } catch(...) { - _M_destroy_nodes(this->_M_finish._M_node + 1, + _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, __new_finish._M_node + 1); __throw_exception_again; } @@ -552,21 +552,21 @@ namespace __gnu_norm _ForwardIterator __first, _ForwardIterator __last, size_type __n) { - const difference_type __elemsbefore = __pos - this->_M_start; + const difference_type __elemsbefore = __pos - this->_M_impl._M_start; size_type __length = size(); if (static_cast<size_type>(__elemsbefore) < __length / 2) { iterator __new_start = _M_reserve_elements_at_front(__n); - iterator __old_start = this->_M_start; - __pos = this->_M_start + __elemsbefore; + iterator __old_start = this->_M_impl._M_start; + __pos = this->_M_impl._M_start + __elemsbefore; try { if (__elemsbefore >= difference_type(__n)) { - iterator __start_n = this->_M_start + difference_type(__n); - std::uninitialized_copy(this->_M_start, __start_n, + iterator __start_n = this->_M_impl._M_start + difference_type(__n); + std::uninitialized_copy(this->_M_impl._M_start, __start_n, __new_start); - this->_M_start = __new_start; + this->_M_impl._M_start = __new_start; std::copy(__start_n, __pos, __old_start); std::copy(__first, __last, __pos - difference_type(__n)); } @@ -574,34 +574,34 @@ namespace __gnu_norm { _ForwardIterator __mid = __first; std::advance(__mid, difference_type(__n) - __elemsbefore); - std::__uninitialized_copy_copy(this->_M_start, __pos, + std::__uninitialized_copy_copy(this->_M_impl._M_start, __pos, __first, __mid, __new_start); - this->_M_start = __new_start; + this->_M_impl._M_start = __new_start; std::copy(__mid, __last, __old_start); } } catch(...) { - _M_destroy_nodes(__new_start._M_node, this->_M_start._M_node); + _M_destroy_nodes(__new_start._M_node, this->_M_impl._M_start._M_node); __throw_exception_again; } } else { iterator __new_finish = _M_reserve_elements_at_back(__n); - iterator __old_finish = this->_M_finish; + iterator __old_finish = this->_M_impl._M_finish; const difference_type __elemsafter = difference_type(__length) - __elemsbefore; - __pos = this->_M_finish - __elemsafter; + __pos = this->_M_impl._M_finish - __elemsafter; try { if (__elemsafter > difference_type(__n)) { - iterator __finish_n = this->_M_finish - difference_type(__n); + iterator __finish_n = this->_M_impl._M_finish - difference_type(__n); std::uninitialized_copy(__finish_n, - this->_M_finish, - this->_M_finish); - this->_M_finish = __new_finish; + this->_M_impl._M_finish, + this->_M_impl._M_finish); + this->_M_impl._M_finish = __new_finish; std::copy_backward(__pos, __finish_n, __old_finish); std::copy(__first, __last, __pos); } @@ -610,15 +610,15 @@ namespace __gnu_norm _ForwardIterator __mid = __first; std::advance(__mid, __elemsafter); std::__uninitialized_copy_copy(__mid, __last, __pos, - this->_M_finish, - this->_M_finish); - this->_M_finish = __new_finish; + this->_M_impl._M_finish, + this->_M_impl._M_finish); + this->_M_impl._M_finish = __new_finish; std::copy(__first, __mid, __pos); } } catch(...) { - _M_destroy_nodes(this->_M_finish._M_node + 1, + _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, __new_finish._M_node + 1); __throw_exception_again; } @@ -637,12 +637,12 @@ namespace __gnu_norm try { for (__i = 1; __i <= __new_nodes; ++__i) - *(this->_M_start._M_node - __i) = this->_M_allocate_node(); + *(this->_M_impl._M_start._M_node - __i) = this->_M_allocate_node(); } catch(...) { for (size_type __j = 1; __j < __i; ++__j) - _M_deallocate_node(*(this->_M_start._M_node - __j)); + _M_deallocate_node(*(this->_M_impl._M_start._M_node - __j)); __throw_exception_again; } } @@ -659,12 +659,12 @@ namespace __gnu_norm try { for (__i = 1; __i <= __new_nodes; ++__i) - *(this->_M_finish._M_node + __i) = this->_M_allocate_node(); + *(this->_M_impl._M_finish._M_node + __i) = this->_M_allocate_node(); } catch(...) { for (size_type __j = 1; __j < __i; ++__j) - _M_deallocate_node(*(this->_M_finish._M_node + __j)); + _M_deallocate_node(*(this->_M_impl._M_finish._M_node + __j)); __throw_exception_again; } } @@ -675,44 +675,44 @@ namespace __gnu_norm _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front) { size_type __old_num_nodes - = this->_M_finish._M_node - this->_M_start._M_node + 1; + = this->_M_impl._M_finish._M_node - this->_M_impl._M_start._M_node + 1; size_type __new_num_nodes = __old_num_nodes + __nodes_to_add; _Map_pointer __new_nstart; - if (this->_M_map_size > 2 * __new_num_nodes) + if (this->_M_impl._M_map_size > 2 * __new_num_nodes) { - __new_nstart = this->_M_map + (this->_M_map_size + __new_nstart = this->_M_impl._M_map + (this->_M_impl._M_map_size - __new_num_nodes) / 2 + (__add_at_front ? __nodes_to_add : 0); - if (__new_nstart < this->_M_start._M_node) - std::copy(this->_M_start._M_node, - this->_M_finish._M_node + 1, + if (__new_nstart < this->_M_impl._M_start._M_node) + std::copy(this->_M_impl._M_start._M_node, + this->_M_impl._M_finish._M_node + 1, __new_nstart); else - std::copy_backward(this->_M_start._M_node, - this->_M_finish._M_node + 1, + std::copy_backward(this->_M_impl._M_start._M_node, + this->_M_impl._M_finish._M_node + 1, __new_nstart + __old_num_nodes); } else { - size_type __new_map_size = this->_M_map_size - + std::max(this->_M_map_size, + size_type __new_map_size = this->_M_impl._M_map_size + + std::max(this->_M_impl._M_map_size, __nodes_to_add) + 2; _Map_pointer __new_map = this->_M_allocate_map(__new_map_size); __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2 + (__add_at_front ? __nodes_to_add : 0); - std::copy(this->_M_start._M_node, - this->_M_finish._M_node + 1, + std::copy(this->_M_impl._M_start._M_node, + this->_M_impl._M_finish._M_node + 1, __new_nstart); - _M_deallocate_map(this->_M_map, this->_M_map_size); + _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size); - this->_M_map = __new_map; - this->_M_map_size = __new_map_size; + this->_M_impl._M_map = __new_map; + this->_M_impl._M_map_size = __new_map_size; } - this->_M_start._M_set_node(__new_nstart); - this->_M_finish._M_set_node(__new_nstart + __old_num_nodes - 1); + this->_M_impl._M_start._M_set_node(__new_nstart); + this->_M_impl._M_finish._M_set_node(__new_nstart + __old_num_nodes - 1); } } // namespace __gnu_norm diff --git a/libstdc++-v3/include/bits/list.tcc b/libstdc++-v3/include/bits/list.tcc index c5e20f8e5d7..f712be2ab0b 100644 --- a/libstdc++-v3/include/bits/list.tcc +++ b/libstdc++-v3/include/bits/list.tcc @@ -69,8 +69,8 @@ namespace __gnu_norm _M_clear() { typedef _List_node<_Tp> _Node; - _Node* __cur = static_cast<_Node*>(this->_M_node._M_next); - while (__cur != &this->_M_node) + _Node* __cur = static_cast<_Node*>(this->_M_impl._M_node._M_next); + while (__cur != &this->_M_impl._M_node) { _Node* __tmp = __cur; __cur = static_cast<_Node*>(__cur->_M_next); @@ -237,8 +237,8 @@ namespace __gnu_norm sort() { // Do nothing if the list has length 0 or 1. - if (this->_M_node._M_next != &this->_M_node - && this->_M_node._M_next->_M_next != &this->_M_node) + if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node + && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node) { list __carry; list __tmp[64]; @@ -341,8 +341,8 @@ namespace __gnu_norm sort(_StrictWeakOrdering __comp) { // Do nothing if the list has length 0 or 1. - if (this->_M_node._M_next != &this->_M_node - && this->_M_node._M_next->_M_next != &this->_M_node) + if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node + && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node) { list __carry; list __tmp[64]; diff --git a/libstdc++-v3/include/bits/stl_deque.h b/libstdc++-v3/include/bits/stl_deque.h index 31126775ad0..5d237d5f3c1 100644 --- a/libstdc++-v3/include/bits/stl_deque.h +++ b/libstdc++-v3/include/bits/stl_deque.h @@ -351,39 +351,54 @@ namespace __gnu_norm */ template<typename _Tp, typename _Alloc> class _Deque_base - : public _Alloc { public: typedef _Alloc allocator_type; allocator_type get_allocator() const - { return *static_cast<const _Alloc*>(this); } + { return *static_cast<const _Alloc*>(&this->_M_impl); } typedef _Deque_iterator<_Tp,_Tp&,_Tp*> iterator; typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; _Deque_base(const allocator_type& __a, size_t __num_elements) - : _Alloc(__a), _M_start(), _M_finish() + : _M_impl(__a) { _M_initialize_map(__num_elements); } _Deque_base(const allocator_type& __a) - : _Alloc(__a), _M_start(), _M_finish() { } + : _M_impl(__a) + { } ~_Deque_base(); protected: + //This struct encapsulates the implementation of the std::deque + //standard container and at the same time makes use of the EBO + //for empty allocators. + struct _Deque_impl + : public _Alloc { + _Tp** _M_map; + size_t _M_map_size; + iterator _M_start; + iterator _M_finish; + + _Deque_impl(const _Alloc& __a) + : _Alloc(__a), _M_map(0), _M_map_size(0), _M_start(), _M_finish() + { } + }; + typedef typename _Alloc::template rebind<_Tp*>::other _Map_alloc_type; _Map_alloc_type _M_get_map_allocator() const { return _Map_alloc_type(this->get_allocator()); } _Tp* _M_allocate_node() - { return _Alloc::allocate(__deque_buf_size(sizeof(_Tp))); } + { return _M_impl._Alloc::allocate(__deque_buf_size(sizeof(_Tp))); } void _M_deallocate_node(_Tp* __p) - { _Alloc::deallocate(__p, __deque_buf_size(sizeof(_Tp))); } + { _M_impl._Alloc::deallocate(__p, __deque_buf_size(sizeof(_Tp))); } _Tp** _M_allocate_map(size_t __n) @@ -399,19 +414,16 @@ namespace __gnu_norm void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish); enum { _S_initial_map_size = 8 }; - _Tp** _M_map; - size_t _M_map_size; - iterator _M_start; - iterator _M_finish; + _Deque_impl _M_impl; }; template<typename _Tp, typename _Alloc> _Deque_base<_Tp,_Alloc>::~_Deque_base() { - if (this->_M_map) + if (this->_M_impl._M_map) { - _M_destroy_nodes(_M_start._M_node, _M_finish._M_node + 1); - _M_deallocate_map(this->_M_map, this->_M_map_size); + _M_destroy_nodes(this->_M_impl._M_start._M_node, this->_M_impl._M_finish._M_node + 1); + _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size); } } @@ -431,32 +443,32 @@ namespace __gnu_norm { size_t __num_nodes = __num_elements / __deque_buf_size(sizeof(_Tp)) + 1; - this->_M_map_size = std::max((size_t) _S_initial_map_size, + this->_M_impl._M_map_size = std::max((size_t) _S_initial_map_size, __num_nodes + 2); - this->_M_map = _M_allocate_map(this->_M_map_size); + this->_M_impl._M_map = _M_allocate_map(this->_M_impl._M_map_size); // For "small" maps (needing less than _M_map_size nodes), allocation // starts in the middle elements and grows outwards. So nstart may be // the beginning of _M_map, but for small maps it may be as far in as // _M_map+3. - _Tp** __nstart = this->_M_map + (this->_M_map_size - __num_nodes) / 2; + _Tp** __nstart = this->_M_impl._M_map + (this->_M_impl._M_map_size - __num_nodes) / 2; _Tp** __nfinish = __nstart + __num_nodes; try { _M_create_nodes(__nstart, __nfinish); } catch(...) { - _M_deallocate_map(this->_M_map, this->_M_map_size); - this->_M_map = 0; - this->_M_map_size = 0; + _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size); + this->_M_impl._M_map = 0; + this->_M_impl._M_map_size = 0; __throw_exception_again; } - _M_start._M_set_node(__nstart); - _M_finish._M_set_node(__nfinish - 1); - _M_start._M_cur = _M_start._M_first; - _M_finish._M_cur = _M_finish._M_first + __num_elements + this->_M_impl._M_start._M_set_node(__nstart); + this->_M_impl._M_finish._M_set_node(__nfinish - 1); + this->_M_impl._M_start._M_cur = _M_impl._M_start._M_first; + this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first + __num_elements % __deque_buf_size(sizeof(_Tp)); } @@ -608,12 +620,10 @@ namespace __gnu_norm /** @if maint * A total of four data members accumulated down the heirarchy. + * May be accessed via _M_impl.* * @endif */ - using _Base::_M_map; - using _Base::_M_map_size; - using _Base::_M_start; - using _Base::_M_finish; + using _Base::_M_impl; public: // [23.2.1.1] construct/copy/destroy @@ -658,7 +668,7 @@ namespace __gnu_norm */ deque(const deque& __x) : _Base(__x.get_allocator(), __x.size()) - { std::uninitialized_copy(__x.begin(), __x.end(), this->_M_start); } + { std::uninitialized_copy(__x.begin(), __x.end(), this->_M_impl._M_start); } /** * @brief Builds a %deque from a range. @@ -690,7 +700,7 @@ namespace __gnu_norm * way. Managing the pointer is the user's responsibilty. */ ~deque() - { std::_Destroy(this->_M_start, this->_M_finish); } + { std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); } /** * @brief %Deque assignment operator. @@ -748,7 +758,7 @@ namespace __gnu_norm */ iterator begin() - { return this->_M_start; } + { return this->_M_impl._M_start; } /** * Returns a read-only (constant) iterator that points to the first @@ -756,7 +766,7 @@ namespace __gnu_norm */ const_iterator begin() const - { return this->_M_start; } + { return this->_M_impl._M_start; } /** * Returns a read/write iterator that points one past the last element in @@ -764,7 +774,7 @@ namespace __gnu_norm */ iterator end() - { return this->_M_finish; } + { return this->_M_impl._M_finish; } /** * Returns a read-only (constant) iterator that points one past the last @@ -772,7 +782,7 @@ namespace __gnu_norm */ const_iterator end() const - { return this->_M_finish; } + { return this->_M_impl._M_finish; } /** * Returns a read/write reverse iterator that points to the last element @@ -780,7 +790,7 @@ namespace __gnu_norm */ reverse_iterator rbegin() - { return reverse_iterator(this->_M_finish); } + { return reverse_iterator(this->_M_impl._M_finish); } /** * Returns a read-only (constant) reverse iterator that points to the @@ -789,7 +799,7 @@ namespace __gnu_norm */ const_reverse_iterator rbegin() const - { return const_reverse_iterator(this->_M_finish); } + { return const_reverse_iterator(this->_M_impl._M_finish); } /** * Returns a read/write reverse iterator that points to one before the @@ -797,7 +807,7 @@ namespace __gnu_norm * order. */ reverse_iterator - rend() { return reverse_iterator(this->_M_start); } + rend() { return reverse_iterator(this->_M_impl._M_start); } /** * Returns a read-only (constant) reverse iterator that points to one @@ -806,13 +816,13 @@ namespace __gnu_norm */ const_reverse_iterator rend() const - { return const_reverse_iterator(this->_M_start); } + { return const_reverse_iterator(this->_M_impl._M_start); } // [23.2.1.2] capacity /** Returns the number of elements in the %deque. */ size_type size() const - { return this->_M_finish - this->_M_start; } + { return this->_M_impl._M_finish - this->_M_impl._M_start; } /** Returns the size() of the largest possible %deque. */ size_type @@ -834,9 +844,9 @@ namespace __gnu_norm { const size_type __len = size(); if (__new_size < __len) - erase(this->_M_start + __new_size, this->_M_finish); + erase(this->_M_impl._M_start + __new_size, this->_M_impl._M_finish); else - insert(this->_M_finish, __new_size - __len, __x); + insert(this->_M_impl._M_finish, __new_size - __len, __x); } /** @@ -857,7 +867,7 @@ namespace __gnu_norm */ bool empty() const - { return this->_M_finish == this->_M_start; } + { return this->_M_impl._M_finish == this->_M_impl._M_start; } // element access /** @@ -871,7 +881,7 @@ namespace __gnu_norm */ reference operator[](size_type __n) - { return this->_M_start[difference_type(__n)]; } + { return this->_M_impl._M_start[difference_type(__n)]; } /** * @brief Subscript access to the data contained in the %deque. @@ -884,7 +894,7 @@ namespace __gnu_norm */ const_reference operator[](size_type __n) const - { return this->_M_start[difference_type(__n)]; } + { return this->_M_impl._M_start[difference_type(__n)]; } protected: /// @if maint Safety check used only from at(). @endif @@ -933,7 +943,7 @@ namespace __gnu_norm */ reference front() - { return *this->_M_start; } + { return *this->_M_impl._M_start; } /** * Returns a read-only (constant) reference to the data at the first @@ -941,7 +951,7 @@ namespace __gnu_norm */ const_reference front() const - { return *this->_M_start; } + { return *this->_M_impl._M_start; } /** * Returns a read/write reference to the data at the last element of the @@ -950,7 +960,7 @@ namespace __gnu_norm reference back() { - iterator __tmp = this->_M_finish; + iterator __tmp = this->_M_impl._M_finish; --__tmp; return *__tmp; } @@ -962,7 +972,7 @@ namespace __gnu_norm const_reference back() const { - const_iterator __tmp = this->_M_finish; + const_iterator __tmp = this->_M_impl._M_finish; --__tmp; return *__tmp; } @@ -979,10 +989,10 @@ namespace __gnu_norm void push_front(const value_type& __x) { - if (this->_M_start._M_cur != this->_M_start._M_first) + if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_first) { - std::_Construct(this->_M_start._M_cur - 1, __x); - --this->_M_start._M_cur; + std::_Construct(this->_M_impl._M_start._M_cur - 1, __x); + --this->_M_impl._M_start._M_cur; } else _M_push_front_aux(__x); @@ -999,10 +1009,10 @@ namespace __gnu_norm void push_back(const value_type& __x) { - if (this->_M_finish._M_cur != this->_M_finish._M_last - 1) + if (this->_M_impl._M_finish._M_cur != this->_M_impl._M_finish._M_last - 1) { - std::_Construct(this->_M_finish._M_cur, __x); - ++this->_M_finish._M_cur; + std::_Construct(this->_M_impl._M_finish._M_cur, __x); + ++this->_M_impl._M_finish._M_cur; } else _M_push_back_aux(__x); @@ -1019,10 +1029,10 @@ namespace __gnu_norm void pop_front() { - if (this->_M_start._M_cur != this->_M_start._M_last - 1) + if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_last - 1) { - std::_Destroy(this->_M_start._M_cur); - ++this->_M_start._M_cur; + std::_Destroy(this->_M_impl._M_start._M_cur); + ++this->_M_impl._M_start._M_cur; } else _M_pop_front_aux(); @@ -1039,10 +1049,10 @@ namespace __gnu_norm void pop_back() { - if (this->_M_finish._M_cur != this->_M_finish._M_first) + if (this->_M_impl._M_finish._M_cur != this->_M_impl._M_finish._M_first) { - --this->_M_finish._M_cur; - std::_Destroy(this->_M_finish._M_cur); + --this->_M_impl._M_finish._M_cur; + std::_Destroy(this->_M_impl._M_finish._M_cur); } else _M_pop_back_aux(); @@ -1140,10 +1150,10 @@ namespace __gnu_norm void swap(deque& __x) { - std::swap(this->_M_start, __x._M_start); - std::swap(this->_M_finish, __x._M_finish); - std::swap(this->_M_map, __x._M_map); - std::swap(this->_M_map_size, __x._M_map_size); + std::swap(this->_M_impl._M_start, __x._M_impl._M_start); + std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); + std::swap(this->_M_impl._M_map, __x._M_impl._M_map); + std::swap(this->_M_impl._M_map_size, __x._M_impl._M_map_size); } /** @@ -1362,21 +1372,21 @@ namespace __gnu_norm iterator _M_reserve_elements_at_front(size_type __n) { - const size_type __vacancies = this->_M_start._M_cur - - this->_M_start._M_first; + const size_type __vacancies = this->_M_impl._M_start._M_cur + - this->_M_impl._M_start._M_first; if (__n > __vacancies) _M_new_elements_at_front(__n - __vacancies); - return this->_M_start - difference_type(__n); + return this->_M_impl._M_start - difference_type(__n); } iterator _M_reserve_elements_at_back(size_type __n) { - const size_type __vacancies = (this->_M_finish._M_last - - this->_M_finish._M_cur) - 1; + const size_type __vacancies = (this->_M_impl._M_finish._M_last + - this->_M_impl._M_finish._M_cur) - 1; if (__n > __vacancies) _M_new_elements_at_back(__n - __vacancies); - return this->_M_finish + difference_type(__n); + return this->_M_impl._M_finish + difference_type(__n); } void @@ -1400,15 +1410,15 @@ namespace __gnu_norm void _M_reserve_map_at_back (size_type __nodes_to_add = 1) { - if (__nodes_to_add + 1 > this->_M_map_size - - (this->_M_finish._M_node - this->_M_map)) + if (__nodes_to_add + 1 > this->_M_impl._M_map_size + - (this->_M_impl._M_finish._M_node - this->_M_impl._M_map)) _M_reallocate_map(__nodes_to_add, false); } void _M_reserve_map_at_front (size_type __nodes_to_add = 1) { - if (__nodes_to_add > size_type(this->_M_start._M_node - this->_M_map)) + if (__nodes_to_add > size_type(this->_M_impl._M_start._M_node - this->_M_impl._M_map)) _M_reallocate_map(__nodes_to_add, true); } diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h index 15f73914a2d..c0d821116c7 100644 --- a/libstdc++-v3/include/bits/stl_list.h +++ b/libstdc++-v3/include/bits/stl_list.h @@ -275,7 +275,6 @@ namespace __gnu_norm */ template<typename _Tp, typename _Alloc> class _List_base - : public _Alloc::template rebind<_List_node<_Tp> >::other { protected: // NOTA BENE @@ -295,25 +294,33 @@ namespace __gnu_norm _Node_Alloc_type; - _List_node_base _M_node; + struct _List_impl + : public _Node_Alloc_type { + _List_node_base _M_node; + _List_impl (const _Node_Alloc_type& __a) + : _Node_Alloc_type(__a) + { } + }; + + _List_impl _M_impl; _List_node<_Tp>* _M_get_node() - { return _Node_Alloc_type::allocate(1); } - + { return _M_impl._Node_Alloc_type::allocate(1); } + void _M_put_node(_List_node<_Tp>* __p) - { _Node_Alloc_type::deallocate(__p, 1); } - + { _M_impl._Node_Alloc_type::deallocate(__p, 1); } + public: typedef _Alloc allocator_type; allocator_type get_allocator() const - { return allocator_type(*static_cast<const _Node_Alloc_type*>(this)); } + { return allocator_type(*static_cast<const _Node_Alloc_type*>(&this->_M_impl)); } _List_base(const allocator_type& __a) - : _Node_Alloc_type(__a) + : _M_impl(__a) { _M_init(); } // This is what actually destroys the list. @@ -326,8 +333,8 @@ namespace __gnu_norm void _M_init() { - this->_M_node._M_next = &this->_M_node; - this->_M_node._M_prev = &this->_M_node; + this->_M_impl._M_node._M_next = &this->_M_impl._M_node; + this->_M_impl._M_node._M_prev = &this->_M_impl._M_node; } }; @@ -409,7 +416,7 @@ namespace __gnu_norm * will also be included, accumulated from the topmost parent. * @endif */ - using _Base::_M_node; + using _Base::_M_impl; using _Base::_M_put_node; using _Base::_M_get_node; @@ -588,7 +595,7 @@ namespace __gnu_norm */ iterator begin() - { return this->_M_node._M_next; } + { return this->_M_impl._M_node._M_next; } /** * Returns a read-only (constant) iterator that points to the @@ -597,7 +604,7 @@ namespace __gnu_norm */ const_iterator begin() const - { return this->_M_node._M_next; } + { return this->_M_impl._M_node._M_next; } /** * Returns a read/write iterator that points one past the last @@ -605,7 +612,7 @@ namespace __gnu_norm * order. */ iterator - end() { return &this->_M_node; } + end() { return &this->_M_impl._M_node; } /** * Returns a read-only (constant) iterator that points one past @@ -614,7 +621,7 @@ namespace __gnu_norm */ const_iterator end() const - { return &this->_M_node; } + { return &this->_M_impl._M_node; } /** * Returns a read/write reverse iterator that points to the last @@ -659,7 +666,7 @@ namespace __gnu_norm */ bool empty() const - { return this->_M_node._M_next == &this->_M_node; } + { return this->_M_impl._M_node._M_next == &this->_M_impl._M_node; } /** Returns the number of elements in the %list. */ size_type @@ -788,7 +795,7 @@ namespace __gnu_norm */ void pop_back() - { this->_M_erase(this->_M_node._M_prev); } + { this->_M_erase(this->_M_impl._M_node._M_prev); } /** * @brief Inserts given value into %list before specified iterator. @@ -901,7 +908,7 @@ namespace __gnu_norm */ void swap(list& __x) - { _List_node_base::swap(this->_M_node,__x._M_node); } + { _List_node_base::swap(this->_M_impl._M_node,__x._M_impl._M_node); } /** * Erases all the elements. Note that this function only erases @@ -1064,7 +1071,7 @@ namespace __gnu_norm */ void reverse() - { this->_M_node.reverse(); } + { this->_M_impl._M_node.reverse(); } /** * @brief Sort the elements. diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h index 06048015b87..10adb6368be 100644 --- a/libstdc++-v3/include/bits/stl_vector.h +++ b/libstdc++-v3/include/bits/stl_vector.h @@ -74,40 +74,47 @@ namespace __gnu_norm */ template<typename _Tp, typename _Alloc> struct _Vector_base - : public _Alloc { + struct _Vector_impl + : public _Alloc { + _Tp* _M_start; + _Tp* _M_finish; + _Tp* _M_end_of_storage; + _Vector_impl (_Alloc const& __a) + : _Alloc(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0) + { } + }; + public: typedef _Alloc allocator_type; allocator_type - get_allocator() const { return *static_cast<const _Alloc*>(this); } + get_allocator() const { return *static_cast<const _Alloc*>(&this->_M_impl); } - _Vector_base(const allocator_type& __a) - : _Alloc(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0) { } + _Vector_base(const allocator_type& __a) : _M_impl(__a) + { } _Vector_base(size_t __n, const allocator_type& __a) - : _Alloc(__a) + : _M_impl(__a) { - this->_M_start = this->_M_allocate(__n); - this->_M_finish = this->_M_start; - this->_M_end_of_storage = this->_M_start + __n; + this->_M_impl._M_start = this->_M_allocate(__n); + this->_M_impl._M_finish = this->_M_impl._M_start; + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; } ~_Vector_base() - { _M_deallocate(this->_M_start, - this->_M_end_of_storage - this->_M_start); } + { _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage - this->_M_impl._M_start); } public: - _Tp* _M_start; - _Tp* _M_finish; - _Tp* _M_end_of_storage; + _Vector_impl _M_impl; _Tp* - _M_allocate(size_t __n) { return _Alloc::allocate(__n); } + _M_allocate(size_t __n) { return _M_impl.allocate(__n); } void _M_deallocate(_Tp* __p, size_t __n) - { if (__p) _Alloc::deallocate(__p, __n); } + { if (__p) _M_impl.deallocate(__p, __n); } }; @@ -162,9 +169,7 @@ namespace __gnu_norm */ using _Base::_M_allocate; using _Base::_M_deallocate; - using _Base::_M_start; - using _Base::_M_finish; - using _Base::_M_end_of_storage; + using _Base::_M_impl; public: // [23.2.4.1] construct/copy/destroy @@ -186,7 +191,7 @@ namespace __gnu_norm vector(size_type __n, const value_type& __value, const allocator_type& __a = allocator_type()) : _Base(__n, __a) - { this->_M_finish = std::uninitialized_fill_n(this->_M_start, + { this->_M_impl._M_finish = std::uninitialized_fill_n(this->_M_impl._M_start, __n, __value); } /** @@ -199,7 +204,7 @@ namespace __gnu_norm explicit vector(size_type __n) : _Base(__n, allocator_type()) - { this->_M_finish = std::uninitialized_fill_n(this->_M_start, + { this->_M_impl._M_finish = std::uninitialized_fill_n(this->_M_impl._M_start, __n, value_type()); } /** @@ -213,8 +218,8 @@ namespace __gnu_norm */ vector(const vector& __x) : _Base(__x.size(), __x.get_allocator()) - { this->_M_finish = std::uninitialized_copy(__x.begin(), __x.end(), - this->_M_start); + { this->_M_impl._M_finish = std::uninitialized_copy(__x.begin(), __x.end(), + this->_M_impl._M_start); } /** @@ -248,7 +253,7 @@ namespace __gnu_norm * not touched in any way. Managing the pointer is the user's * responsibilty. */ - ~vector() { std::_Destroy(this->_M_start, this->_M_finish); } + ~vector() { std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); } /** * @brief %Vector assignment operator. @@ -306,7 +311,7 @@ namespace __gnu_norm * element order. */ iterator - begin() { return iterator (this->_M_start); } + begin() { return iterator (this->_M_impl._M_start); } /** * Returns a read-only (constant) iterator that points to the @@ -314,7 +319,7 @@ namespace __gnu_norm * element order. */ const_iterator - begin() const { return const_iterator (this->_M_start); } + begin() const { return const_iterator (this->_M_impl._M_start); } /** * Returns a read/write iterator that points one past the last @@ -322,7 +327,7 @@ namespace __gnu_norm * element order. */ iterator - end() { return iterator (this->_M_finish); } + end() { return iterator (this->_M_impl._M_finish); } /** * Returns a read-only (constant) iterator that points one past @@ -330,7 +335,7 @@ namespace __gnu_norm * ordinary element order. */ const_iterator - end() const { return const_iterator (this->_M_finish); } + end() const { return const_iterator (this->_M_impl._M_finish); } /** * Returns a read/write reverse iterator that points to the @@ -412,7 +417,7 @@ namespace __gnu_norm */ size_type capacity() const - { return size_type(const_iterator(this->_M_end_of_storage) - begin()); } + { return size_type(const_iterator(this->_M_impl._M_end_of_storage) - begin()); } /** * Returns true if the %vector is empty. (Thus begin() would @@ -550,10 +555,10 @@ namespace __gnu_norm void push_back(const value_type& __x) { - if (this->_M_finish != this->_M_end_of_storage) + if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) { - std::_Construct(this->_M_finish, __x); - ++this->_M_finish; + std::_Construct(this->_M_impl._M_finish, __x); + ++this->_M_impl._M_finish; } else _M_insert_aux(end(), __x); @@ -571,8 +576,8 @@ namespace __gnu_norm void pop_back() { - --this->_M_finish; - std::_Destroy(this->_M_finish); + --this->_M_impl._M_finish; + std::_Destroy(this->_M_impl._M_finish); } /** @@ -681,9 +686,9 @@ namespace __gnu_norm void swap(vector& __x) { - std::swap(this->_M_start, __x._M_start); - std::swap(this->_M_finish, __x._M_finish); - std::swap(this->_M_end_of_storage, __x._M_end_of_storage); + std::swap(this->_M_impl._M_start, __x._M_impl._M_start); + std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); + std::swap(this->_M_impl._M_end_of_storage, __x._M_impl._M_end_of_storage); } /** @@ -728,9 +733,9 @@ namespace __gnu_norm void _M_initialize_dispatch(_Integer __n, _Integer __value, __true_type) { - this->_M_start = _M_allocate(__n); - this->_M_end_of_storage = this->_M_start + __n; - this->_M_finish = std::uninitialized_fill_n(this->_M_start, + this->_M_impl._M_start = _M_allocate(__n); + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; + this->_M_impl._M_finish = std::uninitialized_fill_n(this->_M_impl._M_start, __n, __value); } @@ -762,10 +767,10 @@ namespace __gnu_norm _ForwardIterator __last, forward_iterator_tag) { size_type __n = std::distance(__first, __last); - this->_M_start = this->_M_allocate(__n); - this->_M_end_of_storage = this->_M_start + __n; - this->_M_finish = std::uninitialized_copy(__first, __last, - this->_M_start); + this->_M_impl._M_start = this->_M_allocate(__n); + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; + this->_M_impl._M_finish = std::uninitialized_copy(__first, __last, + this->_M_impl._M_start); } diff --git a/libstdc++-v3/include/bits/vector.tcc b/libstdc++-v3/include/bits/vector.tcc index 207367cf59f..dd459a53431 100644 --- a/libstdc++-v3/include/bits/vector.tcc +++ b/libstdc++-v3/include/bits/vector.tcc @@ -74,14 +74,14 @@ namespace __gnu_norm { const size_type __old_size = size(); pointer __tmp = _M_allocate_and_copy(__n, - this->_M_start, - this->_M_finish); - std::_Destroy(this->_M_start, this->_M_finish); - _M_deallocate(this->_M_start, - this->_M_end_of_storage - this->_M_start); - this->_M_start = __tmp; - this->_M_finish = __tmp + __old_size; - this->_M_end_of_storage = this->_M_start + __n; + this->_M_impl._M_start, + this->_M_impl._M_finish); + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage - this->_M_impl._M_start); + this->_M_impl._M_start = __tmp; + this->_M_impl._M_finish = __tmp + __old_size; + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; } } @@ -91,10 +91,10 @@ namespace __gnu_norm insert(iterator __position, const value_type& __x) { size_type __n = __position - begin(); - if (this->_M_finish != this->_M_end_of_storage && __position == end()) + if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage && __position == end()) { - std::_Construct(this->_M_finish, __x); - ++this->_M_finish; + std::_Construct(this->_M_impl._M_finish, __x); + ++this->_M_impl._M_finish; } else _M_insert_aux(__position, __x); @@ -108,8 +108,8 @@ namespace __gnu_norm { if (__position + 1 != end()) std::copy(__position + 1, end(), __position); - --this->_M_finish; - std::_Destroy(this->_M_finish); + --this->_M_impl._M_finish; + std::_Destroy(this->_M_impl._M_finish); return __position; } @@ -120,7 +120,7 @@ namespace __gnu_norm { iterator __i(copy(__last, end(), __first)); std::_Destroy(__i, end()); - this->_M_finish = this->_M_finish - (__last - __first); + this->_M_impl._M_finish = this->_M_impl._M_finish - (__last - __first); return __first; } @@ -135,11 +135,11 @@ namespace __gnu_norm if (__xlen > capacity()) { pointer __tmp = _M_allocate_and_copy(__xlen, __x.begin(), __x.end()); - std::_Destroy(this->_M_start, this->_M_finish); - _M_deallocate(this->_M_start, - this->_M_end_of_storage - this->_M_start); - this->_M_start = __tmp; - this->_M_end_of_storage = this->_M_start + __xlen; + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage - this->_M_impl._M_start); + this->_M_impl._M_start = __tmp; + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __xlen; } else if (size() >= __xlen) { @@ -148,10 +148,10 @@ namespace __gnu_norm } else { - std::copy(__x.begin(), __x.begin() + size(), this->_M_start); - std::uninitialized_copy(__x.begin() + size(), __x.end(), this->_M_finish); + std::copy(__x.begin(), __x.begin() + size(), this->_M_impl._M_start); + std::uninitialized_copy(__x.begin() + size(), __x.end(), this->_M_impl._M_finish); } - this->_M_finish = this->_M_start + __xlen; + this->_M_impl._M_finish = this->_M_impl._M_start + __xlen; } return *this; } @@ -169,8 +169,8 @@ namespace __gnu_norm else if (__n > size()) { std::fill(begin(), end(), __val); - this->_M_finish - = std::uninitialized_fill_n(this->_M_finish, __n - size(), __val); + this->_M_impl._M_finish + = std::uninitialized_fill_n(this->_M_impl._M_finish, __n - size(), __val); } else erase(fill_n(begin(), __n, __val), end()); @@ -201,24 +201,24 @@ namespace __gnu_norm if (__len > capacity()) { pointer __tmp(_M_allocate_and_copy(__len, __first, __last)); - std::_Destroy(this->_M_start, this->_M_finish); - _M_deallocate(this->_M_start, - this->_M_end_of_storage - this->_M_start); - this->_M_start = __tmp; - this->_M_end_of_storage = this->_M_finish = this->_M_start + __len; + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage - this->_M_impl._M_start); + this->_M_impl._M_start = __tmp; + this->_M_impl._M_end_of_storage = this->_M_impl._M_finish = this->_M_impl._M_start + __len; } else if (size() >= __len) { - iterator __new_finish(copy(__first, __last, this->_M_start)); + iterator __new_finish(copy(__first, __last, this->_M_impl._M_start)); std::_Destroy(__new_finish, end()); - this->_M_finish = __new_finish.base(); + this->_M_impl._M_finish = __new_finish.base(); } else { _ForwardIterator __mid = __first; std::advance(__mid, size()); - std::copy(__first, __mid, this->_M_start); - this->_M_finish = std::uninitialized_copy(__mid, __last, this->_M_finish); + std::copy(__first, __mid, this->_M_impl._M_start); + this->_M_impl._M_finish = std::uninitialized_copy(__mid, __last, this->_M_impl._M_finish); } } @@ -227,14 +227,14 @@ namespace __gnu_norm vector<_Tp,_Alloc>:: _M_insert_aux(iterator __position, const _Tp& __x) { - if (this->_M_finish != this->_M_end_of_storage) + if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) { - std::_Construct(this->_M_finish, *(this->_M_finish - 1)); - ++this->_M_finish; + std::_Construct(this->_M_impl._M_finish, *(this->_M_impl._M_finish - 1)); + ++this->_M_impl._M_finish; _Tp __x_copy = __x; std::copy_backward(__position, - iterator(this->_M_finish-2), - iterator(this->_M_finish-1)); + iterator(this->_M_impl._M_finish-2), + iterator(this->_M_impl._M_finish-1)); *__position = __x_copy; } else @@ -245,13 +245,13 @@ namespace __gnu_norm iterator __new_finish(__new_start); try { - __new_finish = std::uninitialized_copy(iterator(this->_M_start), + __new_finish = std::uninitialized_copy(iterator(this->_M_impl._M_start), __position, __new_start); std::_Construct(__new_finish.base(), __x); ++__new_finish; __new_finish = std::uninitialized_copy(__position, - iterator(this->_M_finish), + iterator(this->_M_impl._M_finish), __new_finish); } catch(...) @@ -261,11 +261,11 @@ namespace __gnu_norm __throw_exception_again; } std::_Destroy(begin(), end()); - _M_deallocate(this->_M_start, - this->_M_end_of_storage - this->_M_start); - this->_M_start = __new_start.base(); - this->_M_finish = __new_finish.base(); - this->_M_end_of_storage = __new_start.base() + __len; + _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; } } @@ -276,28 +276,28 @@ namespace __gnu_norm { if (__n != 0) { - if (size_type(this->_M_end_of_storage - this->_M_finish) >= __n) + if (size_type(this->_M_impl._M_end_of_storage - this->_M_impl._M_finish) >= __n) { value_type __x_copy = __x; const size_type __elems_after = end() - __position; - iterator __old_finish(this->_M_finish); + iterator __old_finish(this->_M_impl._M_finish); if (__elems_after > __n) { - std::uninitialized_copy(this->_M_finish - __n, - this->_M_finish, - this->_M_finish); - this->_M_finish += __n; + std::uninitialized_copy(this->_M_impl._M_finish - __n, + this->_M_impl._M_finish, + this->_M_impl._M_finish); + this->_M_impl._M_finish += __n; std::copy_backward(__position, __old_finish - __n, __old_finish); std::fill(__position, __position + __n, __x_copy); } else { - std::uninitialized_fill_n(this->_M_finish, + std::uninitialized_fill_n(this->_M_impl._M_finish, __n - __elems_after, __x_copy); - this->_M_finish += __n - __elems_after; - std::uninitialized_copy(__position, __old_finish, this->_M_finish); - this->_M_finish += __elems_after; + this->_M_impl._M_finish += __n - __elems_after; + std::uninitialized_copy(__position, __old_finish, this->_M_impl._M_finish); + this->_M_impl._M_finish += __elems_after; std::fill(__position, __old_finish, __x_copy); } } @@ -321,12 +321,12 @@ namespace __gnu_norm _M_deallocate(__new_start.base(),__len); __throw_exception_again; } - std::_Destroy(this->_M_start, this->_M_finish); - _M_deallocate(this->_M_start, - this->_M_end_of_storage - this->_M_start); - this->_M_start = __new_start.base(); - this->_M_finish = __new_finish.base(); - this->_M_end_of_storage = __new_start.base() + __len; + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); + _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; } } } @@ -354,16 +354,16 @@ namespace __gnu_norm if (__first != __last) { size_type __n = std::distance(__first, __last); - if (size_type(this->_M_end_of_storage - this->_M_finish) >= __n) + if (size_type(this->_M_impl._M_end_of_storage - this->_M_impl._M_finish) >= __n) { const size_type __elems_after = end() - __position; - iterator __old_finish(this->_M_finish); + iterator __old_finish(this->_M_impl._M_finish); if (__elems_after > __n) { - std::uninitialized_copy(this->_M_finish - __n, - this->_M_finish, - this->_M_finish); - this->_M_finish += __n; + std::uninitialized_copy(this->_M_impl._M_finish - __n, + this->_M_impl._M_finish, + this->_M_impl._M_finish); + this->_M_impl._M_finish += __n; std::copy_backward(__position, __old_finish - __n, __old_finish); std::copy(__first, __last, __position); } @@ -371,10 +371,10 @@ namespace __gnu_norm { _ForwardIterator __mid = __first; std::advance(__mid, __elems_after); - std::uninitialized_copy(__mid, __last, this->_M_finish); - this->_M_finish += __n - __elems_after; - std::uninitialized_copy(__position, __old_finish, this->_M_finish); - this->_M_finish += __elems_after; + std::uninitialized_copy(__mid, __last, this->_M_impl._M_finish); + this->_M_impl._M_finish += __n - __elems_after; + std::uninitialized_copy(__position, __old_finish, this->_M_impl._M_finish); + this->_M_impl._M_finish += __elems_after; std::copy(__first, __mid, __position); } } @@ -386,12 +386,12 @@ namespace __gnu_norm iterator __new_finish(__new_start); try { - __new_finish = std::uninitialized_copy(iterator(this->_M_start), + __new_finish = std::uninitialized_copy(iterator(this->_M_impl._M_start), __position, __new_start); __new_finish = std::uninitialized_copy(__first, __last, __new_finish); __new_finish = std::uninitialized_copy(__position, - iterator(this->_M_finish), + iterator(this->_M_impl._M_finish), __new_finish); } catch(...) @@ -400,12 +400,12 @@ namespace __gnu_norm _M_deallocate(__new_start.base(), __len); __throw_exception_again; } - std::_Destroy(this->_M_start, this->_M_finish); - _M_deallocate(this->_M_start, - this->_M_end_of_storage - this->_M_start); - this->_M_start = __new_start.base(); - this->_M_finish = __new_finish.base(); - this->_M_end_of_storage = __new_start.base() + __len; + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); + _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; } } } diff --git a/libstdc++-v3/testsuite/23_containers/deque/cons/clear_allocator.cc b/libstdc++-v3/testsuite/23_containers/deque/cons/clear_allocator.cc new file mode 100644 index 00000000000..8103928a1e3 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/deque/cons/clear_allocator.cc @@ -0,0 +1,88 @@ +// Copyright (C) 2004 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +#include <deque> +#include <ext/new_allocator.h> + +using namespace std; +using __gnu_cxx::new_allocator; + +template<typename T> + class clear_alloc : public new_allocator<T> + { + public: + + template <typename T1> + struct rebind + { typedef clear_alloc<T1> other; }; + + virtual void clear() + { } + + clear_alloc() + { } + + clear_alloc(clear_alloc const& _wa) + { } + + template<typename T1> + clear_alloc(clear_alloc<T1> const& _wa) + { } + + virtual ~clear_alloc() + { this->clear(); } + + T* allocate(typename new_allocator<T>::size_type n, const void *hint = 0) + { + this->clear(); + return new_allocator<T>::allocate(n, hint); + } + + void deallocate(T *ptr, typename new_allocator<T>::size_type n) + { + this->clear(); + new_allocator<T>::deallocate(ptr, n); + } + }; + +template<typename Container> + void Check_Container() + { + Container* pic = new Container; + int x = 230; + + while (x--) + { + pic->push_back(x); + } + + pic->get_allocator(); + + // The following has led to infinite recursions or cores. + pic->clear(); + + delete pic; + } + + +int main() +{ + Check_Container<std::deque<int, clear_alloc<int> > >(); + return 0; +} + diff --git a/libstdc++-v3/testsuite/23_containers/list/cons/clear_allocator.cc b/libstdc++-v3/testsuite/23_containers/list/cons/clear_allocator.cc new file mode 100644 index 00000000000..c74fc085ffb --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/list/cons/clear_allocator.cc @@ -0,0 +1,88 @@ +// Copyright (C) 2004 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +#include <list> +#include <ext/new_allocator.h> + +using namespace std; +using __gnu_cxx::new_allocator; + +template<typename T> + class clear_alloc : public new_allocator<T> + { + public: + + template <typename T1> + struct rebind + { typedef clear_alloc<T1> other; }; + + virtual void clear() + { } + + clear_alloc() + { } + + clear_alloc(clear_alloc const& _wa) + { } + + template<typename T1> + clear_alloc(clear_alloc<T1> const& _wa) + { } + + virtual ~clear_alloc() + { this->clear(); } + + T* allocate(typename new_allocator<T>::size_type n, const void *hint = 0) + { + this->clear(); + return new_allocator<T>::allocate(n, hint); + } + + void deallocate(T *ptr, typename new_allocator<T>::size_type n) + { + this->clear(); + new_allocator<T>::deallocate(ptr, n); + } + }; + +template<typename Container> + void Check_Container() + { + Container* pic = new Container; + int x = 230; + + while (x--) + { + pic->push_back(x); + } + + pic->get_allocator(); + + // The following has led to infinite recursions or cores. + pic->clear(); + + delete pic; + } + + +int main() +{ + Check_Container<std::list<int, clear_alloc<int> > >(); + return 0; +} + diff --git a/libstdc++-v3/testsuite/23_containers/vector/cons/clear_allocator.cc b/libstdc++-v3/testsuite/23_containers/vector/cons/clear_allocator.cc new file mode 100644 index 00000000000..5cc878e6c59 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/cons/clear_allocator.cc @@ -0,0 +1,88 @@ +// Copyright (C) 2004 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +#include <vector> +#include <ext/new_allocator.h> + +using namespace std; +using __gnu_cxx::new_allocator; + +template<typename T> + class clear_alloc : public new_allocator<T> + { + public: + + template <typename T1> + struct rebind + { typedef clear_alloc<T1> other; }; + + virtual void clear() + { } + + clear_alloc() + { } + + clear_alloc(clear_alloc const& _wa) + { } + + template<typename T1> + clear_alloc(clear_alloc<T1> const& _wa) + { } + + virtual ~clear_alloc() + { this->clear(); } + + T* allocate(typename new_allocator<T>::size_type n, const void *hint = 0) + { + this->clear(); + return new_allocator<T>::allocate(n, hint); + } + + void deallocate(T *ptr, typename new_allocator<T>::size_type n) + { + this->clear(); + new_allocator<T>::deallocate(ptr, n); + } + }; + +template<typename Container> + void Check_Container() + { + Container* pic = new Container; + int x = 230; + + while (x--) + { + pic->push_back(x); + } + + pic->get_allocator(); + + // The following has led to infinite recursions or cores. + pic->clear(); + + delete pic; + } + + +int main() +{ + Check_Container<std::vector<int, clear_alloc<int> > >(); + return 0; +} + |