849 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			849 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
///////////////////////////////////////////////////////////////////////////////
 | 
						|
// Name:        wx/dlist.h
 | 
						|
// Purpose:     wxDList<T> which is a template version of wxList
 | 
						|
// Author:      Robert Roebling
 | 
						|
// Created:     18.09.2008
 | 
						|
// Copyright:   (c) 2008 wxWidgets team
 | 
						|
// Licence:     wxWindows licence
 | 
						|
///////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
#ifndef _WX_DLIST_H_
 | 
						|
#define _WX_DLIST_H_
 | 
						|
 | 
						|
#include "wx/defs.h"
 | 
						|
#include "wx/utils.h"
 | 
						|
 | 
						|
#if wxUSE_STD_CONTAINERS
 | 
						|
 | 
						|
#include "wx/beforestd.h"
 | 
						|
#include <algorithm>
 | 
						|
#include <iterator>
 | 
						|
#include <list>
 | 
						|
#include "wx/afterstd.h"
 | 
						|
 | 
						|
template<typename T>
 | 
						|
class wxDList: public std::list<T*>
 | 
						|
{
 | 
						|
private:
 | 
						|
    bool m_destroy;
 | 
						|
    typedef std::list<T*> BaseListType;
 | 
						|
    typedef wxDList<T> ListType;
 | 
						|
 | 
						|
public:
 | 
						|
    typedef typename BaseListType::iterator iterator;
 | 
						|
 | 
						|
    class compatibility_iterator
 | 
						|
    {
 | 
						|
    private:
 | 
						|
        friend class wxDList<T>;
 | 
						|
 | 
						|
        iterator m_iter;
 | 
						|
        ListType *m_list;
 | 
						|
 | 
						|
    public:
 | 
						|
        compatibility_iterator()
 | 
						|
            : m_iter(), m_list( NULL ) {}
 | 
						|
        compatibility_iterator( ListType* li, iterator i )
 | 
						|
            : m_iter( i ), m_list( li ) {}
 | 
						|
        compatibility_iterator( const ListType* li, iterator i )
 | 
						|
            : m_iter( i ), m_list( const_cast<ListType*>(li) ) {}
 | 
						|
 | 
						|
        compatibility_iterator* operator->() { return this; }
 | 
						|
        const compatibility_iterator* operator->() const { return this; }
 | 
						|
 | 
						|
        bool operator==(const compatibility_iterator& i) const
 | 
						|
        {
 | 
						|
            wxASSERT_MSG( m_list && i.m_list,
 | 
						|
                          "comparing invalid iterators is illegal" );
 | 
						|
            return (m_list == i.m_list) && (m_iter == i.m_iter);
 | 
						|
        }
 | 
						|
        bool operator!=(const compatibility_iterator& i) const
 | 
						|
            { return !( operator==( i ) ); }
 | 
						|
        operator bool() const
 | 
						|
            { return m_list ? m_iter != m_list->end() : false; }
 | 
						|
        bool operator !() const
 | 
						|
            { return !( operator bool() ); }
 | 
						|
 | 
						|
        T* GetData() const { return *m_iter; }
 | 
						|
        void SetData( T* e ) { *m_iter = e; }
 | 
						|
 | 
						|
        compatibility_iterator GetNext() const
 | 
						|
        {
 | 
						|
            iterator i = m_iter;
 | 
						|
            return compatibility_iterator( m_list, ++i );
 | 
						|
        }
 | 
						|
 | 
						|
        compatibility_iterator GetPrevious() const
 | 
						|
        {
 | 
						|
            if ( m_iter == m_list->begin() )
 | 
						|
                return compatibility_iterator();
 | 
						|
 | 
						|
            iterator i = m_iter;
 | 
						|
            return compatibility_iterator( m_list, --i );
 | 
						|
        }
 | 
						|
 | 
						|
        int IndexOf() const
 | 
						|
        {
 | 
						|
            return *this ? std::distance( m_list->begin(), m_iter )
 | 
						|
                : wxNOT_FOUND;
 | 
						|
        }
 | 
						|
    };
 | 
						|
 | 
						|
public:
 | 
						|
    wxDList() : m_destroy( false ) {}
 | 
						|
 | 
						|
    ~wxDList() { Clear(); }
 | 
						|
 | 
						|
    compatibility_iterator Find( const T* e ) const
 | 
						|
    {
 | 
						|
        return compatibility_iterator( this,
 | 
						|
                std::find( const_cast<ListType*>(this)->begin(),
 | 
						|
                           const_cast<ListType*>(this)->end(), e ) );
 | 
						|
    }
 | 
						|
 | 
						|
    bool IsEmpty() const
 | 
						|
        { return this->empty(); }
 | 
						|
    size_t GetCount() const
 | 
						|
        { return this->size(); }
 | 
						|
 | 
						|
    compatibility_iterator Item( size_t idx ) const
 | 
						|
    {
 | 
						|
        iterator i = const_cast<ListType*>(this)->begin();
 | 
						|
        std::advance( i, idx );
 | 
						|
        return compatibility_iterator( this, i );
 | 
						|
    }
 | 
						|
 | 
						|
    T* operator[](size_t idx) const
 | 
						|
    {
 | 
						|
        return Item(idx).GetData();
 | 
						|
    }
 | 
						|
 | 
						|
    compatibility_iterator GetFirst() const
 | 
						|
    {
 | 
						|
        return compatibility_iterator( this, const_cast<ListType*>(this)->begin() );
 | 
						|
    }
 | 
						|
    compatibility_iterator GetLast() const
 | 
						|
    {
 | 
						|
        iterator i = const_cast<ListType*>(this)->end();
 | 
						|
        return compatibility_iterator( this, !(this->empty()) ? --i : i );
 | 
						|
    }
 | 
						|
    compatibility_iterator Member( T* e ) const
 | 
						|
        { return Find( e ); }
 | 
						|
    compatibility_iterator Nth( int n ) const
 | 
						|
        { return Item( n ); }
 | 
						|
    int IndexOf( T* e ) const
 | 
						|
        { return Find( e ).IndexOf(); }
 | 
						|
 | 
						|
    compatibility_iterator Append( T* e )
 | 
						|
    {
 | 
						|
        this->push_back( e );
 | 
						|
        return GetLast();
 | 
						|
    }
 | 
						|
 | 
						|
    compatibility_iterator Insert( T* e )
 | 
						|
    {
 | 
						|
        this->push_front( e );
 | 
						|
        return compatibility_iterator( this, this->begin() );
 | 
						|
    }
 | 
						|
 | 
						|
    compatibility_iterator Insert( compatibility_iterator & i, T* e )
 | 
						|
    {
 | 
						|
        return compatibility_iterator( this, this->insert( i.m_iter, e ) );
 | 
						|
    }
 | 
						|
 | 
						|
    compatibility_iterator Insert( size_t idx, T* e )
 | 
						|
    {
 | 
						|
        return compatibility_iterator( this,
 | 
						|
                this->insert( Item( idx ).m_iter, e ) );
 | 
						|
    }
 | 
						|
 | 
						|
    void DeleteContents( bool destroy )
 | 
						|
        { m_destroy = destroy; }
 | 
						|
 | 
						|
    bool GetDeleteContents() const
 | 
						|
        { return m_destroy; }
 | 
						|
 | 
						|
    void Erase( const compatibility_iterator& i )
 | 
						|
    {
 | 
						|
        if ( m_destroy )
 | 
						|
            delete i->GetData();
 | 
						|
        this->erase( i.m_iter );
 | 
						|
    }
 | 
						|
 | 
						|
    bool DeleteNode( const compatibility_iterator& i )
 | 
						|
    {
 | 
						|
        if( i )
 | 
						|
        {
 | 
						|
            Erase( i );
 | 
						|
            return true;
 | 
						|
        }
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    bool DeleteObject( T* e )
 | 
						|
    {
 | 
						|
        return DeleteNode( Find( e ) );
 | 
						|
    }
 | 
						|
 | 
						|
    void Clear()
 | 
						|
    {
 | 
						|
        if ( m_destroy )
 | 
						|
        {
 | 
						|
            iterator it, en;
 | 
						|
            for ( it = this->begin(), en = this->end(); it != en; ++it )
 | 
						|
                delete *it;
 | 
						|
        }
 | 
						|
        this->clear();
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
#else  // !wxUSE_STD_CONTAINERS
 | 
						|
 | 
						|
template <typename T>
 | 
						|
class wxDList
 | 
						|
{
 | 
						|
public:
 | 
						|
    class Node
 | 
						|
    {
 | 
						|
    public:
 | 
						|
        Node(wxDList<T> *list = NULL,
 | 
						|
             Node *previous = NULL,
 | 
						|
             Node *next = NULL,
 | 
						|
             T *data = NULL)
 | 
						|
        {
 | 
						|
            m_list = list;
 | 
						|
            m_previous = previous;
 | 
						|
            m_next = next;
 | 
						|
            m_data = data;
 | 
						|
            if (previous)
 | 
						|
                previous->m_next = this;
 | 
						|
            if (next)
 | 
						|
                next->m_previous = this;
 | 
						|
        }
 | 
						|
 | 
						|
        ~Node()
 | 
						|
        {
 | 
						|
            // handle the case when we're being deleted from the list by
 | 
						|
            // the user (i.e. not by the list itself from DeleteNode) -
 | 
						|
            // we must do it for compatibility with old code
 | 
						|
            if (m_list != NULL)
 | 
						|
                m_list->DetachNode(this);
 | 
						|
        }
 | 
						|
 | 
						|
        void DeleteData()
 | 
						|
        {
 | 
						|
            delete m_data;
 | 
						|
        }
 | 
						|
 | 
						|
        Node *GetNext() const      { return m_next; }
 | 
						|
        Node *GetPrevious() const  { return m_previous; }
 | 
						|
        T *GetData() const         { return m_data; }
 | 
						|
        T **GetDataPtr() const     { return &(const_cast<nodetype*>(this)->m_data); }
 | 
						|
        void SetData( T *data )    { m_data = data; }
 | 
						|
 | 
						|
        int IndexOf() const
 | 
						|
        {
 | 
						|
            wxCHECK_MSG( m_list, wxNOT_FOUND,
 | 
						|
                         "node doesn't belong to a list in IndexOf" );
 | 
						|
 | 
						|
            int i;
 | 
						|
            Node *prev = m_previous;
 | 
						|
            for( i = 0; prev; i++ )
 | 
						|
                prev = prev->m_previous;
 | 
						|
            return i;
 | 
						|
        }
 | 
						|
 | 
						|
    private:
 | 
						|
        T           *m_data;        // user data
 | 
						|
        Node        *m_next,        // next and previous nodes in the list
 | 
						|
                    *m_previous;
 | 
						|
        wxDList<T>   *m_list;         // list we belong to
 | 
						|
 | 
						|
        friend class wxDList<T>;
 | 
						|
    };
 | 
						|
 | 
						|
    typedef Node nodetype;
 | 
						|
 | 
						|
    class compatibility_iterator
 | 
						|
    {
 | 
						|
    public:
 | 
						|
        compatibility_iterator(nodetype *ptr = NULL) : m_ptr(ptr) { }
 | 
						|
        nodetype *operator->() const { return m_ptr; }
 | 
						|
        operator nodetype *() const  { return m_ptr; }
 | 
						|
 | 
						|
    private:
 | 
						|
        nodetype *m_ptr;
 | 
						|
    };
 | 
						|
 | 
						|
private:
 | 
						|
    void Init()
 | 
						|
    {
 | 
						|
        m_nodeFirst =
 | 
						|
        m_nodeLast = NULL;
 | 
						|
        m_count = 0;
 | 
						|
        m_destroy = false;
 | 
						|
    }
 | 
						|
 | 
						|
    void DoDeleteNode( nodetype *node )
 | 
						|
    {
 | 
						|
        if ( m_destroy )
 | 
						|
            node->DeleteData();
 | 
						|
        // so that the node knows that it's being deleted by the list
 | 
						|
        node->m_list = NULL;
 | 
						|
        delete node;
 | 
						|
    }
 | 
						|
 | 
						|
    size_t m_count;             // number of elements in the list
 | 
						|
    bool m_destroy;             // destroy user data when deleting list items?
 | 
						|
    nodetype *m_nodeFirst,      // pointers to the head and tail of the list
 | 
						|
             *m_nodeLast;
 | 
						|
 | 
						|
public:
 | 
						|
    wxDList()
 | 
						|
    {
 | 
						|
        Init();
 | 
						|
    }
 | 
						|
 | 
						|
    wxDList( const wxDList<T>& list )
 | 
						|
    {
 | 
						|
        Init();
 | 
						|
        Assign(list);
 | 
						|
    }
 | 
						|
 | 
						|
    wxDList( size_t count, T *elements[] )
 | 
						|
    {
 | 
						|
        Init();
 | 
						|
        size_t n;
 | 
						|
        for (n = 0; n < count; n++)
 | 
						|
            Append( elements[n] );
 | 
						|
    }
 | 
						|
 | 
						|
    wxDList& operator=( const wxDList<T>& list )
 | 
						|
    {
 | 
						|
        if (&list != this)
 | 
						|
            Assign(list);
 | 
						|
        return *this;
 | 
						|
    }
 | 
						|
 | 
						|
    ~wxDList()
 | 
						|
    {
 | 
						|
        nodetype *each = m_nodeFirst;
 | 
						|
        while ( each != NULL )
 | 
						|
        {
 | 
						|
            nodetype *next = each->GetNext();
 | 
						|
                DoDeleteNode(each);
 | 
						|
            each = next;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    void Assign(const wxDList<T> &list)
 | 
						|
    {
 | 
						|
        wxASSERT_MSG( !list.m_destroy,
 | 
						|
                      "copying list which owns it's elements is a bad idea" );
 | 
						|
        Clear();
 | 
						|
        m_destroy = list.m_destroy;
 | 
						|
        m_nodeFirst = NULL;
 | 
						|
        m_nodeLast = NULL;
 | 
						|
        nodetype* node;
 | 
						|
        for (node = list.GetFirst(); node; node = node->GetNext() )
 | 
						|
            Append(node->GetData());
 | 
						|
        wxASSERT_MSG( m_count == list.m_count, "logic error in Assign()" );
 | 
						|
    }
 | 
						|
 | 
						|
    nodetype *Append( T *object )
 | 
						|
    {
 | 
						|
        nodetype *node = new nodetype( this, m_nodeLast, NULL, object );
 | 
						|
 | 
						|
        if ( !m_nodeFirst )
 | 
						|
        {
 | 
						|
            m_nodeFirst = node;
 | 
						|
            m_nodeLast = m_nodeFirst;
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            m_nodeLast->m_next = node;
 | 
						|
            m_nodeLast = node;
 | 
						|
        }
 | 
						|
        m_count++;
 | 
						|
        return node;
 | 
						|
    }
 | 
						|
 | 
						|
    nodetype *Insert( T* object )
 | 
						|
    {
 | 
						|
        return Insert( NULL, object );
 | 
						|
    }
 | 
						|
 | 
						|
    nodetype *Insert( size_t pos, T* object )
 | 
						|
    {
 | 
						|
        if (pos == m_count)
 | 
						|
            return Append( object );
 | 
						|
        else
 | 
						|
            return Insert( Item(pos), object );
 | 
						|
    }
 | 
						|
 | 
						|
    nodetype *Insert( nodetype *position, T* object )
 | 
						|
    {
 | 
						|
        wxCHECK_MSG( !position || position->m_list == this, NULL,
 | 
						|
                     "can't insert before a node from another list" );
 | 
						|
 | 
						|
        // previous and next node for the node being inserted
 | 
						|
        nodetype *prev, *next;
 | 
						|
        if ( position )
 | 
						|
        {
 | 
						|
           prev = position->GetPrevious();
 | 
						|
           next = position;
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            // inserting in the beginning of the list
 | 
						|
            prev = NULL;
 | 
						|
            next = m_nodeFirst;
 | 
						|
        }
 | 
						|
        nodetype *node = new nodetype( this, prev, next, object );
 | 
						|
        if ( !m_nodeFirst )
 | 
						|
            m_nodeLast = node;
 | 
						|
        if ( prev == NULL )
 | 
						|
            m_nodeFirst = node;
 | 
						|
        m_count++;
 | 
						|
        return node;
 | 
						|
    }
 | 
						|
 | 
						|
    nodetype *GetFirst() const { return m_nodeFirst; }
 | 
						|
    nodetype *GetLast() const { return m_nodeLast; }
 | 
						|
    size_t GetCount() const { return m_count; }
 | 
						|
    bool IsEmpty() const { return m_count == 0; }
 | 
						|
 | 
						|
    void DeleteContents(bool destroy) { m_destroy = destroy; }
 | 
						|
    bool GetDeleteContents() const { return m_destroy; }
 | 
						|
 | 
						|
    nodetype *Item(size_t index) const
 | 
						|
    {
 | 
						|
        for ( nodetype *current = GetFirst(); current; current = current->GetNext() )
 | 
						|
        {
 | 
						|
            if ( index-- == 0 )
 | 
						|
               return current;
 | 
						|
        }
 | 
						|
        wxFAIL_MSG( "invalid index in Item()" );
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    T *operator[](size_t index) const
 | 
						|
    {
 | 
						|
        nodetype *node = Item(index);
 | 
						|
        return node ? node->GetData() : NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    nodetype *DetachNode( nodetype *node )
 | 
						|
    {
 | 
						|
        wxCHECK_MSG( node, NULL, "detaching NULL wxNodeBase" );
 | 
						|
        wxCHECK_MSG( node->m_list == this, NULL,
 | 
						|
                     "detaching node which is not from this list" );
 | 
						|
        // update the list
 | 
						|
        nodetype **prevNext = node->GetPrevious() ? &node->GetPrevious()->m_next
 | 
						|
                                                  : &m_nodeFirst;
 | 
						|
        nodetype **nextPrev = node->GetNext() ? &node->GetNext()->m_previous
 | 
						|
                                              : &m_nodeLast;
 | 
						|
        *prevNext = node->GetNext();
 | 
						|
        *nextPrev = node->GetPrevious();
 | 
						|
        m_count--;
 | 
						|
        // mark the node as not belonging to this list any more
 | 
						|
        node->m_list = NULL;
 | 
						|
        return node;
 | 
						|
    }
 | 
						|
 | 
						|
    void Erase( nodetype *node )
 | 
						|
    {
 | 
						|
         DeleteNode(node);
 | 
						|
    }
 | 
						|
 | 
						|
    bool DeleteNode( nodetype *node )
 | 
						|
    {
 | 
						|
        if ( !DetachNode(node) )
 | 
						|
           return false;
 | 
						|
        DoDeleteNode(node);
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
 | 
						|
    bool DeleteObject( T *object )
 | 
						|
    {
 | 
						|
        for ( nodetype *current = GetFirst(); current; current = current->GetNext() )
 | 
						|
        {
 | 
						|
            if ( current->GetData() == object )
 | 
						|
            {
 | 
						|
                DeleteNode(current);
 | 
						|
                return true;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        // not found
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    nodetype *Find(const T *object) const
 | 
						|
    {
 | 
						|
        for ( nodetype *current = GetFirst(); current; current = current->GetNext() )
 | 
						|
        {
 | 
						|
            if ( current->GetData() == object )
 | 
						|
                return current;
 | 
						|
        }
 | 
						|
        // not found
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    int IndexOf(const T *object) const
 | 
						|
    {
 | 
						|
        int n = 0;
 | 
						|
        for ( nodetype *current = GetFirst(); current; current = current->GetNext() )
 | 
						|
        {
 | 
						|
            if ( current->GetData() == object )
 | 
						|
                return n;
 | 
						|
            n++;
 | 
						|
        }
 | 
						|
        return wxNOT_FOUND;
 | 
						|
    }
 | 
						|
 | 
						|
    void Clear()
 | 
						|
    {
 | 
						|
        nodetype *current = m_nodeFirst;
 | 
						|
        while ( current )
 | 
						|
        {
 | 
						|
            nodetype *next = current->GetNext();
 | 
						|
            DoDeleteNode(current);
 | 
						|
            current = next;
 | 
						|
        }
 | 
						|
        m_nodeFirst =
 | 
						|
        m_nodeLast = NULL;
 | 
						|
        m_count = 0;
 | 
						|
    }
 | 
						|
 | 
						|
    void Reverse()
 | 
						|
    {
 | 
						|
        nodetype * node = m_nodeFirst;
 | 
						|
        nodetype* tmp;
 | 
						|
        while (node)
 | 
						|
        {
 | 
						|
            // swap prev and next pointers
 | 
						|
            tmp = node->m_next;
 | 
						|
            node->m_next = node->m_previous;
 | 
						|
            node->m_previous = tmp;
 | 
						|
            // this is the node that was next before swapping
 | 
						|
            node = tmp;
 | 
						|
        }
 | 
						|
        // swap first and last node
 | 
						|
        tmp = m_nodeFirst; m_nodeFirst = m_nodeLast; m_nodeLast = tmp;
 | 
						|
    }
 | 
						|
 | 
						|
    void DeleteNodes(nodetype* first, nodetype* last)
 | 
						|
    {
 | 
						|
        nodetype * node = first;
 | 
						|
        while (node != last)
 | 
						|
        {
 | 
						|
            nodetype* next = node->GetNext();
 | 
						|
            DeleteNode(node);
 | 
						|
            node = next;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    void ForEach(wxListIterateFunction F)
 | 
						|
    {
 | 
						|
        for ( nodetype *current = GetFirst(); current; current = current->GetNext() )
 | 
						|
            (*F)(current->GetData());
 | 
						|
    }
 | 
						|
 | 
						|
    T *FirstThat(wxListIterateFunction F)
 | 
						|
    {
 | 
						|
        for ( nodetype *current = GetFirst(); current; current = current->GetNext() )
 | 
						|
        {
 | 
						|
            if ( (*F)(current->GetData()) )
 | 
						|
                return current->GetData();
 | 
						|
        }
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    T *LastThat(wxListIterateFunction F)
 | 
						|
    {
 | 
						|
        for ( nodetype *current = GetLast(); current; current = current->GetPrevious() )
 | 
						|
        {
 | 
						|
            if ( (*F)(current->GetData()) )
 | 
						|
                return current->GetData();
 | 
						|
        }
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    /* STL interface */
 | 
						|
public:
 | 
						|
    typedef size_t size_type;
 | 
						|
    typedef int difference_type;
 | 
						|
    typedef T* value_type;
 | 
						|
    typedef value_type& reference;
 | 
						|
    typedef const value_type& const_reference;
 | 
						|
 | 
						|
    class iterator
 | 
						|
    {
 | 
						|
    public:
 | 
						|
        typedef nodetype Node;
 | 
						|
        typedef iterator itor;
 | 
						|
        typedef T* value_type;
 | 
						|
        typedef value_type* ptr_type;
 | 
						|
        typedef value_type& reference;
 | 
						|
 | 
						|
        Node* m_node;
 | 
						|
        Node* m_init;
 | 
						|
    public:
 | 
						|
        typedef reference reference_type;
 | 
						|
        typedef ptr_type pointer_type;
 | 
						|
 | 
						|
        iterator(Node* node, Node* init) : m_node(node), m_init(init) {}
 | 
						|
        iterator() : m_node(NULL), m_init(NULL) { }
 | 
						|
        reference_type operator*() const
 | 
						|
            { return *m_node->GetDataPtr(); }
 | 
						|
        // ptrop
 | 
						|
        itor& operator++() { m_node = m_node->GetNext(); return *this; }
 | 
						|
        const itor operator++(int)
 | 
						|
            { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }
 | 
						|
        itor& operator--()
 | 
						|
        {
 | 
						|
            m_node = m_node ? m_node->GetPrevious() : m_init;
 | 
						|
            return *this;
 | 
						|
        }
 | 
						|
        const itor operator--(int)
 | 
						|
        {
 | 
						|
            itor tmp = *this;
 | 
						|
            m_node = m_node ? m_node->GetPrevious() : m_init;
 | 
						|
            return tmp;
 | 
						|
        }
 | 
						|
        bool operator!=(const itor& it) const
 | 
						|
            { return it.m_node != m_node; }
 | 
						|
        bool operator==(const itor& it) const
 | 
						|
            { return it.m_node == m_node; }
 | 
						|
    };
 | 
						|
    class const_iterator
 | 
						|
    {
 | 
						|
    public:
 | 
						|
        typedef nodetype Node;
 | 
						|
        typedef T* value_type;
 | 
						|
        typedef const value_type& const_reference;
 | 
						|
        typedef const_iterator itor;
 | 
						|
        typedef value_type* ptr_type;
 | 
						|
 | 
						|
        Node* m_node;
 | 
						|
        Node* m_init;
 | 
						|
    public:
 | 
						|
        typedef const_reference reference_type;
 | 
						|
        typedef const ptr_type pointer_type;
 | 
						|
 | 
						|
        const_iterator(Node* node, Node* init)
 | 
						|
            : m_node(node), m_init(init) { }
 | 
						|
        const_iterator() : m_node(NULL), m_init(NULL) { }
 | 
						|
        const_iterator(const iterator& it)
 | 
						|
            : m_node(it.m_node), m_init(it.m_init) { }
 | 
						|
        reference_type operator*() const
 | 
						|
            { return *m_node->GetDataPtr(); }
 | 
						|
        // ptrop
 | 
						|
        itor& operator++() { m_node = m_node->GetNext(); return *this; }
 | 
						|
        const itor operator++(int)
 | 
						|
            { itor tmp = *this; m_node = m_node->GetNext(); return tmp; }
 | 
						|
        itor& operator--()
 | 
						|
        {
 | 
						|
            m_node = m_node ? m_node->GetPrevious() : m_init;
 | 
						|
            return *this;
 | 
						|
        }
 | 
						|
        const itor operator--(int)
 | 
						|
        {
 | 
						|
            itor tmp = *this;
 | 
						|
            m_node = m_node ? m_node->GetPrevious() : m_init;
 | 
						|
            return tmp;
 | 
						|
        }
 | 
						|
        bool operator!=(const itor& it) const
 | 
						|
            { return it.m_node != m_node; }
 | 
						|
        bool operator==(const itor& it) const
 | 
						|
            { return it.m_node == m_node; }
 | 
						|
    };
 | 
						|
 | 
						|
    class reverse_iterator
 | 
						|
    {
 | 
						|
    public:
 | 
						|
        typedef nodetype Node;
 | 
						|
        typedef T* value_type;
 | 
						|
        typedef reverse_iterator itor;
 | 
						|
        typedef value_type* ptr_type;
 | 
						|
        typedef value_type& reference;
 | 
						|
 | 
						|
        Node* m_node;
 | 
						|
        Node* m_init;
 | 
						|
    public:
 | 
						|
        typedef reference reference_type;
 | 
						|
        typedef ptr_type pointer_type;
 | 
						|
 | 
						|
        reverse_iterator(Node* node, Node* init)
 | 
						|
            : m_node(node), m_init(init) { }
 | 
						|
        reverse_iterator() : m_node(NULL), m_init(NULL) { }
 | 
						|
        reference_type operator*() const
 | 
						|
            { return *m_node->GetDataPtr(); }
 | 
						|
        // ptrop
 | 
						|
        itor& operator++()
 | 
						|
            { m_node = m_node->GetPrevious(); return *this; }
 | 
						|
        const itor operator++(int)
 | 
						|
        { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }
 | 
						|
        itor& operator--()
 | 
						|
        { m_node = m_node ? m_node->GetNext() : m_init; return *this; }
 | 
						|
        const itor operator--(int)
 | 
						|
        {
 | 
						|
            itor tmp = *this;
 | 
						|
            m_node = m_node ? m_node->GetNext() : m_init;
 | 
						|
            return tmp;
 | 
						|
        }
 | 
						|
        bool operator!=(const itor& it) const
 | 
						|
            { return it.m_node != m_node; }
 | 
						|
        bool operator==(const itor& it) const
 | 
						|
            { return it.m_node == m_node; }
 | 
						|
    };
 | 
						|
 | 
						|
    class const_reverse_iterator
 | 
						|
    {
 | 
						|
    public:
 | 
						|
        typedef nodetype Node;
 | 
						|
        typedef T* value_type;
 | 
						|
        typedef const_reverse_iterator itor;
 | 
						|
        typedef value_type* ptr_type;
 | 
						|
        typedef const value_type& const_reference;
 | 
						|
 | 
						|
        Node* m_node;
 | 
						|
        Node* m_init;
 | 
						|
    public:
 | 
						|
        typedef const_reference reference_type;
 | 
						|
        typedef const ptr_type pointer_type;
 | 
						|
 | 
						|
        const_reverse_iterator(Node* node, Node* init)
 | 
						|
            : m_node(node), m_init(init) { }
 | 
						|
        const_reverse_iterator() : m_node(NULL), m_init(NULL) { }
 | 
						|
        const_reverse_iterator(const reverse_iterator& it)
 | 
						|
            : m_node(it.m_node), m_init(it.m_init) { }
 | 
						|
        reference_type operator*() const
 | 
						|
            { return *m_node->GetDataPtr(); }
 | 
						|
        // ptrop
 | 
						|
        itor& operator++()
 | 
						|
            { m_node = m_node->GetPrevious(); return *this; }
 | 
						|
        const itor operator++(int)
 | 
						|
        { itor tmp = *this; m_node = m_node->GetPrevious(); return tmp; }
 | 
						|
        itor& operator--()
 | 
						|
            { m_node = m_node ? m_node->GetNext() : m_init; return *this;}
 | 
						|
        const itor operator--(int)
 | 
						|
        {
 | 
						|
            itor tmp = *this;
 | 
						|
            m_node = m_node ? m_node->GetNext() : m_init;
 | 
						|
            return tmp;
 | 
						|
        }
 | 
						|
        bool operator!=(const itor& it) const
 | 
						|
            { return it.m_node != m_node; }
 | 
						|
        bool operator==(const itor& it) const
 | 
						|
            { return it.m_node == m_node; }
 | 
						|
    };
 | 
						|
 | 
						|
    explicit wxDList(size_type n, const_reference v = value_type())
 | 
						|
        { assign(n, v); }
 | 
						|
    wxDList(const const_iterator& first, const const_iterator& last)
 | 
						|
        { assign(first, last); }
 | 
						|
    iterator begin() { return iterator(GetFirst(), GetLast()); }
 | 
						|
    const_iterator begin() const
 | 
						|
        { return const_iterator(GetFirst(), GetLast()); }
 | 
						|
    iterator end() { return iterator(NULL, GetLast()); }
 | 
						|
    const_iterator end() const { return const_iterator(NULL, GetLast()); }
 | 
						|
    reverse_iterator rbegin()
 | 
						|
        { return reverse_iterator(GetLast(), GetFirst()); }
 | 
						|
    const_reverse_iterator rbegin() const
 | 
						|
        { return const_reverse_iterator(GetLast(), GetFirst()); }
 | 
						|
    reverse_iterator rend() { return reverse_iterator(NULL, GetFirst()); }
 | 
						|
    const_reverse_iterator rend() const
 | 
						|
        { return const_reverse_iterator(NULL, GetFirst()); }
 | 
						|
    void resize(size_type n, value_type v = value_type())
 | 
						|
    {
 | 
						|
        while (n < size())
 | 
						|
            pop_back();
 | 
						|
        while (n > size())
 | 
						|
            push_back(v);
 | 
						|
    }
 | 
						|
    size_type size() const { return GetCount(); }
 | 
						|
    size_type max_size() const { return INT_MAX; }
 | 
						|
    bool empty() const { return IsEmpty(); }
 | 
						|
    reference front() { return *begin(); }
 | 
						|
    const_reference front() const { return *begin(); }
 | 
						|
    reference back() { iterator tmp = end(); return *--tmp; }
 | 
						|
    const_reference back() const { const_iterator tmp = end(); return *--tmp; }
 | 
						|
    void push_front(const_reference v = value_type())
 | 
						|
        { Insert(GetFirst(), v); }
 | 
						|
    void pop_front() { DeleteNode(GetFirst()); }
 | 
						|
    void push_back(const_reference v = value_type())
 | 
						|
        { Append( v ); }
 | 
						|
    void pop_back() { DeleteNode(GetLast()); }
 | 
						|
    void assign(const_iterator first, const const_iterator& last)
 | 
						|
    {
 | 
						|
        clear();
 | 
						|
        for(; first != last; ++first)
 | 
						|
            Append(*first);
 | 
						|
    }
 | 
						|
    void assign(size_type n, const_reference v = value_type())
 | 
						|
    {
 | 
						|
        clear();
 | 
						|
        for(size_type i = 0; i < n; ++i)
 | 
						|
            Append(v);
 | 
						|
    }
 | 
						|
    iterator insert(const iterator& it, const_reference v)
 | 
						|
    {
 | 
						|
        if (it == end())
 | 
						|
            Append( v );
 | 
						|
        else
 | 
						|
            Insert(it.m_node,v);
 | 
						|
        iterator itprev(it);
 | 
						|
        return itprev--;
 | 
						|
    }
 | 
						|
    void insert(const iterator& it, size_type n, const_reference v)
 | 
						|
    {
 | 
						|
        for(size_type i = 0; i < n; ++i)
 | 
						|
            Insert(it.m_node, v);
 | 
						|
    }
 | 
						|
    void insert(const iterator& it, const_iterator first, const const_iterator& last)
 | 
						|
    {
 | 
						|
        for(; first != last; ++first)
 | 
						|
            Insert(it.m_node, *first);
 | 
						|
    }
 | 
						|
    iterator erase(const iterator& it)
 | 
						|
    {
 | 
						|
        iterator next = iterator(it.m_node->GetNext(), GetLast());
 | 
						|
        DeleteNode(it.m_node); return next;
 | 
						|
    }
 | 
						|
    iterator erase(const iterator& first, const iterator& last)
 | 
						|
    {
 | 
						|
        iterator next = last; ++next;
 | 
						|
        DeleteNodes(first.m_node, last.m_node);
 | 
						|
        return next;
 | 
						|
    }
 | 
						|
    void clear() { Clear(); }
 | 
						|
    void splice(const iterator& it, wxDList<T>& l, const iterator& first, const iterator& last)
 | 
						|
        { insert(it, first, last); l.erase(first, last); }
 | 
						|
    void splice(const iterator& it, wxDList<T>& l)
 | 
						|
        { splice(it, l, l.begin(), l.end() ); }
 | 
						|
    void splice(const iterator& it, wxDList<T>& l, const iterator& first)
 | 
						|
    {
 | 
						|
        iterator tmp = first; ++tmp;
 | 
						|
        if(it == first || it == tmp) return;
 | 
						|
        insert(it, *first);
 | 
						|
        l.erase(first);
 | 
						|
    }
 | 
						|
    void remove(const_reference v)
 | 
						|
        { DeleteObject(v); }
 | 
						|
    void reverse()
 | 
						|
        { Reverse(); }
 | 
						|
 /* void swap(list<T>& l)
 | 
						|
    {
 | 
						|
        { size_t t = m_count; m_count = l.m_count; l.m_count = t; }
 | 
						|
        { bool t = m_destroy; m_destroy = l.m_destroy; l.m_destroy = t; }
 | 
						|
        { wxNodeBase* t = m_nodeFirst; m_nodeFirst = l.m_nodeFirst; l.m_nodeFirst = t; }
 | 
						|
        { wxNodeBase* t = m_nodeLast; m_nodeLast = l.m_nodeLast; l.m_nodeLast = t; }
 | 
						|
        { wxKeyType t = m_keyType; m_keyType = l.m_keyType; l.m_keyType = t; }
 | 
						|
    } */
 | 
						|
};
 | 
						|
 | 
						|
#endif // wxUSE_STD_CONTAINERS/!wxUSE_STD_CONTAINERS
 | 
						|
 | 
						|
#endif // _WX_DLIST_H_
 |