dlist.h 6.95 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
/*
 * This program source code file is part of KICAD, a free EDA CAD application.
 *
 * Copyright (C) 2008 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
 * Copyright (C) 1992-2008 Kicad Developers, see change_log.txt for contributors.
 *
 * This program 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
 * of the License, or (at your option) any later version.
 *
 * This program 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 program; if not, you may find one here:
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * or you may search the http://www.gnu.org website for the version 2 license,
 * or you may write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 */


#ifndef DLIST_H_
#define DLIST_H_


30 31 32
#include <stdio.h>          // NULL definition.


33
class EDA_ITEM;
34 35 36 37 38 39 40 41 42


/**
 * Class DHEAD
 * is only for use by template class DLIST, use that instead.
 */
class DHEAD
{
protected:
43 44 45 46
    EDA_ITEM*     first;          ///< first element in list, or NULL if list empty
    EDA_ITEM*     last;           ///< last elment in list, or NULL if empty
    unsigned      count;          ///< how many elements are in the list, automatically maintained.
    bool          meOwner;        ///< I must delete the objects I hold in my destructor
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63

    /**
     * Constructor DHEAD
     * is protected so that a DHEAD can only be instantiated from within a
     * DLIST template.
     */
    DHEAD() :
        first(0),
        last(0),
        count(0),
        meOwner(true)
    {
    }

    ~DHEAD();

    /**
dickelbeck's avatar
dickelbeck committed
64
     * Function append
65
     * adds \a aNewElement to the end of the list.
66
     * @param aNewElement The element to insert.
67
     */
68
    void append( EDA_ITEM* aNewElement );
69

70 71 72 73 74 75 76
    /**
     * Function append
     * adds \a aList to the end of the list.
     * @param aList The list to aList.
     */
    void append( DHEAD& aList );

77
    /**
dickelbeck's avatar
dickelbeck committed
78
     * Function insert
79 80
     * puts \a aNewElement just in front of \a aElementAfterMe in the list sequence.
     * If \a aElementAfterMe is NULL, then simply append().
81 82
     * @param aNewElement The element to insert.
     * @param aElementAfterMe The element to insert \a aNewElement before,
83
     *                        if NULL then append \a aNewElement onto end of list.
84
     */
85
    void insert( EDA_ITEM* aNewElement, EDA_ITEM* aElementAfterMe );
86 87

    /**
dickelbeck's avatar
dickelbeck committed
88
     * Function insert
89 90
     * puts \a aNewElement in front of list sequence.
     * @param aNewElement The element to insert.
91
     */
92
    void insert( EDA_ITEM* aNewElement )
93
    {
dickelbeck's avatar
dickelbeck committed
94
        insert( aNewElement, first );
95 96 97
    }

    /**
dickelbeck's avatar
dickelbeck committed
98
     * Function remove
99
     * removes \a aElement from the list, but does not delete it.
100
     * @param aElement The element to remove.
101
     */
102
    void remove( EDA_ITEM* aElement );
103

104 105 106 107

public:

    /**
dickelbeck's avatar
dickelbeck committed
108 109 110
     * Function DeleteAll
     * deletes all items on the list and leaves the list empty.  The destructor
     * for each item is called.
111
     */
dickelbeck's avatar
dickelbeck committed
112
    void DeleteAll();
113 114 115 116 117 118 119 120 121

    /**
     * Function SetOwnership
     * controls whether the list owns the objects and is responsible for
     * deleteing their memory at time of this object's destruction.
     */
    void SetOwnership( bool Iown ) { meOwner = Iown; }


122 123 124 125
    /**
     * Function GetCount
     * returns the number of elements in the list.
     */
126
    unsigned GetCount() const { return count; }
dickelbeck's avatar
dickelbeck committed
127 128 129 130

#if defined(DEBUG)
    void VerifyListIntegrity();
#endif
131 132 133 134 135 136 137
};


