Commit 4d3d0a8f authored by dickelbeck's avatar dickelbeck

doubly linked list base class and template for contained specific instantations

parent 43f75cda
/*
* 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
*/
#include "fctsys.h"
#include "dlist.h"
#include "base_struct.h"
/* Implement the class DHEAD from dlist.h */
DHEAD::~DHEAD()
{
if( meOwner )
DestructAll();
}
void DHEAD::DestructAll()
{
EDA_BaseStruct* next;
EDA_BaseStruct* item = first;
while( item )
{
next = item->Next();
delete item; // virtual destructor, class specific
item = next;
}
first = 0;
last = 0;
count = 0;
}
void DHEAD::Append( EDA_BaseStruct* aNewElement )
{
wxASSERT( aNewElement != NULL );
if( first ) // list is not empty, first is not touched
{
wxASSERT( last != NULL );
aNewElement->SetNext( 0 );
aNewElement->SetBack( last );
last->SetNext( aNewElement );
last = aNewElement;
}
else // list is empty, first and last are changed
{
aNewElement->SetNext( 0 );
aNewElement->SetBack( 0 );
first = aNewElement;
last = aNewElement;
}
aNewElement->SetList( this );
++count;
}
void DHEAD::Insert( EDA_BaseStruct* aNewElement, EDA_BaseStruct* aAfterMe )
{
wxASSERT( aNewElement != NULL );
if( !aAfterMe )
Append( aNewElement );
else
{
wxASSERT( aAfterMe->GetList() == this );
// the list cannot be empty if aAfterMe is supposedly on the list
wxASSERT( first && last );
if( first == aAfterMe )
{
aAfterMe->SetBack( aNewElement );
aNewElement->SetBack( 0 ); // first in list does not point back
aNewElement->SetNext( aAfterMe );
first = aNewElement;
}
else
{
EDA_BaseStruct* oldBack = aAfterMe->Back();
aAfterMe->SetBack( aNewElement );
aNewElement->SetBack( oldBack );
aNewElement->SetNext( aAfterMe );
oldBack->SetNext( aNewElement );
}
aNewElement->SetList( this );
++count;
}
}
void DHEAD::Remove( EDA_BaseStruct* aElement )
{
wxASSERT( aElement )
wxASSERT( aElement->GetList() == this );
if( aElement->Next() )
{
aElement->Next()->SetBack( aElement->Back() );
}
else
{
wxASSERT( last == aElement );
last = aElement->Back();
}
if( aElement->Back() )
{
aElement->Back()->SetNext( aElement->Back() );
}
else
{
wxASSERT( first == aElement );
first = aElement->Next();
}
aElement->SetBack( 0 );
aElement->SetNext( 0 );
aElement->SetList( 0 );
--count;
}
/*
* 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_
class EDA_BaseStruct;
/**
* Class DHEAD
* is only for use by template class DLIST, use that instead.
*/
class DHEAD
{
protected:
EDA_BaseStruct* first; ///< first element in list, or NULL if list empty
EDA_BaseStruct* last; ///< last elment in list, or NULL if empty
unsigned count; ///< how many elements are in the list
bool meOwner; ///< I must delete the objects in my destructor
/**
* 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();
public:
/**
* Function DestructAll
* deletes all items on the list and leaves the list empty.
*/
void DestructAll();
/**
* 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; }
/**
* Function Append
* adds \a aNewElement to the end of the list.
*/
void Append( EDA_BaseStruct* aNewElement );
/**
* Function Insert
* puts aNewElement just in front of aElementAfterMe in the list sequence.
* If aElementAfterMe is NULL, then simply Append()
*/
void Insert( EDA_BaseStruct* aNewElement, EDA_BaseStruct* aElementAfterMe );
/**
* Function Insert
* puts aNewElement in front of list sequence.
*/
void Insert( EDA_BaseStruct* aNewElement )
{
Insert( aNewElement, first );
}
/**
* Function Remove
* removes \a aElement from the list, but does not delete it.
*/
void Remove( EDA_BaseStruct* aElement );
/**
* Function GetCount
* returns the number of elements in the list.
*/
unsigned GetCount() { return count; }
};
/**
* 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
* be of class T or derived from T, and T must be derived from EDA_BaseStruct.
*/
template <class T>
class DLIST : public DHEAD
{
public:
/**
* operator T*
* is a casting operator that returns \a first casted to a T*
*/
operator T* () const { return GetFirst(); }
/**
* Function GetFirst
* returns the first T* in the list, or NULL if the list is empty.
*/
T* GetFirst() const { return (T*) first; }
/**
* Function GetLast
* returns the last T* in the list, or NULL if the list is empty.
*/
T* GetLast() const { return (T*) last; }
};
#endif // DLIST_H_
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