This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]