/**
 * Class DLIST
 * is the head of a doubly linked list.  It contains pointers to the first
 * and last elements in a doubly linked list.  The elements in the list must
138
 * be of class T or derived from T, and T must be derived from EDA_ITEM.
139
 * @see DHEAD for additional public functions.
140 141 142 143 144 145 146 147
 */
template <class T>
class DLIST : public DHEAD
{
public:

    /**
     * operator T*
dickelbeck's avatar
dickelbeck committed
148
     * is a casting operator that returns \a GetFirst(), a T*
149 150 151
     */
    operator T* () const { return GetFirst(); }

dickelbeck's avatar
dickelbeck committed
152 153 154 155 156 157
    /**
     * operator ->
     * is a dereferencing operator that returns \a GetFirst(), a T*
     */
    T* operator -> () const { return GetFirst(); }

158 159
    /**
     * Function GetFirst
dickelbeck's avatar
dickelbeck committed
160 161
     * returns the first T* in the list without removing it, or NULL if
     * the list is empty.
162 163 164 165 166
     */
    T*  GetFirst() const { return (T*) first; }

    /**
     * Function GetLast
dickelbeck's avatar
dickelbeck committed
167 168
     * returns the last T* in the list without removing it,
     * or NULL if the list is empty.
169 170
     */
    T*  GetLast() const { return (T*) last; }
171 172 173 174

    /**
     * Function Append
     * adds \a aNewElement to the end of the list.
175
     * @param aNewElement The element to insert.
176 177 178
     */
    void Append( T* aNewElement )
    {
dickelbeck's avatar
dickelbeck committed
179
        append( aNewElement );
180 181
    }

182 183 184 185 186 187 188 189 190 191
    /**
     * Function Append
     * adds \a aList to the end of the list.
     * @param aList The list to append to the end of the list.
     */
    void Append( DLIST& aList )
    {
        append( aList );
    }

192 193
    /**
     * Function Insert
194
     * puts \a aNewElement just in front of \a aElementAfterMe in the list sequence.
195
     * If aElementAfterMe is NULL, then simply Append()
196 197 198
     * @param aNewElement The element to insert.
     * @param aElementAfterMe The element to insert \a aNewElement before,
     *                        if NULL then append \a aNewElement onto end of list.
199 200 201
     */
    void Insert( T* aNewElement, T* aElementAfterMe )
    {
dickelbeck's avatar
dickelbeck committed
202
        insert( aNewElement, aElementAfterMe );
203 204 205 206 207
    }

    /**
     * Function Remove
     * removes \a aElement from the list, but does not delete it.
208
     * @param aElement The element to remove from the list.
dickelbeck's avatar
dickelbeck committed
209
     * @return T* - the removed element, so you can easily delete it upon return.
210
     */
dickelbeck's avatar
dickelbeck committed
211
    T* Remove( T* aElement )
212
    {
dickelbeck's avatar
dickelbeck committed
213 214
        remove( aElement );
        return aElement;
215 216
    }

dickelbeck's avatar
dickelbeck committed
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
    //-----< STL like functions >---------------------------------------
    T* begin() const { return GetFirst(); }
    T* end() const { return NULL; }

    T* PopFront()
    {
        if( GetFirst() )
            return Remove( GetFirst() );
        return NULL;
    }

    T* PopBack()
    {
        if( GetLast() )
            return Remove( GetLast() );
        return NULL;
    }

    /**
     * Function PushFront
     * puts aNewElement at front of list sequence.
238
     * @param aNewElement The element to insert at the front of the list.
dickelbeck's avatar
dickelbeck committed
239 240 241 242 243 244
     */
    void PushFront( T* aNewElement )
    {
        insert( aNewElement );
    }

245 246 247
    /**
     * Function PushBack
     * puts aNewElement at the end of the list sequence.
248
     * @param aNewElement The element to push to the end of the list.
249 250
     */
    void PushBack( T* aNewElement )
dickelbeck's avatar
dickelbeck committed
251
    {
252
        append( aNewElement );
dickelbeck's avatar
dickelbeck committed
253 254 255
    }

    //-----</ STL like functions >--------------------------------------
256 257 258
};

#endif      // DLIST_H_