Commit 1985f1cd by Matt Austern Committed by Matt Austern

stl_construct.h (_Destroy): New three-argument overload that takes an allocator argument.

	* include/bits/stl_construct.h (_Destroy): New three-argument
	overload that takes an allocator argument.  Another inline
	three-argument overload that takes std::allocator and dispatches
	to the two-argument version.
	* include/bits/stl_uninitialized.h (__uninitialized_fill_n_aux):
	Change return type to void to match uninitialized_fill_n.
	(__uninitialized_copy_a_): New function.  Like uninitialized_copy
	except that it takes an allocator and uses it for construct and
	destroy.  If the allocator is std::allocator, dispatches to
	uninitialized_copy.
	(__uninitialized_fill_a): Likewise.
	(__uninitialized_fill_n_a): Likewise.
	(__uninitialized_copy_copy): Give it an allocator argument.
	(__uninitialized_fill_copy): Likewise.
	(__uninitialized_copy_fill): Likewise.
	* include/bits/deque.tcc: Use new forms defined in stl_construct.h
	and stl_uninitialized.h.  Replace use of single-argument _Construct
	and _Destroy with use of allocator's construct and destroy methods.
	* include/bits/list.tcc: Likewise.
	* include/bits/stl_deque.h: Likewise.
	* include/bits/stl_list.h: Likewise.
	* include/bits/stl_tree.h: Likewise.
	* include/bits/stl_vector.h: Likewise.
	* include/bits/vector.tcc: Likewise.
	* include/ext/hashtable.h: Use rebind so that allocator_type
	has correct type for a container's allocator.  Replace use of
	single-argument _Construct and _Destroy with use of allocator's
	construct and destroy methods.
	* include/ext/memory (__uninitialized_copy_n_a): New function.
	Like uninitialized_copy_n except that it takes an extra parameter,
	an allocator, and uses it for construct and destroy operations.
	* include/ext/rope: Use new forms defined in stl_construct.h,
	stl_uninitialized.h, and ext/memory.  Replace use of single-argument
	_Construct and _Destroy with allocator construct and destroy methods.
	* include/ext/ropeimpl.h: Likewise.
	* include/ext/slist.h: Likewise.
	* testsuite/testsuite_allocator.h (check_construct_destroy): New.
	* testsuite/testsuite_allocator.cc (check_construct_destroy): New.
	* testsuite/23_containers/deque/check_construct_destroy.cc: New.
	* testsuite/23_containers/list/check_construct_destroy.cc: New.
	* testsuite/23_containers/set/check_construct_destroy.cc: New.
	* testsuite/23_containers/vector/check_construct_destroy.cc: New.
	* testsuite/ext/hash_check_construct_destroy.cc: New.
	* testsuite/ext/slist_check_construct_destroy.cc: New.

From-SVN: r85265
parent 6fea55e9
2004-07-28 Matt Austern <austern@apple.com>
* include/bits/stl_construct.h (_Destroy): New three-argument
overload that takes an allocator argument. Another inline
three-argument overload that takes std::allocator and dispatches
to the two-argument version.
* include/bits/stl_uninitialized.h (__uninitialized_fill_n_aux):
Change return type to void to match uninitialized_fill_n.
(__uninitialized_copy_a_): New function. Like uninitialized_copy
except that it takes an allocator and uses it for construct and
destroy. If the allocator is std::allocator, dispatches to
uninitialized_copy.
(__uninitialized_fill_a): Likewise.
(__uninitialized_fill_n_a): Likewise.
(__uninitialized_copy_copy): Give it an allocator argument.
(__uninitialized_fill_copy): Likewise.
(__uninitialized_copy_fill): Likewise.
* include/bits/deque.tcc: Use new forms defined in stl_construct.h
and stl_uninitialized.h. Replace use of single-argument _Construct
and _Destroy with use of allocator's construct and destroy methods.
* include/bits/list.tcc: Likewise.
* include/bits/stl_deque.h: Likewise.
* include/bits/stl_list.h: Likewise.
* include/bits/stl_tree.h: Likewise.
* include/bits/stl_vector.h: Likewise.
* include/bits/vector.tcc: Likewise.
* include/ext/hashtable.h: Use rebind so that allocator_type
has correct type for a container's allocator. Replace use of
single-argument _Construct and _Destroy with use of allocator's
construct and destroy methods.
* include/ext/memory (__uninitialized_copy_n_a): New function.
Like uninitialized_copy_n except that it takes an extra parameter,
an allocator, and uses it for construct and destroy operations.
* include/ext/rope: Use new forms defined in stl_construct.h,
stl_uninitialized.h, and ext/memory. Replace use of single-argument
_Construct and _Destroy with allocator construct and destroy methods.
* include/ext/ropeimpl.h: Likewise.
* include/ext/slist.h: Likewise.
* testsuite/testsuite_allocator.h (check_construct_destroy): New.
* testsuite/testsuite_allocator.cc (check_construct_destroy): New.
* testsuite/23_containers/deque/check_construct_destroy.cc: New.
* testsuite/23_containers/list/check_construct_destroy.cc: New.
* testsuite/23_containers/set/check_construct_destroy.cc: New.
* testsuite/23_containers/vector/check_construct_destroy.cc: New.
* testsuite/ext/hash_check_construct_destroy.cc
* testsuite/ext/slist_check_construct_destroy.cc
2004-07-28 Alexandre Oliva <aoliva@redhat.com> 2004-07-28 Alexandre Oliva <aoliva@redhat.com>
2003-10-01 Eric Christopher <echristo@redhat.com> 2003-10-01 Eric Christopher <echristo@redhat.com>
......
...@@ -74,7 +74,7 @@ namespace _GLIBCXX_STD ...@@ -74,7 +74,7 @@ namespace _GLIBCXX_STD
{ {
_Node* __tmp = __cur; _Node* __tmp = __cur;
__cur = static_cast<_Node*>(__cur->_M_next); __cur = static_cast<_Node*>(__cur->_M_next);
std::_Destroy(&__tmp->_M_data); this->get_allocator().destroy(&__tmp->_M_data);
_M_put_node(__tmp); _M_put_node(__tmp);
} }
} }
......
...@@ -154,6 +154,35 @@ namespace std ...@@ -154,6 +154,35 @@ namespace std
std::__destroy_aux(__first, __last, _Has_trivial_destructor()); std::__destroy_aux(__first, __last, _Has_trivial_destructor());
} }
/**
* @if maint
* Destroy a range of objects using the supplied allocator. For
* nondefault allocators we do not optimize away invocation of
* destroy() even if _Tp has a trivial destructor.
* @endif
*/
template <typename _Tp> class allocator;
template<typename _ForwardIterator, typename _Allocator>
void
_Destroy(_ForwardIterator __first, _ForwardIterator __last,
_Allocator __alloc)
{
for (; __first != __last; ++__first)
__alloc.destroy(&*__first);
}
template<typename _ForwardIterator, typename _Allocator, typename _Tp>
inline void
_Destroy(_ForwardIterator __first, _ForwardIterator __last,
allocator<_Tp>)
{
_Destroy(__first, __last);
}
} // namespace std } // namespace std
#endif /* _STL_CONSTRUCT_H */ #endif /* _STL_CONSTRUCT_H */
......
...@@ -677,8 +677,8 @@ namespace _GLIBCXX_STD ...@@ -677,8 +677,8 @@ namespace _GLIBCXX_STD
*/ */
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(), { std::__uninitialized_copy_a(__x.begin(), __x.end(), this->_M_impl._M_start,
this->_M_impl._M_start); } this->get_allocator()); }
/** /**
* @brief Builds a %deque from a range. * @brief Builds a %deque from a range.
...@@ -710,7 +710,8 @@ namespace _GLIBCXX_STD ...@@ -710,7 +710,8 @@ namespace _GLIBCXX_STD
* way. Managing the pointer is the user's responsibilty. * way. Managing the pointer is the user's responsibilty.
*/ */
~deque() ~deque()
{ std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); } { std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
this->get_allocator()); }
/** /**
* @brief %Deque assignment operator. * @brief %Deque assignment operator.
...@@ -1004,7 +1005,7 @@ namespace _GLIBCXX_STD ...@@ -1004,7 +1005,7 @@ namespace _GLIBCXX_STD
{ {
if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_first) if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_first)
{ {
std::_Construct(this->_M_impl._M_start._M_cur - 1, __x); this->_M_impl.construct(this->_M_impl._M_start._M_cur - 1, __x);
--this->_M_impl._M_start._M_cur; --this->_M_impl._M_start._M_cur;
} }
else else
...@@ -1025,7 +1026,7 @@ namespace _GLIBCXX_STD ...@@ -1025,7 +1026,7 @@ namespace _GLIBCXX_STD
if (this->_M_impl._M_finish._M_cur if (this->_M_impl._M_finish._M_cur
!= this->_M_impl._M_finish._M_last - 1) != this->_M_impl._M_finish._M_last - 1)
{ {
std::_Construct(this->_M_impl._M_finish._M_cur, __x); this->_M_impl.construct(this->_M_impl._M_finish._M_cur, __x);
++this->_M_impl._M_finish._M_cur; ++this->_M_impl._M_finish._M_cur;
} }
else else
...@@ -1046,7 +1047,7 @@ namespace _GLIBCXX_STD ...@@ -1046,7 +1047,7 @@ namespace _GLIBCXX_STD
if (this->_M_impl._M_start._M_cur if (this->_M_impl._M_start._M_cur
!= this->_M_impl._M_start._M_last - 1) != this->_M_impl._M_start._M_last - 1)
{ {
std::_Destroy(this->_M_impl._M_start._M_cur); this->_M_impl.destroy(this->_M_impl._M_start._M_cur);
++this->_M_impl._M_start._M_cur; ++this->_M_impl._M_start._M_cur;
} }
else else
...@@ -1068,7 +1069,7 @@ namespace _GLIBCXX_STD ...@@ -1068,7 +1069,7 @@ namespace _GLIBCXX_STD
!= this->_M_impl._M_finish._M_first) != this->_M_impl._M_finish._M_first)
{ {
--this->_M_impl._M_finish._M_cur; --this->_M_impl._M_finish._M_cur;
std::_Destroy(this->_M_impl._M_finish._M_cur); this->_M_impl.destroy(this->_M_impl._M_finish._M_cur);
} }
else else
_M_pop_back_aux(); _M_pop_back_aux();
......
...@@ -435,7 +435,7 @@ namespace _GLIBCXX_STD ...@@ -435,7 +435,7 @@ namespace _GLIBCXX_STD
_Node* __p = this->_M_get_node(); _Node* __p = this->_M_get_node();
try try
{ {
std::_Construct(&__p->_M_data, __x); this->get_allocator().construct(&__p->_M_data, __x);
} }
catch(...) catch(...)
{ {
...@@ -457,7 +457,7 @@ namespace _GLIBCXX_STD ...@@ -457,7 +457,7 @@ namespace _GLIBCXX_STD
_Node* __p = this->_M_get_node(); _Node* __p = this->_M_get_node();
try try
{ {
std::_Construct(&__p->_M_data); this->get_allocator().construct(&__p->_M_data);
} }
catch(...) catch(...)
{ {
...@@ -1170,7 +1170,7 @@ namespace _GLIBCXX_STD ...@@ -1170,7 +1170,7 @@ namespace _GLIBCXX_STD
{ {
__position._M_node->unhook(); __position._M_node->unhook();
_Node* __n = static_cast<_Node*>(__position._M_node); _Node* __n = static_cast<_Node*>(__position._M_node);
std::_Destroy(&__n->_M_data); this->get_allocator().destroy(&__n->_M_data);
_M_put_node(__n); _M_put_node(__n);
} }
}; };
......
...@@ -362,7 +362,7 @@ namespace std ...@@ -362,7 +362,7 @@ namespace std
{ {
_Link_type __tmp = _M_get_node(); _Link_type __tmp = _M_get_node();
try try
{ std::_Construct(&__tmp->_M_value_field, __x); } { get_allocator().construct(&__tmp->_M_value_field, __x); }
catch(...) catch(...)
{ {
_M_put_node(__tmp); _M_put_node(__tmp);
...@@ -384,7 +384,7 @@ namespace std ...@@ -384,7 +384,7 @@ namespace std
void void
destroy_node(_Link_type __p) destroy_node(_Link_type __p)
{ {
std::_Destroy(&__p->_M_value_field); get_allocator().destroy(&__p->_M_value_field);
_M_put_node(__p); _M_put_node(__p);
} }
......
...@@ -177,13 +177,13 @@ namespace std ...@@ -177,13 +177,13 @@ namespace std
// Valid if copy construction is equivalent to assignment, and if the // Valid if copy construction is equivalent to assignment, and if the
// destructor is trivial. // destructor is trivial.
template<typename _ForwardIterator, typename _Size, typename _Tp> template<typename _ForwardIterator, typename _Size, typename _Tp>
inline _ForwardIterator inline void
__uninitialized_fill_n_aux(_ForwardIterator __first, _Size __n, __uninitialized_fill_n_aux(_ForwardIterator __first, _Size __n,
const _Tp& __x, __true_type) const _Tp& __x, __true_type)
{ return std::fill_n(__first, __n, __x); } { std::fill_n(__first, __n, __x); }
template<typename _ForwardIterator, typename _Size, typename _Tp> template<typename _ForwardIterator, typename _Size, typename _Tp>
_ForwardIterator void
__uninitialized_fill_n_aux(_ForwardIterator __first, _Size __n, __uninitialized_fill_n_aux(_ForwardIterator __first, _Size __n,
const _Tp& __x, __false_type) const _Tp& __x, __false_type)
{ {
...@@ -192,7 +192,6 @@ namespace std ...@@ -192,7 +192,6 @@ namespace std
{ {
for (; __n > 0; --__n, ++__cur) for (; __n > 0; --__n, ++__cur)
std::_Construct(&*__cur, __x); std::_Construct(&*__cur, __x);
return __cur;
} }
catch(...) catch(...)
{ {
...@@ -219,8 +218,102 @@ namespace std ...@@ -219,8 +218,102 @@ namespace std
std::__uninitialized_fill_n_aux(__first, __n, __x, _Is_POD()); std::__uninitialized_fill_n_aux(__first, __n, __x, _Is_POD());
} }
// Extensions: versions of uninitialized_copy, uninitialized_fill,
// and uninitialized_fill_n that take an allocator parameter.
// We dispatch back to the standard versions when we're given the
// default allocator. For nondefault allocators we do not use
// any of the POD optimizations.
template<typename _InputIterator, typename _ForwardIterator,
typename _Allocator>
_ForwardIterator
__uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
_ForwardIterator __result,
_Allocator __alloc)
{
_ForwardIterator __cur = __result;
try
{
for (; __first != __last; ++__first, ++__cur)
__alloc.construct(&*__cur, *__first);
return __cur;
}
catch(...)
{
std::_Destroy(__result, __cur, __alloc);
__throw_exception_again;
}
}
template<typename _InputIterator, typename _ForwardIterator, typename _Tp>
inline _ForwardIterator
__uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
_ForwardIterator __result,
allocator<_Tp>)
{
return std::uninitialized_copy(__first, __last, __result);
}
template<typename _ForwardIterator, typename _Tp, typename _Allocator>
void
__uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __x, _Allocator __alloc)
{
_ForwardIterator __cur = __first;
try
{
for (; __cur != __last; ++__cur)
__alloc.construct(&*__cur, __x);
}
catch(...)
{
std::_Destroy(__first, __cur, __alloc);
__throw_exception_again;
}
}
template<typename _ForwardIterator, typename _Tp, typename _Tp2>
inline void
__uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __x, allocator<_Tp2>)
{
std::uninitialized_fill(__first, __last, __x);
}
template<typename _ForwardIterator, typename _Size, typename _Tp,
typename _Allocator>
void
__uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
const _Tp& __x,
_Allocator __alloc)
{
_ForwardIterator __cur = __first;
try
{
for (; __n > 0; --__n, ++__cur)
__alloc.construct(&*__cur, __x);
}
catch(...)
{
std::_Destroy(__first, __cur, __alloc);
__throw_exception_again;
}
}
template<typename _ForwardIterator, typename _Size, typename _Tp,
typename _Tp2>
void
__uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
const _Tp& __x,
allocator<_Tp2>)
{
std::uninitialized_fill_n(__first, __n, __x);
}
// Extensions: __uninitialized_copy_copy, __uninitialized_copy_fill, // Extensions: __uninitialized_copy_copy, __uninitialized_copy_fill,
// __uninitialized_fill_copy. // __uninitialized_fill_copy. All of these algorithms take a user-
// supplied allocator, which is used for construction and destruction.
// __uninitialized_copy_copy // __uninitialized_copy_copy
// Copies [first1, last1) into [result, result + (last1 - first1)), and // Copies [first1, last1) into [result, result + (last1 - first1)), and
...@@ -228,23 +321,25 @@ namespace std ...@@ -228,23 +321,25 @@ namespace std
// [result, result + (last1 - first1) + (last2 - first2)). // [result, result + (last1 - first1) + (last2 - first2)).
template<typename _InputIterator1, typename _InputIterator2, template<typename _InputIterator1, typename _InputIterator2,
typename _ForwardIterator> typename _ForwardIterator, typename _Allocator>
inline _ForwardIterator inline _ForwardIterator
__uninitialized_copy_copy(_InputIterator1 __first1, __uninitialized_copy_copy(_InputIterator1 __first1,
_InputIterator1 __last1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __first2,
_InputIterator2 __last2, _InputIterator2 __last2,
_ForwardIterator __result) _ForwardIterator __result,
_Allocator __alloc)
{ {
_ForwardIterator __mid = std::uninitialized_copy(__first1, __last1, _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
__result); __result,
__alloc);
try try
{ {
return std::uninitialized_copy(__first2, __last2, __mid); return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
} }
catch(...) catch(...)
{ {
std::_Destroy(__result, __mid); std::_Destroy(__result, __mid, __alloc);
__throw_exception_again; __throw_exception_again;
} }
} }
...@@ -252,20 +347,22 @@ namespace std ...@@ -252,20 +347,22 @@ namespace std
// __uninitialized_fill_copy // __uninitialized_fill_copy
// Fills [result, mid) with x, and copies [first, last) into // Fills [result, mid) with x, and copies [first, last) into
// [mid, mid + (last - first)). // [mid, mid + (last - first)).
template<typename _ForwardIterator, typename _Tp, typename _InputIterator> template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
typename _Allocator>
inline _ForwardIterator inline _ForwardIterator
__uninitialized_fill_copy(_ForwardIterator __result, _ForwardIterator __mid, __uninitialized_fill_copy(_ForwardIterator __result, _ForwardIterator __mid,
const _Tp& __x, _InputIterator __first, const _Tp& __x, _InputIterator __first,
_InputIterator __last) _InputIterator __last,
_Allocator __alloc)
{ {
std::uninitialized_fill(__result, __mid, __x); std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
try try
{ {
return std::uninitialized_copy(__first, __last, __mid); return std::__uninitialized_copy_a(__first, __last, __mid, __alloc);
} }
catch(...) catch(...)
{ {
std::_Destroy(__result, __mid); std::_Destroy(__result, __mid, __alloc);
__throw_exception_again; __throw_exception_again;
} }
} }
...@@ -273,21 +370,24 @@ namespace std ...@@ -273,21 +370,24 @@ namespace std
// __uninitialized_copy_fill // __uninitialized_copy_fill
// Copies [first1, last1) into [first2, first2 + (last1 - first1)), and // Copies [first1, last1) into [first2, first2 + (last1 - first1)), and
// fills [first2 + (last1 - first1), last2) with x. // fills [first2 + (last1 - first1), last2) with x.
template<typename _InputIterator, typename _ForwardIterator, typename _Tp> template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
typename _Allocator>
inline void inline void
__uninitialized_copy_fill(_InputIterator __first1, _InputIterator __last1, __uninitialized_copy_fill(_InputIterator __first1, _InputIterator __last1,
_ForwardIterator __first2, _ForwardIterator __first2,
_ForwardIterator __last2, const _Tp& __x) _ForwardIterator __last2, const _Tp& __x,
_Allocator __alloc)
{ {
_ForwardIterator __mid2 = std::uninitialized_copy(__first1, __last1, _ForwardIterator __mid2 = std::__uninitialized_copy_a(__first1, __last1,
__first2); __first2,
__alloc);
try try
{ {
std::uninitialized_fill(__mid2, __last2, __x); std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
} }
catch(...) catch(...)
{ {
std::_Destroy(__first2, __mid2); std::_Destroy(__first2, __mid2, __alloc);
__throw_exception_again; __throw_exception_again;
} }
} }
......
...@@ -200,7 +200,8 @@ namespace _GLIBCXX_STD ...@@ -200,7 +200,8 @@ namespace _GLIBCXX_STD
const allocator_type& __a = allocator_type()) const allocator_type& __a = allocator_type())
: _Base(__n, __a) : _Base(__n, __a)
{ {
std::uninitialized_fill_n(this->_M_impl._M_start, __n, __value); std::__uninitialized_fill_n_a(this->_M_impl._M_start, __n, __value,
this->get_allocator());
this->_M_impl._M_finish = this->_M_impl._M_start + __n; this->_M_impl._M_finish = this->_M_impl._M_start + __n;
} }
...@@ -215,7 +216,8 @@ namespace _GLIBCXX_STD ...@@ -215,7 +216,8 @@ namespace _GLIBCXX_STD
vector(size_type __n) vector(size_type __n)
: _Base(__n, allocator_type()) : _Base(__n, allocator_type())
{ {
std::uninitialized_fill_n(this->_M_impl._M_start, __n, value_type()); std::__uninitialized_fill_n_a(this->_M_impl._M_start, __n, value_type(),
this->get_allocator());
this->_M_impl._M_finish = this->_M_impl._M_start + __n; this->_M_impl._M_finish = this->_M_impl._M_start + __n;
} }
...@@ -230,10 +232,11 @@ namespace _GLIBCXX_STD ...@@ -230,10 +232,11 @@ namespace _GLIBCXX_STD
*/ */
vector(const vector& __x) vector(const vector& __x)
: _Base(__x.size(), __x.get_allocator()) : _Base(__x.size(), __x.get_allocator())
{ this->_M_impl._M_finish = std::uninitialized_copy(__x.begin(), { this->_M_impl._M_finish =
__x.end(), std::__uninitialized_copy_a(__x.begin(), __x.end(),
this-> this->_M_impl._M_start,
_M_impl._M_start); } this->get_allocator());
}
/** /**
* @brief Builds a %vector from a range. * @brief Builds a %vector from a range.
...@@ -267,7 +270,9 @@ namespace _GLIBCXX_STD ...@@ -267,7 +270,9 @@ namespace _GLIBCXX_STD
* responsibilty. * responsibilty.
*/ */
~vector() ~vector()
{ std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); } { std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
this->get_allocator());
}
/** /**
* @brief %Vector assignment operator. * @brief %Vector assignment operator.
...@@ -598,7 +603,7 @@ namespace _GLIBCXX_STD ...@@ -598,7 +603,7 @@ namespace _GLIBCXX_STD
{ {
if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
{ {
std::_Construct(this->_M_impl._M_finish, __x); this->_M_impl.construct(this->_M_impl._M_finish, __x);
++this->_M_impl._M_finish; ++this->_M_impl._M_finish;
} }
else else
...@@ -618,7 +623,7 @@ namespace _GLIBCXX_STD ...@@ -618,7 +623,7 @@ namespace _GLIBCXX_STD
pop_back() pop_back()
{ {
--this->_M_impl._M_finish; --this->_M_impl._M_finish;
std::_Destroy(this->_M_impl._M_finish); this->_M_impl.destroy(this->_M_impl._M_finish);
} }
/** /**
...@@ -758,7 +763,8 @@ namespace _GLIBCXX_STD ...@@ -758,7 +763,8 @@ namespace _GLIBCXX_STD
pointer __result = this->_M_allocate(__n); pointer __result = this->_M_allocate(__n);
try try
{ {
std::uninitialized_copy(__first, __last, __result); std::__uninitialized_copy_a(__first, __last, __result,
this->get_allocator());
return __result; return __result;
} }
catch(...) catch(...)
...@@ -778,7 +784,8 @@ namespace _GLIBCXX_STD ...@@ -778,7 +784,8 @@ namespace _GLIBCXX_STD
{ {
this->_M_impl._M_start = _M_allocate(__n); 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_end_of_storage = this->_M_impl._M_start + __n;
std::uninitialized_fill_n(this->_M_impl._M_start, __n, __value); std::__uninitialized_fill_n_a(this->_M_impl._M_start, __n, __value,
this->get_allocator());
this->_M_impl._M_finish = this->_M_impl._M_end_of_storage; this->_M_impl._M_finish = this->_M_impl._M_end_of_storage;
} }
...@@ -812,9 +819,10 @@ namespace _GLIBCXX_STD ...@@ -812,9 +819,10 @@ namespace _GLIBCXX_STD
const size_type __n = std::distance(__first, __last); const size_type __n = std::distance(__first, __last);
this->_M_impl._M_start = this->_M_allocate(__n); 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_end_of_storage = this->_M_impl._M_start + __n;
this->_M_impl._M_finish = std::uninitialized_copy(__first, __last, this->_M_impl._M_finish =
this-> std::__uninitialized_copy_a(__first, __last,
_M_impl._M_start); this->_M_impl._M_start,
this->get_allocator());
} }
......
...@@ -281,7 +281,7 @@ namespace __gnu_cxx ...@@ -281,7 +281,7 @@ namespace __gnu_cxx
typedef _Hashtable_node<_Val> _Node; typedef _Hashtable_node<_Val> _Node;
public: public:
typedef _Alloc allocator_type; typedef typename _Alloc::template rebind<value_type>::other allocator_type;
allocator_type allocator_type
get_allocator() const get_allocator() const
{ return _M_node_allocator; } { return _M_node_allocator; }
...@@ -607,7 +607,7 @@ namespace __gnu_cxx ...@@ -607,7 +607,7 @@ namespace __gnu_cxx
__n->_M_next = 0; __n->_M_next = 0;
try try
{ {
_Construct(&__n->_M_val, __obj); this->get_allocator().construct(&__n->_M_val, __obj);
return __n; return __n;
} }
catch(...) catch(...)
...@@ -620,7 +620,7 @@ namespace __gnu_cxx ...@@ -620,7 +620,7 @@ namespace __gnu_cxx
void void
_M_delete_node(_Node* __n) _M_delete_node(_Node* __n)
{ {
_Destroy(&__n->_M_val); this->get_allocator().destroy(&__n->_M_val);
_M_put_node(__n); _M_put_node(__n);
} }
......
...@@ -128,6 +128,40 @@ namespace __gnu_cxx ...@@ -128,6 +128,40 @@ namespace __gnu_cxx
{ return __uninitialized_copy_n(__first, __count, __result, { return __uninitialized_copy_n(__first, __count, __result,
__iterator_category(__first)); } __iterator_category(__first)); }
// An alternative version of uninitialized_copy_n that constructs
// and destroys objects with a user-provided allocator.
template<typename _InputIter, typename _Size, typename _ForwardIter,
typename _Allocator>
pair<_InputIter, _ForwardIter>
__uninitialized_copy_n_a(_InputIter __first, _Size __count,
_ForwardIter __result,
_Allocator __alloc)
{
_ForwardIter __cur = __result;
try
{
for (; __count > 0 ; --__count, ++__first, ++__cur)
__alloc.construct(&*__cur, *__first);
return pair<_InputIter, _ForwardIter>(__first, __cur);
}
catch(...)
{
std::_Destroy(__result, __cur, __alloc);
__throw_exception_again;
}
}
template<typename _InputIter, typename _Size, typename _ForwardIter,
typename _Tp>
inline pair<_InputIter, _ForwardIter>
__uninitialized_copy_n_a(_InputIter __first, _Size __count,
_ForwardIter __result,
std::allocator<_Tp>)
{
return uninitialized_copy_n(__first, __count, __result);
}
/** /**
* This class provides similar behavior and semantics of the standard * This class provides similar behavior and semantics of the standard
* functions get_temporary_buffer() and return_temporary_buffer(), but * functions get_temporary_buffer() and return_temporary_buffer(), but
......
...@@ -1642,7 +1642,7 @@ protected: ...@@ -1642,7 +1642,7 @@ protected:
return 0; return 0;
_CharT* __buf = __a.allocate(_S_rounded_up_size(__size)); _CharT* __buf = __a.allocate(_S_rounded_up_size(__size));
uninitialized_copy_n(__s, __size, __buf); __uninitialized_copy_n_a(__s, __size, __buf, __a);
_S_cond_store_eos(__buf[__size]); _S_cond_store_eos(__buf[__size]);
try try
{ return _S_new_RopeLeaf(__buf, __size, __a); } { return _S_new_RopeLeaf(__buf, __size, __a); }
...@@ -1790,7 +1790,7 @@ protected: ...@@ -1790,7 +1790,7 @@ protected:
{ {
_CharT* __buf = this->_Data_allocate(_S_rounded_up_size(1)); _CharT* __buf = this->_Data_allocate(_S_rounded_up_size(1));
std::_Construct(__buf, __c); get_allocator().construct(__buf, __c);
try try
{ this->_M_tree_ptr = _S_new_RopeLeaf(__buf, 1, __a); } { this->_M_tree_ptr = _S_new_RopeLeaf(__buf, 1, __a); }
catch(...) catch(...)
...@@ -1905,7 +1905,7 @@ protected: ...@@ -1905,7 +1905,7 @@ protected:
void void
copy(_CharT* __buffer) const copy(_CharT* __buffer) const
{ {
_Destroy(__buffer, __buffer + size()); _Destroy(__buffer, __buffer + size(), get_allocator());
_S_flatten(this->_M_tree_ptr, __buffer); _S_flatten(this->_M_tree_ptr, __buffer);
} }
...@@ -1920,7 +1920,7 @@ protected: ...@@ -1920,7 +1920,7 @@ protected:
size_t __size = size(); size_t __size = size();
size_t __len = (__pos + __n > __size? __size - __pos : __n); size_t __len = (__pos + __n > __size? __size - __pos : __n);
_Destroy(__buffer, __buffer + __len); _Destroy(__buffer, __buffer + __len, get_allocator());
_S_flatten(this->_M_tree_ptr, __pos, __len, __buffer); _S_flatten(this->_M_tree_ptr, __pos, __len, __buffer);
return __len; return __len;
} }
......
...@@ -346,7 +346,7 @@ namespace __gnu_cxx ...@@ -346,7 +346,7 @@ namespace __gnu_cxx
if (0 != __cstr) if (0 != __cstr)
{ {
size_t __size = this->_M_size + 1; size_t __size = this->_M_size + 1;
_Destroy(__cstr, __cstr + __size); _Destroy(__cstr, __cstr + __size, get_allocator());
this->_Data_deallocate(__cstr, __size); this->_Data_deallocate(__cstr, __size);
} }
} }
...@@ -357,7 +357,7 @@ namespace __gnu_cxx ...@@ -357,7 +357,7 @@ namespace __gnu_cxx
_S_free_string(_CharT* __s, size_t __n, allocator_type __a) _S_free_string(_CharT* __s, size_t __n, allocator_type __a)
{ {
if (!_S_is_basic_char_type((_CharT*)0)) if (!_S_is_basic_char_type((_CharT*)0))
_Destroy(__s, __s + __n); _Destroy(__s, __s + __n, __a);
// This has to be a static member, so this gets a bit messy // This has to be a static member, so this gets a bit messy
__a.deallocate(__s, __a.deallocate(__s,
...@@ -1547,7 +1547,8 @@ namespace __gnu_cxx ...@@ -1547,7 +1547,8 @@ namespace __gnu_cxx
else else
{ {
__rest_buffer = this->_Data_allocate(_S_rounded_up_size(__rest)); __rest_buffer = this->_Data_allocate(_S_rounded_up_size(__rest));
uninitialized_fill_n(__rest_buffer, __rest, __c); __uninitialized_fill_n_a(__rest_buffer, __rest, __c,
get_allocator());
_S_cond_store_eos(__rest_buffer[__rest]); _S_cond_store_eos(__rest_buffer[__rest]);
try try
{ __remainder = _S_new_RopeLeaf(__rest_buffer, __rest, __a); } { __remainder = _S_new_RopeLeaf(__rest_buffer, __rest, __a); }
...@@ -1564,7 +1565,8 @@ namespace __gnu_cxx ...@@ -1564,7 +1565,8 @@ namespace __gnu_cxx
this->_Data_allocate(_S_rounded_up_size(__exponentiate_threshold)); this->_Data_allocate(_S_rounded_up_size(__exponentiate_threshold));
_RopeLeaf* __base_leaf; _RopeLeaf* __base_leaf;
rope __base_rope; rope __base_rope;
uninitialized_fill_n(__base_buffer, __exponentiate_threshold, __c); __uninitialized_fill_n_a(__base_buffer, __exponentiate_threshold, __c,
get_allocator());
_S_cond_store_eos(__base_buffer[__exponentiate_threshold]); _S_cond_store_eos(__base_buffer[__exponentiate_threshold]);
try try
{ {
......
...@@ -260,7 +260,7 @@ namespace __gnu_cxx ...@@ -260,7 +260,7 @@ namespace __gnu_cxx
_Slist_node<_Tp>* __next = (_Slist_node<_Tp>*) (__pos->_M_next); _Slist_node<_Tp>* __next = (_Slist_node<_Tp>*) (__pos->_M_next);
_Slist_node_base* __next_next = __next->_M_next; _Slist_node_base* __next_next = __next->_M_next;
__pos->_M_next = __next_next; __pos->_M_next = __next_next;
_Destroy(&__next->_M_data); get_allocator().destroy(&__next->_M_data);
_M_put_node(__next); _M_put_node(__next);
return __next_next; return __next_next;
} }
...@@ -277,7 +277,7 @@ namespace __gnu_cxx ...@@ -277,7 +277,7 @@ namespace __gnu_cxx
{ {
_Slist_node<_Tp>* __tmp = __cur; _Slist_node<_Tp>* __tmp = __cur;
__cur = (_Slist_node<_Tp>*) __cur->_M_next; __cur = (_Slist_node<_Tp>*) __cur->_M_next;
_Destroy(&__tmp->_M_data); get_allocator().destroy(&__tmp->_M_data);
_M_put_node(__tmp); _M_put_node(__tmp);
} }
__before_first->_M_next = __last_node; __before_first->_M_next = __last_node;
...@@ -327,7 +327,7 @@ namespace __gnu_cxx ...@@ -327,7 +327,7 @@ namespace __gnu_cxx
_Node* __node = this->_M_get_node(); _Node* __node = this->_M_get_node();
try try
{ {
_Construct(&__node->_M_data, __x); get_allocator().construct(&__node->_M_data, __x);
__node->_M_next = 0; __node->_M_next = 0;
} }
catch(...) catch(...)
...@@ -344,7 +344,7 @@ namespace __gnu_cxx ...@@ -344,7 +344,7 @@ namespace __gnu_cxx
_Node* __node = this->_M_get_node(); _Node* __node = this->_M_get_node();
try try
{ {
_Construct(&__node->_M_data); get_allocator().construct(&__node->_M_data);
__node->_M_next = 0; __node->_M_next = 0;
} }
catch(...) catch(...)
...@@ -490,7 +490,7 @@ namespace __gnu_cxx ...@@ -490,7 +490,7 @@ namespace __gnu_cxx
{ {
_Node* __node = (_Node*) this->_M_head._M_next; _Node* __node = (_Node*) this->_M_head._M_next;
this->_M_head._M_next = __node->_M_next; this->_M_head._M_next = __node->_M_next;
_Destroy(&__node->_M_data); get_allocator().destroy(&__node->_M_data);
this->_M_put_node(__node); this->_M_put_node(__node);
} }
......
// 2004-07-26 Matt Austern <austern@apple.com>
//
// Copyright (C) 2003 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.
//
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
#include <deque>
#include <testsuite_allocator.h>
using namespace __gnu_test;
int main()
{
typedef std::deque<int, tracker_alloc<int> > Container;
const int arr10[10] = { 2, 4, 1, 7, 3, 8, 10, 5, 9, 6 };
bool ok = true;
allocation_tracker::resetCounts();
{
Container c;
ok = check_construct_destroy("empty container", 0, 0) && ok;
}
ok = check_construct_destroy("empty container", 0, 0) && ok;
allocation_tracker::resetCounts();
{
Container c(arr10, arr10 + 10);
ok = check_construct_destroy("Construct from range", 10, 0) && ok;
}
ok = check_construct_destroy("Construct from range", 10, 10) && ok;
{
Container c(arr10, arr10 + 10);
allocation_tracker::resetCounts();
c.insert(c.begin(), arr10[0]);
ok = check_construct_destroy("Insert element", 1, 0) && ok;
}
ok = check_construct_destroy("Insert element", 1, 11) && ok;
{
Container c(arr10, arr10 + 10);
allocation_tracker::resetCounts();
c.insert(c.begin() + 5, arr10, arr10+3);
ok = check_construct_destroy("Insert short range", 3, 0) && ok;
}
ok = check_construct_destroy("Insert short range", 3, 13) && ok;
{
Container c(arr10, arr10 + 10);
allocation_tracker::resetCounts();
c.insert(c.begin() + 7, arr10, arr10+10);
ok = check_construct_destroy("Insert long range", 10, 0) && ok;
}
ok = check_construct_destroy("Insert long range", 10, 20) && ok;
return ok ? 0 : 1;;
}
// 2004-07-26 Matt Austern <austern@apple.com>
//
// Copyright (C) 2003 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.
//
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
#include <list>
#include <iterator>
#include <testsuite_allocator.h>
using namespace __gnu_test;
int main()
{
typedef std::list<int, tracker_alloc<int> > Container;
const int arr10[10] = { 2, 4, 1, 7, 3, 8, 10, 5, 9, 6 };
bool ok = true;
allocation_tracker::resetCounts();
{
Container c;
ok = check_construct_destroy("empty container", 0, 0) && ok;
}
ok = check_construct_destroy("empty container", 0, 0) && ok;
allocation_tracker::resetCounts();
{
Container c(arr10, arr10 + 10);
ok = check_construct_destroy("Construct from range", 10, 0) && ok;
}
ok = check_construct_destroy("Construct from range", 10, 10) && ok;
{
Container c(arr10, arr10 + 10);
allocation_tracker::resetCounts();
c.insert(c.begin(), arr10[0]);
ok = check_construct_destroy("Insert element", 1, 0) && ok;
}
ok = check_construct_destroy("Insert element", 1, 11) && ok;
{
Container c(arr10, arr10 + 10);
allocation_tracker::resetCounts();
Container::iterator i5 = c.begin();
std::advance(i5, 5);
c.insert(i5, arr10, arr10+3);
ok = check_construct_destroy("Insert short range", 3, 0) && ok;
}
ok = check_construct_destroy("Insert short range", 3, 13) && ok;
{
Container c(arr10, arr10 + 10);
allocation_tracker::resetCounts();
Container::iterator i7 = c.begin();
std::advance(i7, 5);
c.insert(i7, arr10, arr10+10);
ok = check_construct_destroy("Insert long range", 10, 0) && ok;
}
ok = check_construct_destroy("Insert long range", 10, 20) && ok;
return ok ? 0 : 1;
}
// 2004-07-26 Matt Austern <austern@apple.com>
//
// Copyright (C) 2003 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.
//
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
#include <set>
#include <functional>
#include <iterator>
#include <testsuite_allocator.h>
using namespace __gnu_test;
int main()
{
typedef std::set<int, std::less<int>, tracker_alloc<int> > Container;
const int arr10[10] = { 2, 4, 1, 7, 3, 8, 10, 5, 9, 6 };
const int arr10a[10] = { 31, 23, 82, 46, 13, 17, 30, 71, 22, 51 };
bool ok = true;
allocation_tracker::resetCounts();
{
Container c;
ok = check_construct_destroy("empty container", 0, 0) && ok;
}
ok = check_construct_destroy("empty container", 0, 0) && ok;
allocation_tracker::resetCounts();
{
Container c(arr10, arr10 + 10);
ok = check_construct_destroy("Construct from range", 10, 0) && ok;
}
ok = check_construct_destroy("Construct from range", 10, 10) && ok;
{
Container c(arr10, arr10 + 10);
allocation_tracker::resetCounts();
c.insert(arr10a[0]);
ok = check_construct_destroy("Insert element", 1, 0) && ok;
}
ok = check_construct_destroy("Insert element", 1, 11) && ok;
{
Container c(arr10, arr10 + 10);
allocation_tracker::resetCounts();
c.insert(arr10a, arr10a+3);
ok = check_construct_destroy("Insert short range", 3, 0) && ok;
}
ok = check_construct_destroy("Insert short range", 3, 13) && ok;
{
Container c(arr10, arr10 + 10);
allocation_tracker::resetCounts();
c.insert(arr10a, arr10a+10);
ok = check_construct_destroy("Insert long range", 10, 0) && ok;
}
ok = check_construct_destroy("Insert long range", 10, 20) && ok;
return ok ? 0 : 1;
}
// 2004-07-26 Matt Austern <austern@apple.com>
//
// Copyright (C) 2003 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.
//
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
#include <vector>
#include <testsuite_allocator.h>
using namespace __gnu_test;
int main()
{
typedef std::vector<int, tracker_alloc<int> > Container;
const int arr10[10] = { 2, 4, 1, 7, 3, 8, 10, 5, 9, 6 };
bool ok = true;
allocation_tracker::resetCounts();
{
Container c;
ok = check_construct_destroy("empty container", 0, 0) && ok;
}
ok = check_construct_destroy("empty container", 0, 0) && ok;
allocation_tracker::resetCounts();
{
Container c(arr10, arr10 + 10);
ok = check_construct_destroy("Construct from range", 10, 0) && ok;
}
ok = check_construct_destroy("Construct from range", 10, 10) && ok;
{
Container c(arr10, arr10 + 10);
c.reserve(100);
allocation_tracker::resetCounts();
c.insert(c.begin(), arr10[0]);
ok = check_construct_destroy("Insert element", 1, 0) && ok;
}
ok = check_construct_destroy("Insert element", 1, 11) && ok;
{
Container c(arr10, arr10 + 10);
c.reserve(100);
allocation_tracker::resetCounts();
c.insert(c.begin() + 5, arr10, arr10+3);
ok = check_construct_destroy("Insert short range", 3, 0) && ok;
}
ok = check_construct_destroy("Insert short range", 3, 13) && ok;
{
Container c(arr10, arr10 + 10);
c.reserve(100);
allocation_tracker::resetCounts();
c.insert(c.begin() + 7, arr10, arr10+10);
ok = check_construct_destroy("Insert long range", 10, 0) && ok;
}
ok = check_construct_destroy("Insert long range", 10, 20) && ok;
return ok ? 0 : 1;
}
// 2004-07-26 Matt Austern <austern@apple.com>
//
// Copyright (C) 2003 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.
//
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
#include <ext/hash_set>
#include <functional>
#include <iterator>
#include <testsuite_allocator.h>
using namespace __gnu_test;
int main()
{
typedef __gnu_cxx::hash_set<int, __gnu_cxx::hash<int>, std::equal_to<int>,
tracker_alloc<int> >
Container;
const int arr10[10] = { 2, 4, 1, 7, 3, 8, 10, 5, 9, 6 };
const int arr10a[10] = { 31, 23, 82, 46, 13, 17, 30, 71, 22, 51 };
bool ok = true;
int buckets;
allocation_tracker::resetCounts();
{
Container c;
buckets = c.bucket_count();
ok = check_construct_destroy("empty container", buckets, 0) && ok;
}
ok = check_construct_destroy("empty container", buckets, buckets) && ok;
allocation_tracker::resetCounts();
{
Container c(arr10, arr10 + 10);
ok = check_construct_destroy("Construct from range", buckets+10, 0) && ok;
}
ok = check_construct_destroy("Construct from range", buckets+10, buckets+10) && ok;
allocation_tracker::resetCounts();
{
Container c(arr10, arr10 + 10);
c.insert(arr10a[0]);
ok = check_construct_destroy("Insert element", buckets+11, 0) && ok;
}
ok = check_construct_destroy("Insert element", buckets+11, buckets+11) && ok;
allocation_tracker::resetCounts();
{
Container c(arr10, arr10 + 10);
c.insert(arr10a, arr10a+3);
ok = check_construct_destroy("Insert short range", buckets+13, 0) && ok;
}
ok = check_construct_destroy("Insert short range", buckets+13, buckets+13) && ok;
allocation_tracker::resetCounts();
{
Container c(arr10, arr10 + 10);
c.insert(arr10a, arr10a+10);
ok = check_construct_destroy("Insert long range", buckets+20, 0) && ok;
}
ok = check_construct_destroy("Insert long range", buckets+20, buckets+20) && ok;
return ok ? 0 : 1;
}
// 2004-07-26 Matt Austern <austern@apple.com>
//
// Copyright (C) 2003 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.
//
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
#include <ext/slist>
#include <iterator>
#include <testsuite_allocator.h>
using namespace __gnu_test;
int main()
{
typedef __gnu_cxx::slist<int, tracker_alloc<int> > Container;
const int arr10[10] = { 2, 4, 1, 7, 3, 8, 10, 5, 9, 6 };
bool ok = true;
allocation_tracker::resetCounts();
{
Container c;
ok = check_construct_destroy("empty container", 0, 0) && ok;
}
ok = check_construct_destroy("empty container", 0, 0) && ok;
allocation_tracker::resetCounts();
{
Container c(arr10, arr10 + 10);
ok = check_construct_destroy("Construct from range", 10, 0) && ok;
}
ok = check_construct_destroy("Construct from range", 10, 10) && ok;
{
Container c(arr10, arr10 + 10);
allocation_tracker::resetCounts();
c.insert(c.begin(), arr10[0]);
ok = check_construct_destroy("Insert element", 1, 0) && ok;
}
ok = check_construct_destroy("Insert element", 1, 11) && ok;
{
Container c(arr10, arr10 + 10);
allocation_tracker::resetCounts();
Container::iterator i5 = c.begin();
std::advance(i5, 5);
c.insert(i5, arr10, arr10+3);
ok = check_construct_destroy("Insert short range", 3, 0) && ok;
}
ok = check_construct_destroy("Insert short range", 3, 13) && ok;
{
Container c(arr10, arr10 + 10);
allocation_tracker::resetCounts();
Container::iterator i7 = c.begin();
std::advance(i7, 5);
c.insert(i7, arr10, arr10+10);
ok = check_construct_destroy("Insert long range", 10, 0) && ok;
}
ok = check_construct_destroy("Insert long range", 10, 20) && ok;
return ok ? 0 : 1;
}
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
// invalidate any other reasons why the executable file might be covered by // invalidate any other reasons why the executable file might be covered by
// the GNU General Public License. // the GNU General Public License.
#include <iostream>
#include <testsuite_allocator.h> #include <testsuite_allocator.h>
namespace __gnu_test namespace __gnu_test
...@@ -36,5 +37,24 @@ namespace __gnu_test ...@@ -36,5 +37,24 @@ namespace __gnu_test
allocation_tracker::size_type allocation_tracker::deallocationTotal_ = 0; allocation_tracker::size_type allocation_tracker::deallocationTotal_ = 0;
int allocation_tracker::constructCount_ = 0; int allocation_tracker::constructCount_ = 0;
int allocation_tracker::destructCount_ = 0; int allocation_tracker::destructCount_ = 0;
bool
check_construct_destroy(const char* tag, int expected_c, int expected_d)
{
if (allocation_tracker::constructCount() == expected_c &&
allocation_tracker::destructCount() == expected_d)
return true;
else {
std::cerr << tag << ": "
<< " construct = " << allocation_tracker::constructCount()
<< " (should be " << expected_c << "),"
<< " destroy = " << allocation_tracker::destructCount()
<< " (should be " << expected_d << ")"
<< std::endl;
return false;
}
}
}; // namespace __cxx_test }; // namespace __cxx_test
...@@ -169,6 +169,10 @@ namespace __gnu_test ...@@ -169,6 +169,10 @@ namespace __gnu_test
bool bool
operator!=(const tracker_alloc<T1>&, const tracker_alloc<T2>&) throw() operator!=(const tracker_alloc<T1>&, const tracker_alloc<T2>&) throw()
{ return false; } { return false; }
bool
check_construct_destroy(const char* tag, int expected_c, int expected_d);
}; // namespace __gnu_test }; // namespace __gnu_test
#endif // _GLIBCXX_TESTSUITE_ALLOCATOR_H #endif // _GLIBCXX_TESTSUITE_ALLOCATOR_H
......
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