This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[smart containers] _M_clear()
- From: "Phil Bouchard" <philippe at fornux dot com>
- To: libstdc++ at gcc dot gnu dot org
- Date: Fri, 26 Sep 2008 06:57:50 -0700
- Subject: [smart containers] _M_clear()
Ok Bob,
I've got something that makes sense here and won't require you adding new
member functions to the _Pointer_adapter. The following is a copy of how a
list is currently cleared, to refresh everybody's memory:
template<typename _Tp, typename _Alloc>
void
_List_base<_Tp,_Alloc>::
_M_clear()
{
typedef _List_node<_Tp,_Alloc> _Node;
typedef _List_node_base<_Alloc> _Node_base;
typename _Node_base::pointer* __cur = & this->_M_impl._M_node->_M_next;
while (__cur != & this->_M_impl._M_node)
{
typename _Node_base::pointer* __tmp = __cur;
__cur = & (*__cur)->_M_next;
_M_impl._Node_Alloc_type::destroy(*(typename _Node::pointer*)
__tmp);
_M_put_node(*(typename _Node::pointer*) __tmp);
}
}
Now here is the logic I suggest (untested) for _M_clear() to handle raw C
pointers and smart pointers having "allocator::destroy(pointer &)"
simultaneously. The pointer is passed in as a reference to destroy() and
deallocate():
template <typename T>
class smart_ptr
{
...
element_type * release()
{
element_type * __p = pointer_ref();
pointer_ref() = 0;
if (-- counter_ref())
return 0;
else
return __p;
}
};
template <typename T>
class smart_allocator
{
...
typedef T value_type;
typedef smart<T> element_type;
typedef smart_ptr<T> pointer;
typedef smart_ptr<const T> const_pointer;
...
void destroy(pointer & p)
{
delete p.release();
}
void deallocate(pointer & p, size_type)
{
}
};
template<typename _Tp, typename _Alloc>
void
_List_base<_Tp,_Alloc>::
_M_clear()
{
typedef _List_node<_Tp,_Alloc> _Node;
typedef _List_node_base<_Alloc> _Node_base;
typename _Node_base::pointer* __cur = & this->_M_impl._M_node->_M_next;
while (__cur != & this->_M_impl._M_node)
{
typename _Node_base::pointer* __next = & (*__cur)->_M_next;
_M_impl._Node_Alloc_type::destroy(*(typename _Node::pointer*)
__cur);
_M_put_node(*(typename _Node::pointer*) __cur);
if (! *__cur) break; // (*__cur) might equal 0 if it is a smart
pointer
__cur = next;
}
}
The same code can be used to handle C pointers and smart pointers but the
latter one will obviously need residing headers.
Just go on the way _Pointer_adapter currently is and I will use it
accordingly.
Thanks,
-Phil