Commit 03f9ea44 by Dhruv Matani Committed by Benjamin Kosnik

stl_list.h: Created a _List_impl class and made it derive from the allocator...


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.

From-SVN: r79957
parent 666c27b9
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> 2004-03-24 Dhruv Matani <dhruvbird@gmx.net>
* ext/malloc_allocator.h: Fixed the construct function to call * include/ext/malloc_allocator.h: Fixed the construct function to
global placement new instead of assignment. Added a check after call global placement new instead of assignment. Added a check
the return from malloc to check whether returned pointer is NULL, after the return from malloc to check whether returned pointer is
and if so, throw std::bad_alloc(). NULL, and if so, throw std::bad_alloc().
* ext/debug_allocator.h: Added a check in the deallocate function * include/ext/debug_allocator.h: Added a check in the deallocate
to check whether the user has passed a NULL pointer or not. function to check whether the user has passed a NULL pointer or
not.
2004-03-24 Benjamin Kosnik <bkoz@redhat.com> 2004-03-24 Benjamin Kosnik <bkoz@redhat.com>
......
...@@ -72,13 +72,13 @@ namespace __gnu_norm ...@@ -72,13 +72,13 @@ namespace __gnu_norm
if (&__x != this) if (&__x != this)
{ {
if (__len >= __x.size()) if (__len >= __x.size())
erase(std::copy(__x.begin(), __x.end(), this->_M_start), erase(std::copy(__x.begin(), __x.end(), this->_M_impl._M_start),
this->_M_finish); this->_M_impl._M_finish);
else else
{ {
const_iterator __mid = __x.begin() + difference_type(__len); const_iterator __mid = __x.begin() + difference_type(__len);
std::copy(__x.begin(), __mid, this->_M_start); std::copy(__x.begin(), __mid, this->_M_impl._M_start);
insert(this->_M_finish, __mid, __x.end()); insert(this->_M_impl._M_finish, __mid, __x.end());
} }
} }
return *this; return *this;
...@@ -89,15 +89,15 @@ namespace __gnu_norm ...@@ -89,15 +89,15 @@ namespace __gnu_norm
deque<_Tp,_Alloc>:: deque<_Tp,_Alloc>::
insert(iterator position, const value_type& __x) 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); 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); push_back(__x);
iterator __tmp = this->_M_finish; iterator __tmp = this->_M_impl._M_finish;
--__tmp; --__tmp;
return __tmp; return __tmp;
} }
...@@ -112,18 +112,18 @@ namespace __gnu_norm ...@@ -112,18 +112,18 @@ namespace __gnu_norm
{ {
iterator __next = __position; iterator __next = __position;
++__next; ++__next;
size_type __index = __position - this->_M_start; size_type __index = __position - this->_M_impl._M_start;
if (__index < (size() >> 1)) if (__index < (size() >> 1))
{ {
std::copy_backward(this->_M_start, __position, __next); std::copy_backward(this->_M_impl._M_start, __position, __next);
pop_front(); pop_front();
} }
else else
{ {
std::copy(__next, this->_M_finish, __position); std::copy(__next, this->_M_impl._M_finish, __position);
pop_back(); pop_back();
} }
return this->_M_start + __index; return this->_M_impl._M_start + __index;
} }
template <typename _Tp, typename _Alloc> template <typename _Tp, typename _Alloc>
...@@ -131,33 +131,33 @@ namespace __gnu_norm ...@@ -131,33 +131,33 @@ namespace __gnu_norm
deque<_Tp,_Alloc>:: deque<_Tp,_Alloc>::
erase(iterator __first, iterator __last) 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(); clear();
return this->_M_finish; return this->_M_impl._M_finish;
} }
else else
{ {
const difference_type __n = __last - __first; 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) if (static_cast<size_type>(__elems_before) < (size() - __n) / 2)
{ {
std::copy_backward(this->_M_start, __first, __last); std::copy_backward(this->_M_impl._M_start, __first, __last);
iterator __new_start = this->_M_start + __n; iterator __new_start = this->_M_impl._M_start + __n;
std::_Destroy(this->_M_start, __new_start); std::_Destroy(this->_M_impl._M_start, __new_start);
_M_destroy_nodes(this->_M_start._M_node, __new_start._M_node); _M_destroy_nodes(this->_M_impl._M_start._M_node, __new_start._M_node);
this->_M_start = __new_start; this->_M_impl._M_start = __new_start;
} }
else else
{ {
std::copy(__last, this->_M_finish, __first); std::copy(__last, this->_M_impl._M_finish, __first);
iterator __new_finish = this->_M_finish - __n; iterator __new_finish = this->_M_impl._M_finish - __n;
std::_Destroy(__new_finish, this->_M_finish); std::_Destroy(__new_finish, this->_M_impl._M_finish);
_M_destroy_nodes(__new_finish._M_node + 1, _M_destroy_nodes(__new_finish._M_node + 1,
this->_M_finish._M_node + 1); this->_M_impl._M_finish._M_node + 1);
this->_M_finish = __new_finish; 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 ...@@ -166,24 +166,24 @@ namespace __gnu_norm
deque<_Tp,_Alloc>:: deque<_Tp,_Alloc>::
clear() clear()
{ {
for (_Map_pointer __node = this->_M_start._M_node + 1; for (_Map_pointer __node = this->_M_impl._M_start._M_node + 1;
__node < this->_M_finish._M_node; __node < this->_M_impl._M_finish._M_node;
++__node) ++__node)
{ {
std::_Destroy(*__node, *__node + _S_buffer_size()); std::_Destroy(*__node, *__node + _S_buffer_size());
_M_deallocate_node(*__node); _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_impl._M_start._M_cur, this->_M_impl._M_start._M_last);
std::_Destroy(this->_M_finish._M_first, this->_M_finish._M_cur); std::_Destroy(this->_M_impl._M_finish._M_first, this->_M_impl._M_finish._M_cur);
_M_deallocate_node(this->_M_finish._M_first); _M_deallocate_node(this->_M_impl._M_finish._M_first);
} }
else 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> template <typename _Tp, class _Alloc>
...@@ -207,31 +207,31 @@ namespace __gnu_norm ...@@ -207,31 +207,31 @@ namespace __gnu_norm
deque<_Tp,_Alloc>:: deque<_Tp,_Alloc>::
_M_fill_insert(iterator __pos, size_type __n, const value_type& __x) _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); iterator __new_start = _M_reserve_elements_at_front(__n);
try try
{ {
std::uninitialized_fill(__new_start, this->_M_start, __x); std::uninitialized_fill(__new_start, this->_M_impl._M_start, __x);
this->_M_start = __new_start; this->_M_impl._M_start = __new_start;
} }
catch(...) 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; __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); iterator __new_finish = _M_reserve_elements_at_back(__n);
try try
{ {
std::uninitialized_fill(this->_M_finish, __new_finish, __x); std::uninitialized_fill(this->_M_impl._M_finish, __new_finish, __x);
this->_M_finish = __new_finish; this->_M_impl._M_finish = __new_finish;
} }
catch(...) 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); __new_finish._M_node + 1);
__throw_exception_again; __throw_exception_again;
} }
...@@ -248,17 +248,17 @@ namespace __gnu_norm ...@@ -248,17 +248,17 @@ namespace __gnu_norm
_Map_pointer __cur; _Map_pointer __cur;
try try
{ {
for (__cur = this->_M_start._M_node; for (__cur = this->_M_impl._M_start._M_node;
__cur < this->_M_finish._M_node; __cur < this->_M_impl._M_finish._M_node;
++__cur) ++__cur)
std::uninitialized_fill(*__cur, *__cur + _S_buffer_size(), __value); std::uninitialized_fill(*__cur, *__cur + _S_buffer_size(), __value);
std::uninitialized_fill(this->_M_finish._M_first, std::uninitialized_fill(this->_M_impl._M_finish._M_first,
this->_M_finish._M_cur, this->_M_impl._M_finish._M_cur,
__value); __value);
} }
catch(...) catch(...)
{ {
std::_Destroy(this->_M_start, iterator(*__cur, __cur)); std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur));
__throw_exception_again; __throw_exception_again;
} }
} }
...@@ -296,8 +296,8 @@ namespace __gnu_norm ...@@ -296,8 +296,8 @@ namespace __gnu_norm
_Map_pointer __cur_node; _Map_pointer __cur_node;
try try
{ {
for (__cur_node = this->_M_start._M_node; for (__cur_node = this->_M_impl._M_start._M_node;
__cur_node < this->_M_finish._M_node; __cur_node < this->_M_impl._M_finish._M_node;
++__cur_node) ++__cur_node)
{ {
_ForwardIterator __mid = __first; _ForwardIterator __mid = __first;
...@@ -305,16 +305,16 @@ namespace __gnu_norm ...@@ -305,16 +305,16 @@ namespace __gnu_norm
std::uninitialized_copy(__first, __mid, *__cur_node); std::uninitialized_copy(__first, __mid, *__cur_node);
__first = __mid; __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(...) 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; __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> template <typename _Tp, typename _Alloc>
void void
deque<_Tp,_Alloc>:: deque<_Tp,_Alloc>::
...@@ -322,21 +322,21 @@ namespace __gnu_norm ...@@ -322,21 +322,21 @@ namespace __gnu_norm
{ {
value_type __t_copy = __t; value_type __t_copy = __t;
_M_reserve_map_at_back(); _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 try
{ {
std::_Construct(this->_M_finish._M_cur, __t_copy); std::_Construct(this->_M_impl._M_finish._M_cur, __t_copy);
this->_M_finish._M_set_node(this->_M_finish._M_node + 1); this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node + 1);
this->_M_finish._M_cur = this->_M_finish._M_first; this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first;
} }
catch(...) catch(...)
{ {
_M_deallocate_node(*(this->_M_finish._M_node + 1)); _M_deallocate_node(*(this->_M_impl._M_finish._M_node + 1));
__throw_exception_again; __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> template <typename _Tp, typename _Alloc>
void void
deque<_Tp,_Alloc>:: deque<_Tp,_Alloc>::
...@@ -344,44 +344,44 @@ namespace __gnu_norm ...@@ -344,44 +344,44 @@ namespace __gnu_norm
{ {
value_type __t_copy = __t; value_type __t_copy = __t;
_M_reserve_map_at_front(); _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 try
{ {
this->_M_start._M_set_node(this->_M_start._M_node - 1); this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node - 1);
this->_M_start._M_cur = this->_M_start._M_last - 1; this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_last - 1;
std::_Construct(this->_M_start._M_cur, __t_copy); std::_Construct(this->_M_impl._M_start._M_cur, __t_copy);
} }
catch(...) catch(...)
{ {
++this->_M_start; ++this->_M_impl._M_start;
_M_deallocate_node(*(this->_M_start._M_node - 1)); _M_deallocate_node(*(this->_M_impl._M_start._M_node - 1));
__throw_exception_again; __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> template <typename _Tp, typename _Alloc>
void deque<_Tp,_Alloc>:: void deque<_Tp,_Alloc>::
_M_pop_back_aux() _M_pop_back_aux()
{ {
_M_deallocate_node(this->_M_finish._M_first); _M_deallocate_node(this->_M_impl._M_finish._M_first);
this->_M_finish._M_set_node(this->_M_finish._M_node - 1); this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node - 1);
this->_M_finish._M_cur = this->_M_finish._M_last - 1; this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_last - 1;
std::_Destroy(this->_M_finish._M_cur); 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 // 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. // must have at least two nodes.
template <typename _Tp, typename _Alloc> template <typename _Tp, typename _Alloc>
void deque<_Tp,_Alloc>:: void deque<_Tp,_Alloc>::
_M_pop_front_aux() _M_pop_front_aux()
{ {
std::_Destroy(this->_M_start._M_cur); std::_Destroy(this->_M_impl._M_start._M_cur);
_M_deallocate_node(this->_M_start._M_first); _M_deallocate_node(this->_M_impl._M_start._M_first);
this->_M_start._M_set_node(this->_M_start._M_node + 1); this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node + 1);
this->_M_start._M_cur = this->_M_start._M_first; this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_first;
} }
template <typename _Tp, typename _Alloc> template <typename _Tp, typename _Alloc>
...@@ -402,31 +402,31 @@ namespace __gnu_norm ...@@ -402,31 +402,31 @@ namespace __gnu_norm
forward_iterator_tag) forward_iterator_tag)
{ {
size_type __n = std::distance(__first, __last); 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); iterator __new_start = _M_reserve_elements_at_front(__n);
try try
{ {
std::uninitialized_copy(__first, __last, __new_start); std::uninitialized_copy(__first, __last, __new_start);
this->_M_start = __new_start; this->_M_impl._M_start = __new_start;
} }
catch(...) 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; __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); iterator __new_finish = _M_reserve_elements_at_back(__n);
try try
{ {
std::uninitialized_copy(__first, __last, this->_M_finish); std::uninitialized_copy(__first, __last, this->_M_impl._M_finish);
this->_M_finish = __new_finish; this->_M_impl._M_finish = __new_finish;
} }
catch(...) 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); __new_finish._M_node + 1);
__throw_exception_again; __throw_exception_again;
} }
...@@ -440,16 +440,16 @@ namespace __gnu_norm ...@@ -440,16 +440,16 @@ namespace __gnu_norm
deque<_Tp,_Alloc>:: deque<_Tp,_Alloc>::
_M_insert_aux(iterator __pos, const value_type& __x) _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 value_type __x_copy = __x; // XXX copy
if (static_cast<size_type>(__index) < size() / 2) if (static_cast<size_type>(__index) < size() / 2)
{ {
push_front(front()); push_front(front());
iterator __front1 = this->_M_start; iterator __front1 = this->_M_impl._M_start;
++__front1; ++__front1;
iterator __front2 = __front1; iterator __front2 = __front1;
++__front2; ++__front2;
__pos = this->_M_start + __index; __pos = this->_M_impl._M_start + __index;
iterator __pos1 = __pos; iterator __pos1 = __pos;
++__pos1; ++__pos1;
std::copy(__front2, __pos1, __front1); std::copy(__front2, __pos1, __front1);
...@@ -457,11 +457,11 @@ namespace __gnu_norm ...@@ -457,11 +457,11 @@ namespace __gnu_norm
else else
{ {
push_back(back()); push_back(back());
iterator __back1 = this->_M_finish; iterator __back1 = this->_M_impl._M_finish;
--__back1; --__back1;
iterator __back2 = __back1; iterator __back2 = __back1;
--__back2; --__back2;
__pos = this->_M_start + __index; __pos = this->_M_impl._M_start + __index;
std::copy_backward(__pos, __back2, __back1); std::copy_backward(__pos, __back2, __back1);
} }
*__pos = __x_copy; *__pos = __x_copy;
...@@ -473,71 +473,71 @@ namespace __gnu_norm ...@@ -473,71 +473,71 @@ namespace __gnu_norm
deque<_Tp,_Alloc>:: deque<_Tp,_Alloc>::
_M_insert_aux(iterator __pos, size_type __n, const value_type& __x) _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(); size_type __length = this->size();
value_type __x_copy = __x; value_type __x_copy = __x;
if (__elems_before < difference_type(__length / 2)) if (__elems_before < difference_type(__length / 2))
{ {
iterator __new_start = _M_reserve_elements_at_front(__n); iterator __new_start = _M_reserve_elements_at_front(__n);
iterator __old_start = this->_M_start; iterator __old_start = this->_M_impl._M_start;
__pos = this->_M_start + __elems_before; __pos = this->_M_impl._M_start + __elems_before;
try try
{ {
if (__elems_before >= difference_type(__n)) if (__elems_before >= difference_type(__n))
{ {
iterator __start_n = this->_M_start + difference_type(__n); iterator __start_n = this->_M_impl._M_start + difference_type(__n);
std::uninitialized_copy(this->_M_start, __start_n, std::uninitialized_copy(this->_M_impl._M_start, __start_n,
__new_start); __new_start);
this->_M_start = __new_start; this->_M_impl._M_start = __new_start;
std::copy(__start_n, __pos, __old_start); std::copy(__start_n, __pos, __old_start);
fill(__pos - difference_type(__n), __pos, __x_copy); fill(__pos - difference_type(__n), __pos, __x_copy);
} }
else else
{ {
std::__uninitialized_copy_fill(this->_M_start, __pos, std::__uninitialized_copy_fill(this->_M_impl._M_start, __pos,
__new_start, __new_start,
this->_M_start, __x_copy); this->_M_impl._M_start, __x_copy);
this->_M_start = __new_start; this->_M_impl._M_start = __new_start;
std::fill(__old_start, __pos, __x_copy); std::fill(__old_start, __pos, __x_copy);
} }
} }
catch(...) 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; __throw_exception_again;
} }
} }
else else
{ {
iterator __new_finish = _M_reserve_elements_at_back(__n); 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 = const difference_type __elems_after =
difference_type(__length) - __elems_before; difference_type(__length) - __elems_before;
__pos = this->_M_finish - __elems_after; __pos = this->_M_impl._M_finish - __elems_after;
try try
{ {
if (__elems_after > difference_type(__n)) if (__elems_after > 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, std::uninitialized_copy(__finish_n, this->_M_impl._M_finish,
this->_M_finish); this->_M_impl._M_finish);
this->_M_finish = __new_finish; this->_M_impl._M_finish = __new_finish;
std::copy_backward(__pos, __finish_n, __old_finish); std::copy_backward(__pos, __finish_n, __old_finish);
std::fill(__pos, __pos + difference_type(__n), __x_copy); std::fill(__pos, __pos + difference_type(__n), __x_copy);
} }
else else
{ {
std::__uninitialized_fill_copy(this->_M_finish, std::__uninitialized_fill_copy(this->_M_impl._M_finish,
__pos + difference_type(__n), __pos + difference_type(__n),
__x_copy, __pos, __x_copy, __pos,
this->_M_finish); this->_M_impl._M_finish);
this->_M_finish = __new_finish; this->_M_impl._M_finish = __new_finish;
std::fill(__pos, __old_finish, __x_copy); std::fill(__pos, __old_finish, __x_copy);
} }
} }
catch(...) 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); __new_finish._M_node + 1);
__throw_exception_again; __throw_exception_again;
} }
...@@ -552,21 +552,21 @@ namespace __gnu_norm ...@@ -552,21 +552,21 @@ namespace __gnu_norm
_ForwardIterator __first, _ForwardIterator __last, _ForwardIterator __first, _ForwardIterator __last,
size_type __n) 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(); size_type __length = size();
if (static_cast<size_type>(__elemsbefore) < __length / 2) if (static_cast<size_type>(__elemsbefore) < __length / 2)
{ {
iterator __new_start = _M_reserve_elements_at_front(__n); iterator __new_start = _M_reserve_elements_at_front(__n);
iterator __old_start = this->_M_start; iterator __old_start = this->_M_impl._M_start;
__pos = this->_M_start + __elemsbefore; __pos = this->_M_impl._M_start + __elemsbefore;
try try
{ {
if (__elemsbefore >= difference_type(__n)) if (__elemsbefore >= difference_type(__n))
{ {
iterator __start_n = this->_M_start + difference_type(__n); iterator __start_n = this->_M_impl._M_start + difference_type(__n);
std::uninitialized_copy(this->_M_start, __start_n, std::uninitialized_copy(this->_M_impl._M_start, __start_n,
__new_start); __new_start);
this->_M_start = __new_start; this->_M_impl._M_start = __new_start;
std::copy(__start_n, __pos, __old_start); std::copy(__start_n, __pos, __old_start);
std::copy(__first, __last, __pos - difference_type(__n)); std::copy(__first, __last, __pos - difference_type(__n));
} }
...@@ -574,34 +574,34 @@ namespace __gnu_norm ...@@ -574,34 +574,34 @@ namespace __gnu_norm
{ {
_ForwardIterator __mid = __first; _ForwardIterator __mid = __first;
std::advance(__mid, difference_type(__n) - __elemsbefore); 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); __first, __mid, __new_start);
this->_M_start = __new_start; this->_M_impl._M_start = __new_start;
std::copy(__mid, __last, __old_start); std::copy(__mid, __last, __old_start);
} }
} }
catch(...) 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; __throw_exception_again;
} }
} }
else else
{ {
iterator __new_finish = _M_reserve_elements_at_back(__n); 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 = const difference_type __elemsafter =
difference_type(__length) - __elemsbefore; difference_type(__length) - __elemsbefore;
__pos = this->_M_finish - __elemsafter; __pos = this->_M_impl._M_finish - __elemsafter;
try try
{ {
if (__elemsafter > difference_type(__n)) 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, std::uninitialized_copy(__finish_n,
this->_M_finish, this->_M_impl._M_finish,
this->_M_finish); this->_M_impl._M_finish);
this->_M_finish = __new_finish; this->_M_impl._M_finish = __new_finish;
std::copy_backward(__pos, __finish_n, __old_finish); std::copy_backward(__pos, __finish_n, __old_finish);
std::copy(__first, __last, __pos); std::copy(__first, __last, __pos);
} }
...@@ -610,15 +610,15 @@ namespace __gnu_norm ...@@ -610,15 +610,15 @@ namespace __gnu_norm
_ForwardIterator __mid = __first; _ForwardIterator __mid = __first;
std::advance(__mid, __elemsafter); std::advance(__mid, __elemsafter);
std::__uninitialized_copy_copy(__mid, __last, __pos, std::__uninitialized_copy_copy(__mid, __last, __pos,
this->_M_finish, this->_M_impl._M_finish,
this->_M_finish); this->_M_impl._M_finish);
this->_M_finish = __new_finish; this->_M_impl._M_finish = __new_finish;
std::copy(__first, __mid, __pos); std::copy(__first, __mid, __pos);
} }
} }
catch(...) 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); __new_finish._M_node + 1);
__throw_exception_again; __throw_exception_again;
} }
...@@ -637,12 +637,12 @@ namespace __gnu_norm ...@@ -637,12 +637,12 @@ namespace __gnu_norm
try try
{ {
for (__i = 1; __i <= __new_nodes; ++__i) 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(...) catch(...)
{ {
for (size_type __j = 1; __j < __i; ++__j) 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; __throw_exception_again;
} }
} }
...@@ -659,12 +659,12 @@ namespace __gnu_norm ...@@ -659,12 +659,12 @@ namespace __gnu_norm
try try
{ {
for (__i = 1; __i <= __new_nodes; ++__i) 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(...) catch(...)
{ {
for (size_type __j = 1; __j < __i; ++__j) 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; __throw_exception_again;
} }
} }
...@@ -675,44 +675,44 @@ namespace __gnu_norm ...@@ -675,44 +675,44 @@ namespace __gnu_norm
_M_reallocate_map(size_type __nodes_to_add, bool __add_at_front) _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front)
{ {
size_type __old_num_nodes 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; size_type __new_num_nodes = __old_num_nodes + __nodes_to_add;
_Map_pointer __new_nstart; _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 - __new_num_nodes) / 2
+ (__add_at_front ? __nodes_to_add : 0); + (__add_at_front ? __nodes_to_add : 0);
if (__new_nstart < this->_M_start._M_node) if (__new_nstart < this->_M_impl._M_start._M_node)
std::copy(this->_M_start._M_node, std::copy(this->_M_impl._M_start._M_node,
this->_M_finish._M_node + 1, this->_M_impl._M_finish._M_node + 1,
__new_nstart); __new_nstart);
else else
std::copy_backward(this->_M_start._M_node, std::copy_backward(this->_M_impl._M_start._M_node,
this->_M_finish._M_node + 1, this->_M_impl._M_finish._M_node + 1,
__new_nstart + __old_num_nodes); __new_nstart + __old_num_nodes);
} }
else else
{ {
size_type __new_map_size = this->_M_map_size size_type __new_map_size = this->_M_impl._M_map_size
+ std::max(this->_M_map_size, + std::max(this->_M_impl._M_map_size,
__nodes_to_add) + 2; __nodes_to_add) + 2;
_Map_pointer __new_map = this->_M_allocate_map(__new_map_size); _Map_pointer __new_map = this->_M_allocate_map(__new_map_size);
__new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2 __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2
+ (__add_at_front ? __nodes_to_add : 0); + (__add_at_front ? __nodes_to_add : 0);
std::copy(this->_M_start._M_node, std::copy(this->_M_impl._M_start._M_node,
this->_M_finish._M_node + 1, this->_M_impl._M_finish._M_node + 1,
__new_nstart); __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_impl._M_map = __new_map;
this->_M_map_size = __new_map_size; this->_M_impl._M_map_size = __new_map_size;
} }
this->_M_start._M_set_node(__new_nstart); this->_M_impl._M_start._M_set_node(__new_nstart);
this->_M_finish._M_set_node(__new_nstart + __old_num_nodes - 1); this->_M_impl._M_finish._M_set_node(__new_nstart + __old_num_nodes - 1);
} }
} // namespace __gnu_norm } // namespace __gnu_norm
......
...@@ -69,8 +69,8 @@ namespace __gnu_norm ...@@ -69,8 +69,8 @@ namespace __gnu_norm
_M_clear() _M_clear()
{ {
typedef _List_node<_Tp> _Node; typedef _List_node<_Tp> _Node;
_Node* __cur = static_cast<_Node*>(this->_M_node._M_next); _Node* __cur = static_cast<_Node*>(this->_M_impl._M_node._M_next);
while (__cur != &this->_M_node) while (__cur != &this->_M_impl._M_node)
{ {
_Node* __tmp = __cur; _Node* __tmp = __cur;
__cur = static_cast<_Node*>(__cur->_M_next); __cur = static_cast<_Node*>(__cur->_M_next);
...@@ -237,8 +237,8 @@ namespace __gnu_norm ...@@ -237,8 +237,8 @@ namespace __gnu_norm
sort() sort()
{ {
// Do nothing if the list has length 0 or 1. // Do nothing if the list has length 0 or 1.
if (this->_M_node._M_next != &this->_M_node if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node
&& this->_M_node._M_next->_M_next != &this->_M_node) && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node)
{ {
list __carry; list __carry;
list __tmp[64]; list __tmp[64];
...@@ -341,8 +341,8 @@ namespace __gnu_norm ...@@ -341,8 +341,8 @@ namespace __gnu_norm
sort(_StrictWeakOrdering __comp) sort(_StrictWeakOrdering __comp)
{ {
// Do nothing if the list has length 0 or 1. // Do nothing if the list has length 0 or 1.
if (this->_M_node._M_next != &this->_M_node if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node
&& this->_M_node._M_next->_M_next != &this->_M_node) && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node)
{ {
list __carry; list __carry;
list __tmp[64]; list __tmp[64];
......
...@@ -351,39 +351,54 @@ namespace __gnu_norm ...@@ -351,39 +351,54 @@ namespace __gnu_norm
*/ */
template<typename _Tp, typename _Alloc> template<typename _Tp, typename _Alloc>
class _Deque_base class _Deque_base
: public _Alloc
{ {
public: public:
typedef _Alloc allocator_type; typedef _Alloc allocator_type;
allocator_type allocator_type
get_allocator() const 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,_Tp&,_Tp*> iterator;
typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
_Deque_base(const allocator_type& __a, size_t __num_elements) _Deque_base(const allocator_type& __a, size_t __num_elements)
: _Alloc(__a), _M_start(), _M_finish() : _M_impl(__a)
{ _M_initialize_map(__num_elements); } { _M_initialize_map(__num_elements); }
_Deque_base(const allocator_type& __a) _Deque_base(const allocator_type& __a)
: _Alloc(__a), _M_start(), _M_finish() { } : _M_impl(__a)
{ }
~_Deque_base(); ~_Deque_base();
protected: 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; typedef typename _Alloc::template rebind<_Tp*>::other _Map_alloc_type;
_Map_alloc_type _M_get_map_allocator() const _Map_alloc_type _M_get_map_allocator() const
{ return _Map_alloc_type(this->get_allocator()); } { return _Map_alloc_type(this->get_allocator()); }
_Tp* _Tp*
_M_allocate_node() _M_allocate_node()
{ return _Alloc::allocate(__deque_buf_size(sizeof(_Tp))); } { return _M_impl._Alloc::allocate(__deque_buf_size(sizeof(_Tp))); }
void void
_M_deallocate_node(_Tp* __p) _M_deallocate_node(_Tp* __p)
{ _Alloc::deallocate(__p, __deque_buf_size(sizeof(_Tp))); } { _M_impl._Alloc::deallocate(__p, __deque_buf_size(sizeof(_Tp))); }
_Tp** _Tp**
_M_allocate_map(size_t __n) _M_allocate_map(size_t __n)
...@@ -399,19 +414,16 @@ namespace __gnu_norm ...@@ -399,19 +414,16 @@ namespace __gnu_norm
void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish); void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish);
enum { _S_initial_map_size = 8 }; enum { _S_initial_map_size = 8 };
_Tp** _M_map; _Deque_impl _M_impl;
size_t _M_map_size;
iterator _M_start;
iterator _M_finish;
}; };
template<typename _Tp, typename _Alloc> template<typename _Tp, typename _Alloc>
_Deque_base<_Tp,_Alloc>::~_Deque_base() _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_destroy_nodes(this->_M_impl._M_start._M_node, this->_M_impl._M_finish._M_node + 1);
_M_deallocate_map(this->_M_map, this->_M_map_size); _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size);
} }
} }
...@@ -431,32 +443,32 @@ namespace __gnu_norm ...@@ -431,32 +443,32 @@ namespace __gnu_norm
{ {
size_t __num_nodes = __num_elements / __deque_buf_size(sizeof(_Tp)) + 1; 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); __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 // For "small" maps (needing less than _M_map_size nodes), allocation
// starts in the middle elements and grows outwards. So nstart may be // 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 // the beginning of _M_map, but for small maps it may be as far in as
// _M_map+3. // _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; _Tp** __nfinish = __nstart + __num_nodes;
try try
{ _M_create_nodes(__nstart, __nfinish); } { _M_create_nodes(__nstart, __nfinish); }
catch(...) catch(...)
{ {
_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 = 0; this->_M_impl._M_map = 0;
this->_M_map_size = 0; this->_M_impl._M_map_size = 0;
__throw_exception_again; __throw_exception_again;
} }
_M_start._M_set_node(__nstart); this->_M_impl._M_start._M_set_node(__nstart);
_M_finish._M_set_node(__nfinish - 1); this->_M_impl._M_finish._M_set_node(__nfinish - 1);
_M_start._M_cur = _M_start._M_first; this->_M_impl._M_start._M_cur = _M_impl._M_start._M_first;
_M_finish._M_cur = _M_finish._M_first + __num_elements this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first + __num_elements
% __deque_buf_size(sizeof(_Tp)); % __deque_buf_size(sizeof(_Tp));
} }
...@@ -608,12 +620,10 @@ namespace __gnu_norm ...@@ -608,12 +620,10 @@ namespace __gnu_norm
/** @if maint /** @if maint
* A total of four data members accumulated down the heirarchy. * A total of four data members accumulated down the heirarchy.
* May be accessed via _M_impl.*
* @endif * @endif
*/ */
using _Base::_M_map; using _Base::_M_impl;
using _Base::_M_map_size;
using _Base::_M_start;
using _Base::_M_finish;
public: public:
// [23.2.1.1] construct/copy/destroy // [23.2.1.1] construct/copy/destroy
...@@ -658,7 +668,7 @@ namespace __gnu_norm ...@@ -658,7 +668,7 @@ namespace __gnu_norm
*/ */
deque(const deque& __x) deque(const deque& __x)
: _Base(__x.get_allocator(), __x.size()) : _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. * @brief Builds a %deque from a range.
...@@ -690,7 +700,7 @@ namespace __gnu_norm ...@@ -690,7 +700,7 @@ namespace __gnu_norm
* way. Managing the pointer is the user's responsibilty. * way. Managing the pointer is the user's responsibilty.
*/ */
~deque() ~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. * @brief %Deque assignment operator.
...@@ -748,7 +758,7 @@ namespace __gnu_norm ...@@ -748,7 +758,7 @@ namespace __gnu_norm
*/ */
iterator iterator
begin() begin()
{ return this->_M_start; } { return this->_M_impl._M_start; }
/** /**
* Returns a read-only (constant) iterator that points to the first * Returns a read-only (constant) iterator that points to the first
...@@ -756,7 +766,7 @@ namespace __gnu_norm ...@@ -756,7 +766,7 @@ namespace __gnu_norm
*/ */
const_iterator const_iterator
begin() const 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 * Returns a read/write iterator that points one past the last element in
...@@ -764,7 +774,7 @@ namespace __gnu_norm ...@@ -764,7 +774,7 @@ namespace __gnu_norm
*/ */
iterator iterator
end() end()
{ return this->_M_finish; } { return this->_M_impl._M_finish; }
/** /**
* Returns a read-only (constant) iterator that points one past the last * Returns a read-only (constant) iterator that points one past the last
...@@ -772,7 +782,7 @@ namespace __gnu_norm ...@@ -772,7 +782,7 @@ namespace __gnu_norm
*/ */
const_iterator const_iterator
end() const end() const
{ return this->_M_finish; } { return this->_M_impl._M_finish; }
/** /**
* Returns a read/write reverse iterator that points to the last element * Returns a read/write reverse iterator that points to the last element
...@@ -780,7 +790,7 @@ namespace __gnu_norm ...@@ -780,7 +790,7 @@ namespace __gnu_norm
*/ */
reverse_iterator reverse_iterator
rbegin() 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 * Returns a read-only (constant) reverse iterator that points to the
...@@ -789,7 +799,7 @@ namespace __gnu_norm ...@@ -789,7 +799,7 @@ namespace __gnu_norm
*/ */
const_reverse_iterator const_reverse_iterator
rbegin() const 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 * Returns a read/write reverse iterator that points to one before the
...@@ -797,7 +807,7 @@ namespace __gnu_norm ...@@ -797,7 +807,7 @@ namespace __gnu_norm
* order. * order.
*/ */
reverse_iterator 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 * Returns a read-only (constant) reverse iterator that points to one
...@@ -806,13 +816,13 @@ namespace __gnu_norm ...@@ -806,13 +816,13 @@ namespace __gnu_norm
*/ */
const_reverse_iterator const_reverse_iterator
rend() const rend() const
{ return const_reverse_iterator(this->_M_start); } { return const_reverse_iterator(this->_M_impl._M_start); }
// [23.2.1.2] capacity // [23.2.1.2] capacity
/** Returns the number of elements in the %deque. */ /** Returns the number of elements in the %deque. */
size_type size_type
size() const 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. */ /** Returns the size() of the largest possible %deque. */
size_type size_type
...@@ -834,9 +844,9 @@ namespace __gnu_norm ...@@ -834,9 +844,9 @@ namespace __gnu_norm
{ {
const size_type __len = size(); const size_type __len = size();
if (__new_size < __len) 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 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 ...@@ -857,7 +867,7 @@ namespace __gnu_norm
*/ */
bool bool
empty() const empty() const
{ return this->_M_finish == this->_M_start; } { return this->_M_impl._M_finish == this->_M_impl._M_start; }
// element access // element access
/** /**
...@@ -871,7 +881,7 @@ namespace __gnu_norm ...@@ -871,7 +881,7 @@ namespace __gnu_norm
*/ */
reference reference
operator[](size_type __n) 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. * @brief Subscript access to the data contained in the %deque.
...@@ -884,7 +894,7 @@ namespace __gnu_norm ...@@ -884,7 +894,7 @@ namespace __gnu_norm
*/ */
const_reference const_reference
operator[](size_type __n) const operator[](size_type __n) const
{ return this->_M_start[difference_type(__n)]; } { return this->_M_impl._M_start[difference_type(__n)]; }
protected: protected:
/// @if maint Safety check used only from at(). @endif /// @if maint Safety check used only from at(). @endif
...@@ -933,7 +943,7 @@ namespace __gnu_norm ...@@ -933,7 +943,7 @@ namespace __gnu_norm
*/ */
reference reference
front() front()
{ return *this->_M_start; } { return *this->_M_impl._M_start; }
/** /**
* Returns a read-only (constant) reference to the data at the first * Returns a read-only (constant) reference to the data at the first
...@@ -941,7 +951,7 @@ namespace __gnu_norm ...@@ -941,7 +951,7 @@ namespace __gnu_norm
*/ */
const_reference const_reference
front() const 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 * Returns a read/write reference to the data at the last element of the
...@@ -950,7 +960,7 @@ namespace __gnu_norm ...@@ -950,7 +960,7 @@ namespace __gnu_norm
reference reference
back() back()
{ {
iterator __tmp = this->_M_finish; iterator __tmp = this->_M_impl._M_finish;
--__tmp; --__tmp;
return *__tmp; return *__tmp;
} }
...@@ -962,7 +972,7 @@ namespace __gnu_norm ...@@ -962,7 +972,7 @@ namespace __gnu_norm
const_reference const_reference
back() const back() const
{ {
const_iterator __tmp = this->_M_finish; const_iterator __tmp = this->_M_impl._M_finish;
--__tmp; --__tmp;
return *__tmp; return *__tmp;
} }
...@@ -979,10 +989,10 @@ namespace __gnu_norm ...@@ -979,10 +989,10 @@ namespace __gnu_norm
void void
push_front(const value_type& __x) 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); std::_Construct(this->_M_impl._M_start._M_cur - 1, __x);
--this->_M_start._M_cur; --this->_M_impl._M_start._M_cur;
} }
else else
_M_push_front_aux(__x); _M_push_front_aux(__x);
...@@ -999,10 +1009,10 @@ namespace __gnu_norm ...@@ -999,10 +1009,10 @@ namespace __gnu_norm
void void
push_back(const value_type& __x) 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); std::_Construct(this->_M_impl._M_finish._M_cur, __x);
++this->_M_finish._M_cur; ++this->_M_impl._M_finish._M_cur;
} }
else else
_M_push_back_aux(__x); _M_push_back_aux(__x);
...@@ -1019,10 +1029,10 @@ namespace __gnu_norm ...@@ -1019,10 +1029,10 @@ namespace __gnu_norm
void void
pop_front() 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); std::_Destroy(this->_M_impl._M_start._M_cur);
++this->_M_start._M_cur; ++this->_M_impl._M_start._M_cur;
} }
else else
_M_pop_front_aux(); _M_pop_front_aux();
...@@ -1039,10 +1049,10 @@ namespace __gnu_norm ...@@ -1039,10 +1049,10 @@ namespace __gnu_norm
void void
pop_back() 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; --this->_M_impl._M_finish._M_cur;
std::_Destroy(this->_M_finish._M_cur); std::_Destroy(this->_M_impl._M_finish._M_cur);
} }
else else
_M_pop_back_aux(); _M_pop_back_aux();
...@@ -1140,10 +1150,10 @@ namespace __gnu_norm ...@@ -1140,10 +1150,10 @@ namespace __gnu_norm
void void
swap(deque& __x) swap(deque& __x)
{ {
std::swap(this->_M_start, __x._M_start); std::swap(this->_M_impl._M_start, __x._M_impl._M_start);
std::swap(this->_M_finish, __x._M_finish); std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish);
std::swap(this->_M_map, __x._M_map); std::swap(this->_M_impl._M_map, __x._M_impl._M_map);
std::swap(this->_M_map_size, __x._M_map_size); std::swap(this->_M_impl._M_map_size, __x._M_impl._M_map_size);
} }
/** /**
...@@ -1362,21 +1372,21 @@ namespace __gnu_norm ...@@ -1362,21 +1372,21 @@ namespace __gnu_norm
iterator iterator
_M_reserve_elements_at_front(size_type __n) _M_reserve_elements_at_front(size_type __n)
{ {
const size_type __vacancies = this->_M_start._M_cur const size_type __vacancies = this->_M_impl._M_start._M_cur
- this->_M_start._M_first; - this->_M_impl._M_start._M_first;
if (__n > __vacancies) if (__n > __vacancies)
_M_new_elements_at_front(__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 iterator
_M_reserve_elements_at_back(size_type __n) _M_reserve_elements_at_back(size_type __n)
{ {
const size_type __vacancies = (this->_M_finish._M_last const size_type __vacancies = (this->_M_impl._M_finish._M_last
- this->_M_finish._M_cur) - 1; - this->_M_impl._M_finish._M_cur) - 1;
if (__n > __vacancies) if (__n > __vacancies)
_M_new_elements_at_back(__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 void
...@@ -1400,15 +1410,15 @@ namespace __gnu_norm ...@@ -1400,15 +1410,15 @@ namespace __gnu_norm
void void
_M_reserve_map_at_back (size_type __nodes_to_add = 1) _M_reserve_map_at_back (size_type __nodes_to_add = 1)
{ {
if (__nodes_to_add + 1 > this->_M_map_size if (__nodes_to_add + 1 > this->_M_impl._M_map_size
- (this->_M_finish._M_node - this->_M_map)) - (this->_M_impl._M_finish._M_node - this->_M_impl._M_map))
_M_reallocate_map(__nodes_to_add, false); _M_reallocate_map(__nodes_to_add, false);
} }
void void
_M_reserve_map_at_front (size_type __nodes_to_add = 1) _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); _M_reallocate_map(__nodes_to_add, true);
} }
......
...@@ -275,7 +275,6 @@ namespace __gnu_norm ...@@ -275,7 +275,6 @@ namespace __gnu_norm
*/ */
template<typename _Tp, typename _Alloc> template<typename _Tp, typename _Alloc>
class _List_base class _List_base
: public _Alloc::template rebind<_List_node<_Tp> >::other
{ {
protected: protected:
// NOTA BENE // NOTA BENE
...@@ -295,25 +294,33 @@ namespace __gnu_norm ...@@ -295,25 +294,33 @@ namespace __gnu_norm
_Node_Alloc_type; _Node_Alloc_type;
struct _List_impl
: public _Node_Alloc_type {
_List_node_base _M_node; _List_node_base _M_node;
_List_impl (const _Node_Alloc_type& __a)
: _Node_Alloc_type(__a)
{ }
};
_List_impl _M_impl;
_List_node<_Tp>* _List_node<_Tp>*
_M_get_node() _M_get_node()
{ return _Node_Alloc_type::allocate(1); } { return _M_impl._Node_Alloc_type::allocate(1); }
void void
_M_put_node(_List_node<_Tp>* __p) _M_put_node(_List_node<_Tp>* __p)
{ _Node_Alloc_type::deallocate(__p, 1); } { _M_impl._Node_Alloc_type::deallocate(__p, 1); }
public: public:
typedef _Alloc allocator_type; typedef _Alloc allocator_type;
allocator_type allocator_type
get_allocator() const 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) _List_base(const allocator_type& __a)
: _Node_Alloc_type(__a) : _M_impl(__a)
{ _M_init(); } { _M_init(); }
// This is what actually destroys the list. // This is what actually destroys the list.
...@@ -326,8 +333,8 @@ namespace __gnu_norm ...@@ -326,8 +333,8 @@ namespace __gnu_norm
void void
_M_init() _M_init()
{ {
this->_M_node._M_next = &this->_M_node; this->_M_impl._M_node._M_next = &this->_M_impl._M_node;
this->_M_node._M_prev = &this->_M_node; this->_M_impl._M_node._M_prev = &this->_M_impl._M_node;
} }
}; };
...@@ -409,7 +416,7 @@ namespace __gnu_norm ...@@ -409,7 +416,7 @@ namespace __gnu_norm
* will also be included, accumulated from the topmost parent. * will also be included, accumulated from the topmost parent.
* @endif * @endif
*/ */
using _Base::_M_node; using _Base::_M_impl;
using _Base::_M_put_node; using _Base::_M_put_node;
using _Base::_M_get_node; using _Base::_M_get_node;
...@@ -588,7 +595,7 @@ namespace __gnu_norm ...@@ -588,7 +595,7 @@ namespace __gnu_norm
*/ */
iterator iterator
begin() 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 * Returns a read-only (constant) iterator that points to the
...@@ -597,7 +604,7 @@ namespace __gnu_norm ...@@ -597,7 +604,7 @@ namespace __gnu_norm
*/ */
const_iterator const_iterator
begin() const 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 * Returns a read/write iterator that points one past the last
...@@ -605,7 +612,7 @@ namespace __gnu_norm ...@@ -605,7 +612,7 @@ namespace __gnu_norm
* order. * order.
*/ */
iterator iterator
end() { return &this->_M_node; } end() { return &this->_M_impl._M_node; }
/** /**
* Returns a read-only (constant) iterator that points one past * Returns a read-only (constant) iterator that points one past
...@@ -614,7 +621,7 @@ namespace __gnu_norm ...@@ -614,7 +621,7 @@ namespace __gnu_norm
*/ */
const_iterator const_iterator
end() const end() const
{ return &this->_M_node; } { return &this->_M_impl._M_node; }
/** /**
* Returns a read/write reverse iterator that points to the last * Returns a read/write reverse iterator that points to the last
...@@ -659,7 +666,7 @@ namespace __gnu_norm ...@@ -659,7 +666,7 @@ namespace __gnu_norm
*/ */
bool bool
empty() const 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. */ /** Returns the number of elements in the %list. */
size_type size_type
...@@ -788,7 +795,7 @@ namespace __gnu_norm ...@@ -788,7 +795,7 @@ namespace __gnu_norm
*/ */
void void
pop_back() 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. * @brief Inserts given value into %list before specified iterator.
...@@ -901,7 +908,7 @@ namespace __gnu_norm ...@@ -901,7 +908,7 @@ namespace __gnu_norm
*/ */
void void
swap(list& __x) 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 * Erases all the elements. Note that this function only erases
...@@ -1064,7 +1071,7 @@ namespace __gnu_norm ...@@ -1064,7 +1071,7 @@ namespace __gnu_norm
*/ */
void void
reverse() reverse()
{ this->_M_node.reverse(); } { this->_M_impl._M_node.reverse(); }
/** /**
* @brief Sort the elements. * @brief Sort the elements.
......
...@@ -74,40 +74,47 @@ namespace __gnu_norm ...@@ -74,40 +74,47 @@ namespace __gnu_norm
*/ */
template<typename _Tp, typename _Alloc> template<typename _Tp, typename _Alloc>
struct _Vector_base 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: public:
typedef _Alloc allocator_type; typedef _Alloc allocator_type;
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) _Vector_base(const allocator_type& __a) : _M_impl(__a)
: _Alloc(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0) { } { }
_Vector_base(size_t __n, const allocator_type& __a) _Vector_base(size_t __n, const allocator_type& __a)
: _Alloc(__a) : _M_impl(__a)
{ {
this->_M_start = this->_M_allocate(__n); this->_M_impl._M_start = this->_M_allocate(__n);
this->_M_finish = this->_M_start; this->_M_impl._M_finish = this->_M_impl._M_start;
this->_M_end_of_storage = this->_M_start + __n; this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
} }
~_Vector_base() ~_Vector_base()
{ _M_deallocate(this->_M_start, { _M_deallocate(this->_M_impl._M_start,
this->_M_end_of_storage - this->_M_start); } this->_M_impl._M_end_of_storage - this->_M_impl._M_start); }
public: public:
_Tp* _M_start; _Vector_impl _M_impl;
_Tp* _M_finish;
_Tp* _M_end_of_storage;
_Tp* _Tp*
_M_allocate(size_t __n) { return _Alloc::allocate(__n); } _M_allocate(size_t __n) { return _M_impl.allocate(__n); }
void void
_M_deallocate(_Tp* __p, size_t __n) _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 ...@@ -162,9 +169,7 @@ namespace __gnu_norm
*/ */
using _Base::_M_allocate; using _Base::_M_allocate;
using _Base::_M_deallocate; using _Base::_M_deallocate;
using _Base::_M_start; using _Base::_M_impl;
using _Base::_M_finish;
using _Base::_M_end_of_storage;
public: public:
// [23.2.4.1] construct/copy/destroy // [23.2.4.1] construct/copy/destroy
...@@ -186,7 +191,7 @@ namespace __gnu_norm ...@@ -186,7 +191,7 @@ namespace __gnu_norm
vector(size_type __n, const value_type& __value, vector(size_type __n, const value_type& __value,
const allocator_type& __a = allocator_type()) const allocator_type& __a = allocator_type())
: _Base(__n, __a) : _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); } __n, __value); }
/** /**
...@@ -199,7 +204,7 @@ namespace __gnu_norm ...@@ -199,7 +204,7 @@ namespace __gnu_norm
explicit explicit
vector(size_type __n) vector(size_type __n)
: _Base(__n, allocator_type()) : _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()); } __n, value_type()); }
/** /**
...@@ -213,8 +218,8 @@ namespace __gnu_norm ...@@ -213,8 +218,8 @@ namespace __gnu_norm
*/ */
vector(const vector& __x) vector(const vector& __x)
: _Base(__x.size(), __x.get_allocator()) : _Base(__x.size(), __x.get_allocator())
{ this->_M_finish = std::uninitialized_copy(__x.begin(), __x.end(), { this->_M_impl._M_finish = std::uninitialized_copy(__x.begin(), __x.end(),
this->_M_start); this->_M_impl._M_start);
} }
/** /**
...@@ -248,7 +253,7 @@ namespace __gnu_norm ...@@ -248,7 +253,7 @@ namespace __gnu_norm
* not touched in any way. Managing the pointer is the user's * not touched in any way. Managing the pointer is the user's
* responsibilty. * 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. * @brief %Vector assignment operator.
...@@ -306,7 +311,7 @@ namespace __gnu_norm ...@@ -306,7 +311,7 @@ namespace __gnu_norm
* element order. * element order.
*/ */
iterator 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 * Returns a read-only (constant) iterator that points to the
...@@ -314,7 +319,7 @@ namespace __gnu_norm ...@@ -314,7 +319,7 @@ namespace __gnu_norm
* element order. * element order.
*/ */
const_iterator 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 * Returns a read/write iterator that points one past the last
...@@ -322,7 +327,7 @@ namespace __gnu_norm ...@@ -322,7 +327,7 @@ namespace __gnu_norm
* element order. * element order.
*/ */
iterator 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 * Returns a read-only (constant) iterator that points one past
...@@ -330,7 +335,7 @@ namespace __gnu_norm ...@@ -330,7 +335,7 @@ namespace __gnu_norm
* ordinary element order. * ordinary element order.
*/ */
const_iterator 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 * Returns a read/write reverse iterator that points to the
...@@ -412,7 +417,7 @@ namespace __gnu_norm ...@@ -412,7 +417,7 @@ namespace __gnu_norm
*/ */
size_type size_type
capacity() const 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 * Returns true if the %vector is empty. (Thus begin() would
...@@ -550,10 +555,10 @@ namespace __gnu_norm ...@@ -550,10 +555,10 @@ namespace __gnu_norm
void void
push_back(const value_type& __x) 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); std::_Construct(this->_M_impl._M_finish, __x);
++this->_M_finish; ++this->_M_impl._M_finish;
} }
else else
_M_insert_aux(end(), __x); _M_insert_aux(end(), __x);
...@@ -571,8 +576,8 @@ namespace __gnu_norm ...@@ -571,8 +576,8 @@ namespace __gnu_norm
void void
pop_back() pop_back()
{ {
--this->_M_finish; --this->_M_impl._M_finish;
std::_Destroy(this->_M_finish); std::_Destroy(this->_M_impl._M_finish);
} }
/** /**
...@@ -681,9 +686,9 @@ namespace __gnu_norm ...@@ -681,9 +686,9 @@ namespace __gnu_norm
void void
swap(vector& __x) swap(vector& __x)
{ {
std::swap(this->_M_start, __x._M_start); std::swap(this->_M_impl._M_start, __x._M_impl._M_start);
std::swap(this->_M_finish, __x._M_finish); std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish);
std::swap(this->_M_end_of_storage, __x._M_end_of_storage); std::swap(this->_M_impl._M_end_of_storage, __x._M_impl._M_end_of_storage);
} }
/** /**
...@@ -728,9 +733,9 @@ namespace __gnu_norm ...@@ -728,9 +733,9 @@ namespace __gnu_norm
void void
_M_initialize_dispatch(_Integer __n, _Integer __value, __true_type) _M_initialize_dispatch(_Integer __n, _Integer __value, __true_type)
{ {
this->_M_start = _M_allocate(__n); this->_M_impl._M_start = _M_allocate(__n);
this->_M_end_of_storage = this->_M_start + __n; this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
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); __n, __value);
} }
...@@ -762,10 +767,10 @@ namespace __gnu_norm ...@@ -762,10 +767,10 @@ namespace __gnu_norm
_ForwardIterator __last, forward_iterator_tag) _ForwardIterator __last, forward_iterator_tag)
{ {
size_type __n = std::distance(__first, __last); size_type __n = std::distance(__first, __last);
this->_M_start = this->_M_allocate(__n); this->_M_impl._M_start = this->_M_allocate(__n);
this->_M_end_of_storage = this->_M_start + __n; this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
this->_M_finish = std::uninitialized_copy(__first, __last, this->_M_impl._M_finish = std::uninitialized_copy(__first, __last,
this->_M_start); this->_M_impl._M_start);
} }
......
...@@ -74,14 +74,14 @@ namespace __gnu_norm ...@@ -74,14 +74,14 @@ namespace __gnu_norm
{ {
const size_type __old_size = size(); const size_type __old_size = size();
pointer __tmp = _M_allocate_and_copy(__n, pointer __tmp = _M_allocate_and_copy(__n,
this->_M_start, this->_M_impl._M_start,
this->_M_finish); this->_M_impl._M_finish);
std::_Destroy(this->_M_start, this->_M_finish); std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish);
_M_deallocate(this->_M_start, _M_deallocate(this->_M_impl._M_start,
this->_M_end_of_storage - this->_M_start); this->_M_impl._M_end_of_storage - this->_M_impl._M_start);
this->_M_start = __tmp; this->_M_impl._M_start = __tmp;
this->_M_finish = __tmp + __old_size; this->_M_impl._M_finish = __tmp + __old_size;
this->_M_end_of_storage = this->_M_start + __n; this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
} }
} }
...@@ -91,10 +91,10 @@ namespace __gnu_norm ...@@ -91,10 +91,10 @@ namespace __gnu_norm
insert(iterator __position, const value_type& __x) insert(iterator __position, const value_type& __x)
{ {
size_type __n = __position - begin(); 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); std::_Construct(this->_M_impl._M_finish, __x);
++this->_M_finish; ++this->_M_impl._M_finish;
} }
else else
_M_insert_aux(__position, __x); _M_insert_aux(__position, __x);
...@@ -108,8 +108,8 @@ namespace __gnu_norm ...@@ -108,8 +108,8 @@ namespace __gnu_norm
{ {
if (__position + 1 != end()) if (__position + 1 != end())
std::copy(__position + 1, end(), __position); std::copy(__position + 1, end(), __position);
--this->_M_finish; --this->_M_impl._M_finish;
std::_Destroy(this->_M_finish); std::_Destroy(this->_M_impl._M_finish);
return __position; return __position;
} }
...@@ -120,7 +120,7 @@ namespace __gnu_norm ...@@ -120,7 +120,7 @@ namespace __gnu_norm
{ {
iterator __i(copy(__last, end(), __first)); iterator __i(copy(__last, end(), __first));
std::_Destroy(__i, end()); 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; return __first;
} }
...@@ -135,11 +135,11 @@ namespace __gnu_norm ...@@ -135,11 +135,11 @@ namespace __gnu_norm
if (__xlen > capacity()) if (__xlen > capacity())
{ {
pointer __tmp = _M_allocate_and_copy(__xlen, __x.begin(), __x.end()); pointer __tmp = _M_allocate_and_copy(__xlen, __x.begin(), __x.end());
std::_Destroy(this->_M_start, this->_M_finish); std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish);
_M_deallocate(this->_M_start, _M_deallocate(this->_M_impl._M_start,
this->_M_end_of_storage - this->_M_start); this->_M_impl._M_end_of_storage - this->_M_impl._M_start);
this->_M_start = __tmp; this->_M_impl._M_start = __tmp;
this->_M_end_of_storage = this->_M_start + __xlen; this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __xlen;
} }
else if (size() >= __xlen) else if (size() >= __xlen)
{ {
...@@ -148,10 +148,10 @@ namespace __gnu_norm ...@@ -148,10 +148,10 @@ namespace __gnu_norm
} }
else else
{ {
std::copy(__x.begin(), __x.begin() + size(), this->_M_start); std::copy(__x.begin(), __x.begin() + size(), this->_M_impl._M_start);
std::uninitialized_copy(__x.begin() + size(), __x.end(), this->_M_finish); 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; return *this;
} }
...@@ -169,8 +169,8 @@ namespace __gnu_norm ...@@ -169,8 +169,8 @@ namespace __gnu_norm
else if (__n > size()) else if (__n > size())
{ {
std::fill(begin(), end(), __val); std::fill(begin(), end(), __val);
this->_M_finish this->_M_impl._M_finish
= std::uninitialized_fill_n(this->_M_finish, __n - size(), __val); = std::uninitialized_fill_n(this->_M_impl._M_finish, __n - size(), __val);
} }
else else
erase(fill_n(begin(), __n, __val), end()); erase(fill_n(begin(), __n, __val), end());
...@@ -201,24 +201,24 @@ namespace __gnu_norm ...@@ -201,24 +201,24 @@ namespace __gnu_norm
if (__len > capacity()) if (__len > capacity())
{ {
pointer __tmp(_M_allocate_and_copy(__len, __first, __last)); pointer __tmp(_M_allocate_and_copy(__len, __first, __last));
std::_Destroy(this->_M_start, this->_M_finish); std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish);
_M_deallocate(this->_M_start, _M_deallocate(this->_M_impl._M_start,
this->_M_end_of_storage - this->_M_start); this->_M_impl._M_end_of_storage - this->_M_impl._M_start);
this->_M_start = __tmp; this->_M_impl._M_start = __tmp;
this->_M_end_of_storage = this->_M_finish = this->_M_start + __len; this->_M_impl._M_end_of_storage = this->_M_impl._M_finish = this->_M_impl._M_start + __len;
} }
else if (size() >= __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()); std::_Destroy(__new_finish, end());
this->_M_finish = __new_finish.base(); this->_M_impl._M_finish = __new_finish.base();
} }
else else
{ {
_ForwardIterator __mid = __first; _ForwardIterator __mid = __first;
std::advance(__mid, size()); std::advance(__mid, size());
std::copy(__first, __mid, this->_M_start); std::copy(__first, __mid, this->_M_impl._M_start);
this->_M_finish = std::uninitialized_copy(__mid, __last, this->_M_finish); this->_M_impl._M_finish = std::uninitialized_copy(__mid, __last, this->_M_impl._M_finish);
} }
} }
...@@ -227,14 +227,14 @@ namespace __gnu_norm ...@@ -227,14 +227,14 @@ namespace __gnu_norm
vector<_Tp,_Alloc>:: vector<_Tp,_Alloc>::
_M_insert_aux(iterator __position, const _Tp& __x) _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)); std::_Construct(this->_M_impl._M_finish, *(this->_M_impl._M_finish - 1));
++this->_M_finish; ++this->_M_impl._M_finish;
_Tp __x_copy = __x; _Tp __x_copy = __x;
std::copy_backward(__position, std::copy_backward(__position,
iterator(this->_M_finish-2), iterator(this->_M_impl._M_finish-2),
iterator(this->_M_finish-1)); iterator(this->_M_impl._M_finish-1));
*__position = __x_copy; *__position = __x_copy;
} }
else else
...@@ -245,13 +245,13 @@ namespace __gnu_norm ...@@ -245,13 +245,13 @@ namespace __gnu_norm
iterator __new_finish(__new_start); iterator __new_finish(__new_start);
try try
{ {
__new_finish = std::uninitialized_copy(iterator(this->_M_start), __new_finish = std::uninitialized_copy(iterator(this->_M_impl._M_start),
__position, __position,
__new_start); __new_start);
std::_Construct(__new_finish.base(), __x); std::_Construct(__new_finish.base(), __x);
++__new_finish; ++__new_finish;
__new_finish = std::uninitialized_copy(__position, __new_finish = std::uninitialized_copy(__position,
iterator(this->_M_finish), iterator(this->_M_impl._M_finish),
__new_finish); __new_finish);
} }
catch(...) catch(...)
...@@ -261,11 +261,11 @@ namespace __gnu_norm ...@@ -261,11 +261,11 @@ namespace __gnu_norm
__throw_exception_again; __throw_exception_again;
} }
std::_Destroy(begin(), end()); std::_Destroy(begin(), end());
_M_deallocate(this->_M_start, _M_deallocate(this->_M_impl._M_start,
this->_M_end_of_storage - this->_M_start); this->_M_impl._M_end_of_storage - this->_M_impl._M_start);
this->_M_start = __new_start.base(); this->_M_impl._M_start = __new_start.base();
this->_M_finish = __new_finish.base(); this->_M_impl._M_finish = __new_finish.base();
this->_M_end_of_storage = __new_start.base() + __len; this->_M_impl._M_end_of_storage = __new_start.base() + __len;
} }
} }
...@@ -276,28 +276,28 @@ namespace __gnu_norm ...@@ -276,28 +276,28 @@ namespace __gnu_norm
{ {
if (__n != 0) 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; value_type __x_copy = __x;
const size_type __elems_after = end() - __position; 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) if (__elems_after > __n)
{ {
std::uninitialized_copy(this->_M_finish - __n, std::uninitialized_copy(this->_M_impl._M_finish - __n,
this->_M_finish, this->_M_impl._M_finish,
this->_M_finish); this->_M_impl._M_finish);
this->_M_finish += __n; this->_M_impl._M_finish += __n;
std::copy_backward(__position, __old_finish - __n, __old_finish); std::copy_backward(__position, __old_finish - __n, __old_finish);
std::fill(__position, __position + __n, __x_copy); std::fill(__position, __position + __n, __x_copy);
} }
else else
{ {
std::uninitialized_fill_n(this->_M_finish, std::uninitialized_fill_n(this->_M_impl._M_finish,
__n - __elems_after, __n - __elems_after,
__x_copy); __x_copy);
this->_M_finish += __n - __elems_after; this->_M_impl._M_finish += __n - __elems_after;
std::uninitialized_copy(__position, __old_finish, this->_M_finish); std::uninitialized_copy(__position, __old_finish, this->_M_impl._M_finish);
this->_M_finish += __elems_after; this->_M_impl._M_finish += __elems_after;
std::fill(__position, __old_finish, __x_copy); std::fill(__position, __old_finish, __x_copy);
} }
} }
...@@ -321,12 +321,12 @@ namespace __gnu_norm ...@@ -321,12 +321,12 @@ namespace __gnu_norm
_M_deallocate(__new_start.base(),__len); _M_deallocate(__new_start.base(),__len);
__throw_exception_again; __throw_exception_again;
} }
std::_Destroy(this->_M_start, this->_M_finish); std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish);
_M_deallocate(this->_M_start, _M_deallocate(this->_M_impl._M_start,
this->_M_end_of_storage - this->_M_start); this->_M_impl._M_end_of_storage - this->_M_impl._M_start);
this->_M_start = __new_start.base(); this->_M_impl._M_start = __new_start.base();
this->_M_finish = __new_finish.base(); this->_M_impl._M_finish = __new_finish.base();
this->_M_end_of_storage = __new_start.base() + __len; this->_M_impl._M_end_of_storage = __new_start.base() + __len;
} }
} }
} }
...@@ -354,16 +354,16 @@ namespace __gnu_norm ...@@ -354,16 +354,16 @@ namespace __gnu_norm
if (__first != __last) if (__first != __last)
{ {
size_type __n = std::distance(__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; 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) if (__elems_after > __n)
{ {
std::uninitialized_copy(this->_M_finish - __n, std::uninitialized_copy(this->_M_impl._M_finish - __n,
this->_M_finish, this->_M_impl._M_finish,
this->_M_finish); this->_M_impl._M_finish);
this->_M_finish += __n; this->_M_impl._M_finish += __n;
std::copy_backward(__position, __old_finish - __n, __old_finish); std::copy_backward(__position, __old_finish - __n, __old_finish);
std::copy(__first, __last, __position); std::copy(__first, __last, __position);
} }
...@@ -371,10 +371,10 @@ namespace __gnu_norm ...@@ -371,10 +371,10 @@ namespace __gnu_norm
{ {
_ForwardIterator __mid = __first; _ForwardIterator __mid = __first;
std::advance(__mid, __elems_after); std::advance(__mid, __elems_after);
std::uninitialized_copy(__mid, __last, this->_M_finish); std::uninitialized_copy(__mid, __last, this->_M_impl._M_finish);
this->_M_finish += __n - __elems_after; this->_M_impl._M_finish += __n - __elems_after;
std::uninitialized_copy(__position, __old_finish, this->_M_finish); std::uninitialized_copy(__position, __old_finish, this->_M_impl._M_finish);
this->_M_finish += __elems_after; this->_M_impl._M_finish += __elems_after;
std::copy(__first, __mid, __position); std::copy(__first, __mid, __position);
} }
} }
...@@ -386,12 +386,12 @@ namespace __gnu_norm ...@@ -386,12 +386,12 @@ namespace __gnu_norm
iterator __new_finish(__new_start); iterator __new_finish(__new_start);
try try
{ {
__new_finish = std::uninitialized_copy(iterator(this->_M_start), __new_finish = std::uninitialized_copy(iterator(this->_M_impl._M_start),
__position, __new_start); __position, __new_start);
__new_finish = std::uninitialized_copy(__first, __last, __new_finish = std::uninitialized_copy(__first, __last,
__new_finish); __new_finish);
__new_finish = std::uninitialized_copy(__position, __new_finish = std::uninitialized_copy(__position,
iterator(this->_M_finish), iterator(this->_M_impl._M_finish),
__new_finish); __new_finish);
} }
catch(...) catch(...)
...@@ -400,12 +400,12 @@ namespace __gnu_norm ...@@ -400,12 +400,12 @@ namespace __gnu_norm
_M_deallocate(__new_start.base(), __len); _M_deallocate(__new_start.base(), __len);
__throw_exception_again; __throw_exception_again;
} }
std::_Destroy(this->_M_start, this->_M_finish); std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish);
_M_deallocate(this->_M_start, _M_deallocate(this->_M_impl._M_start,
this->_M_end_of_storage - this->_M_start); this->_M_impl._M_end_of_storage - this->_M_impl._M_start);
this->_M_start = __new_start.base(); this->_M_impl._M_start = __new_start.base();
this->_M_finish = __new_finish.base(); this->_M_impl._M_finish = __new_finish.base();
this->_M_end_of_storage = __new_start.base() + __len; this->_M_impl._M_end_of_storage = __new_start.base() + __len;
} }
} }
} }
......
// 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;
}
// 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;
}
// 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment