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>
* ext/malloc_allocator.h: Fixed the construct function to call
global placement new instead of assignment. Added a check after
the return from malloc to check whether returned pointer is NULL,
and if so, throw std::bad_alloc().
* ext/debug_allocator.h: Added a check in the deallocate function
to check whether the user has passed a NULL pointer or not.
* include/ext/malloc_allocator.h: Fixed the construct function to
call global placement new instead of assignment. Added a check
after the return from malloc to check whether returned pointer is
NULL, and if so, throw std::bad_alloc().
* include/ext/debug_allocator.h: Added a check in the deallocate
function to check whether the user has passed a NULL pointer or
not.
2004-03-24 Benjamin Kosnik <bkoz@redhat.com>
......
......@@ -69,8 +69,8 @@ namespace __gnu_norm
_M_clear()
{
typedef _List_node<_Tp> _Node;
_Node* __cur = static_cast<_Node*>(this->_M_node._M_next);
while (__cur != &this->_M_node)
_Node* __cur = static_cast<_Node*>(this->_M_impl._M_node._M_next);
while (__cur != &this->_M_impl._M_node)
{
_Node* __tmp = __cur;
__cur = static_cast<_Node*>(__cur->_M_next);
......@@ -237,8 +237,8 @@ namespace __gnu_norm
sort()
{
// Do nothing if the list has length 0 or 1.
if (this->_M_node._M_next != &this->_M_node
&& this->_M_node._M_next->_M_next != &this->_M_node)
if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node
&& this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node)
{
list __carry;
list __tmp[64];
......@@ -341,8 +341,8 @@ namespace __gnu_norm
sort(_StrictWeakOrdering __comp)
{
// Do nothing if the list has length 0 or 1.
if (this->_M_node._M_next != &this->_M_node
&& this->_M_node._M_next->_M_next != &this->_M_node)
if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node
&& this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node)
{
list __carry;
list __tmp[64];
......
......@@ -275,7 +275,6 @@ namespace __gnu_norm
*/
template<typename _Tp, typename _Alloc>
class _List_base
: public _Alloc::template rebind<_List_node<_Tp> >::other
{
protected:
// NOTA BENE
......@@ -295,25 +294,33 @@ namespace __gnu_norm
_Node_Alloc_type;
_List_node_base _M_node;
struct _List_impl
: public _Node_Alloc_type {
_List_node_base _M_node;
_List_impl (const _Node_Alloc_type& __a)
: _Node_Alloc_type(__a)
{ }
};
_List_impl _M_impl;
_List_node<_Tp>*
_M_get_node()
{ return _Node_Alloc_type::allocate(1); }
{ return _M_impl._Node_Alloc_type::allocate(1); }
void
_M_put_node(_List_node<_Tp>* __p)
{ _Node_Alloc_type::deallocate(__p, 1); }
{ _M_impl._Node_Alloc_type::deallocate(__p, 1); }
public:
typedef _Alloc allocator_type;
allocator_type
get_allocator() const
{ return allocator_type(*static_cast<const _Node_Alloc_type*>(this)); }
{ return allocator_type(*static_cast<const _Node_Alloc_type*>(&this->_M_impl)); }
_List_base(const allocator_type& __a)
: _Node_Alloc_type(__a)
: _M_impl(__a)
{ _M_init(); }
// This is what actually destroys the list.
......@@ -326,8 +333,8 @@ namespace __gnu_norm
void
_M_init()
{
this->_M_node._M_next = &this->_M_node;
this->_M_node._M_prev = &this->_M_node;
this->_M_impl._M_node._M_next = &this->_M_impl._M_node;
this->_M_impl._M_node._M_prev = &this->_M_impl._M_node;
}
};
......@@ -409,7 +416,7 @@ namespace __gnu_norm
* will also be included, accumulated from the topmost parent.
* @endif
*/
using _Base::_M_node;
using _Base::_M_impl;
using _Base::_M_put_node;
using _Base::_M_get_node;
......@@ -588,7 +595,7 @@ namespace __gnu_norm
*/
iterator
begin()
{ return this->_M_node._M_next; }
{ return this->_M_impl._M_node._M_next; }
/**
* Returns a read-only (constant) iterator that points to the
......@@ -597,7 +604,7 @@ namespace __gnu_norm
*/
const_iterator
begin() const
{ return this->_M_node._M_next; }
{ return this->_M_impl._M_node._M_next; }
/**
* Returns a read/write iterator that points one past the last
......@@ -605,7 +612,7 @@ namespace __gnu_norm
* order.
*/
iterator
end() { return &this->_M_node; }
end() { return &this->_M_impl._M_node; }
/**
* Returns a read-only (constant) iterator that points one past
......@@ -614,7 +621,7 @@ namespace __gnu_norm
*/
const_iterator
end() const
{ return &this->_M_node; }
{ return &this->_M_impl._M_node; }
/**
* Returns a read/write reverse iterator that points to the last
......@@ -659,7 +666,7 @@ namespace __gnu_norm
*/
bool
empty() const
{ return this->_M_node._M_next == &this->_M_node; }
{ return this->_M_impl._M_node._M_next == &this->_M_impl._M_node; }
/** Returns the number of elements in the %list. */
size_type
......@@ -788,7 +795,7 @@ namespace __gnu_norm
*/
void
pop_back()
{ this->_M_erase(this->_M_node._M_prev); }
{ this->_M_erase(this->_M_impl._M_node._M_prev); }
/**
* @brief Inserts given value into %list before specified iterator.
......@@ -901,7 +908,7 @@ namespace __gnu_norm
*/
void
swap(list& __x)
{ _List_node_base::swap(this->_M_node,__x._M_node); }
{ _List_node_base::swap(this->_M_impl._M_node,__x._M_impl._M_node); }
/**
* Erases all the elements. Note that this function only erases
......@@ -1064,7 +1071,7 @@ namespace __gnu_norm
*/
void
reverse()
{ this->_M_node.reverse(); }
{ this->_M_impl._M_node.reverse(); }
/**
* @brief Sort the elements.
......
......@@ -74,40 +74,47 @@ namespace __gnu_norm
*/
template<typename _Tp, typename _Alloc>
struct _Vector_base
: public _Alloc
{
struct _Vector_impl
: public _Alloc {
_Tp* _M_start;
_Tp* _M_finish;
_Tp* _M_end_of_storage;
_Vector_impl (_Alloc const& __a)
: _Alloc(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0)
{ }
};
public:
typedef _Alloc allocator_type;
allocator_type
get_allocator() const { return *static_cast<const _Alloc*>(this); }
get_allocator() const { return *static_cast<const _Alloc*>(&this->_M_impl); }
_Vector_base(const allocator_type& __a)
: _Alloc(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0) { }
_Vector_base(const allocator_type& __a) : _M_impl(__a)
{ }
_Vector_base(size_t __n, const allocator_type& __a)
: _Alloc(__a)
: _M_impl(__a)
{
this->_M_start = this->_M_allocate(__n);
this->_M_finish = this->_M_start;
this->_M_end_of_storage = this->_M_start + __n;
this->_M_impl._M_start = this->_M_allocate(__n);
this->_M_impl._M_finish = this->_M_impl._M_start;
this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
}
~_Vector_base()
{ _M_deallocate(this->_M_start,
this->_M_end_of_storage - this->_M_start); }
{ _M_deallocate(this->_M_impl._M_start,
this->_M_impl._M_end_of_storage - this->_M_impl._M_start); }
public:
_Tp* _M_start;
_Tp* _M_finish;
_Tp* _M_end_of_storage;
_Vector_impl _M_impl;
_Tp*
_M_allocate(size_t __n) { return _Alloc::allocate(__n); }
_M_allocate(size_t __n) { return _M_impl.allocate(__n); }
void
_M_deallocate(_Tp* __p, size_t __n)
{ if (__p) _Alloc::deallocate(__p, __n); }
{ if (__p) _M_impl.deallocate(__p, __n); }
};
......@@ -162,9 +169,7 @@ namespace __gnu_norm
*/
using _Base::_M_allocate;
using _Base::_M_deallocate;
using _Base::_M_start;
using _Base::_M_finish;
using _Base::_M_end_of_storage;
using _Base::_M_impl;
public:
// [23.2.4.1] construct/copy/destroy
......@@ -186,7 +191,7 @@ namespace __gnu_norm
vector(size_type __n, const value_type& __value,
const allocator_type& __a = allocator_type())
: _Base(__n, __a)
{ this->_M_finish = std::uninitialized_fill_n(this->_M_start,
{ this->_M_impl._M_finish = std::uninitialized_fill_n(this->_M_impl._M_start,
__n, __value); }
/**
......@@ -199,7 +204,7 @@ namespace __gnu_norm
explicit
vector(size_type __n)
: _Base(__n, allocator_type())
{ this->_M_finish = std::uninitialized_fill_n(this->_M_start,
{ this->_M_impl._M_finish = std::uninitialized_fill_n(this->_M_impl._M_start,
__n, value_type()); }
/**
......@@ -213,8 +218,8 @@ namespace __gnu_norm
*/
vector(const vector& __x)
: _Base(__x.size(), __x.get_allocator())
{ this->_M_finish = std::uninitialized_copy(__x.begin(), __x.end(),
this->_M_start);
{ this->_M_impl._M_finish = std::uninitialized_copy(__x.begin(), __x.end(),
this->_M_impl._M_start);
}
/**
......@@ -248,7 +253,7 @@ namespace __gnu_norm
* not touched in any way. Managing the pointer is the user's
* responsibilty.
*/
~vector() { std::_Destroy(this->_M_start, this->_M_finish); }
~vector() { std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); }
/**
* @brief %Vector assignment operator.
......@@ -306,7 +311,7 @@ namespace __gnu_norm
* element order.
*/
iterator
begin() { return iterator (this->_M_start); }
begin() { return iterator (this->_M_impl._M_start); }
/**
* Returns a read-only (constant) iterator that points to the
......@@ -314,7 +319,7 @@ namespace __gnu_norm
* element order.
*/
const_iterator
begin() const { return const_iterator (this->_M_start); }
begin() const { return const_iterator (this->_M_impl._M_start); }
/**
* Returns a read/write iterator that points one past the last
......@@ -322,7 +327,7 @@ namespace __gnu_norm
* element order.
*/
iterator
end() { return iterator (this->_M_finish); }
end() { return iterator (this->_M_impl._M_finish); }
/**
* Returns a read-only (constant) iterator that points one past
......@@ -330,7 +335,7 @@ namespace __gnu_norm
* ordinary element order.
*/
const_iterator
end() const { return const_iterator (this->_M_finish); }
end() const { return const_iterator (this->_M_impl._M_finish); }
/**
* Returns a read/write reverse iterator that points to the
......@@ -412,7 +417,7 @@ namespace __gnu_norm
*/
size_type
capacity() const
{ return size_type(const_iterator(this->_M_end_of_storage) - begin()); }
{ return size_type(const_iterator(this->_M_impl._M_end_of_storage) - begin()); }
/**
* Returns true if the %vector is empty. (Thus begin() would
......@@ -550,10 +555,10 @@ namespace __gnu_norm
void
push_back(const value_type& __x)
{
if (this->_M_finish != this->_M_end_of_storage)
if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
{
std::_Construct(this->_M_finish, __x);
++this->_M_finish;
std::_Construct(this->_M_impl._M_finish, __x);
++this->_M_impl._M_finish;
}
else
_M_insert_aux(end(), __x);
......@@ -571,8 +576,8 @@ namespace __gnu_norm
void
pop_back()
{
--this->_M_finish;
std::_Destroy(this->_M_finish);
--this->_M_impl._M_finish;
std::_Destroy(this->_M_impl._M_finish);
}
/**
......@@ -681,9 +686,9 @@ namespace __gnu_norm
void
swap(vector& __x)
{
std::swap(this->_M_start, __x._M_start);
std::swap(this->_M_finish, __x._M_finish);
std::swap(this->_M_end_of_storage, __x._M_end_of_storage);
std::swap(this->_M_impl._M_start, __x._M_impl._M_start);
std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish);
std::swap(this->_M_impl._M_end_of_storage, __x._M_impl._M_end_of_storage);
}
/**
......@@ -728,9 +733,9 @@ namespace __gnu_norm
void
_M_initialize_dispatch(_Integer __n, _Integer __value, __true_type)
{
this->_M_start = _M_allocate(__n);
this->_M_end_of_storage = this->_M_start + __n;
this->_M_finish = std::uninitialized_fill_n(this->_M_start,
this->_M_impl._M_start = _M_allocate(__n);
this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
this->_M_impl._M_finish = std::uninitialized_fill_n(this->_M_impl._M_start,
__n, __value);
}
......@@ -762,10 +767,10 @@ namespace __gnu_norm
_ForwardIterator __last, forward_iterator_tag)
{
size_type __n = std::distance(__first, __last);
this->_M_start = this->_M_allocate(__n);
this->_M_end_of_storage = this->_M_start + __n;
this->_M_finish = std::uninitialized_copy(__first, __last,
this->_M_start);
this->_M_impl._M_start = this->_M_allocate(__n);
this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
this->_M_impl._M_finish = std::uninitialized_copy(__first, __last,
this->_M_impl._M_start);
}
......
// 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