libyui

/data/gitorious.org/libyui/libyui-master/src/TreeItem.h

00001 /**************************************************************************
00002 Copyright (C) 2000 - 2010 Novell, Inc.
00003 All Rights Reserved.
00004 
00005 This program is free software; you can redistribute it and/or modify
00006 it under the terms of the GNU General Public License as published by
00007 the Free Software Foundation; either version 2 of the License, or
00008 (at your option) any later version.
00009 
00010 This program is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 GNU General Public License for more details.
00014 
00015 You should have received a copy of the GNU General Public License along
00016 with this program; if not, write to the Free Software Foundation, Inc.,
00017 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00018 
00019 **************************************************************************/
00020 
00021 
00022 
00023 /*---------------------------------------------------------------------\
00024 |                                                                      |
00025 |                      __   __    ____ _____ ____                      |
00026 |                      \ \ / /_ _/ ___|_   _|___ \                     |
00027 |                       \ V / _` \___ \ | |   __) |                    |
00028 |                        | | (_| |___) || |  / __/                     |
00029 |                        |_|\__,_|____/ |_| |_____|                    |
00030 |                                                                      |
00031 |                            General Utilities                         |
00032 |                                                        (C) SuSE GmbH |
00033 \----------------------------------------------------------------------/
00034 
00035   File:         TreeItem.h
00036 
00037   Author:       Stefan Hundhammer <sh@suse.de>
00038 
00039 /-*/
00040 
00041 #ifndef TreeItem_h
00042 #define TreeItem_h
00043 
00044 #include <string>
00045 
00046 
00047 
00048 
00056 template<class PAYLOAD> class TreeItem
00057 {
00058 public:
00059 
00065     TreeItem<PAYLOAD> ( const PAYLOAD &         val,
00066                         TreeItem<PAYLOAD> *     parent = 0 )
00067         : _value( val )
00068         , _parent( parent )
00069         , _next(0)
00070         , _firstChild(0)
00071     {
00072         if ( _parent )
00073             _parent->addChild( this );
00074     }
00075 
00076 
00077 protected:
00078 
00085     TreeItem<PAYLOAD> ( PAYLOAD                 val,
00086                         bool                    autoAddChild,
00087                         TreeItem<PAYLOAD> *     parent = 0 )
00088         : _value( val )
00089         , _parent( parent )
00090         , _next(0)
00091         , _firstChild(0)
00092     {
00093         if ( _parent && autoAddChild )
00094             _parent->addChild( this );
00095     }
00096 
00097 
00098 private:
00103     TreeItem<PAYLOAD>             ( const TreeItem<PAYLOAD> & ) {}
00104     TreeItem<PAYLOAD> & operator= ( const TreeItem<PAYLOAD> & ) {}
00105 
00106 
00107 public:
00108 
00113     virtual ~TreeItem<PAYLOAD> ()
00114     {
00115         TreeItem<PAYLOAD> * child = firstChild();
00116 
00117         while ( child )
00118         {
00119             TreeItem<PAYLOAD> * lastChild = child;
00120             child = child->next();
00121             delete lastChild;
00122         }
00123     }
00124 
00125 
00129     const PAYLOAD & value() const { return _value; }
00130 
00138     void setValue( PAYLOAD newValue ) { _value = newValue; }
00139 
00143     TreeItem<PAYLOAD> *         parent()        const { return _parent;         }
00144 
00148     TreeItem<PAYLOAD> *         next()          const { return _next;           }
00149 
00153     TreeItem<PAYLOAD> *         firstChild()    const { return _firstChild;     }
00154 
00158     void setParent( TreeItem<PAYLOAD> * newParent )     { _parent = newParent;  }
00159 
00163     void setNext( TreeItem<PAYLOAD> * newNext )         { _next = newNext;      }
00164 
00168     void setFirstChild( TreeItem<PAYLOAD> * newFirstChild )
00169         { _firstChild = newFirstChild; }
00170 
00171 
00181     void addChild( TreeItem<PAYLOAD> * newChild )
00182     {
00183         if ( newChild )
00184         {
00185             newChild->setNext( firstChild() );
00186             setFirstChild( newChild );
00187         }
00188     }
00189 
00190 
00191 protected:
00192 
00193     PAYLOAD             _value;
00194     TreeItem<PAYLOAD> * _parent;
00195     TreeItem<PAYLOAD> * _next;
00196     TreeItem<PAYLOAD> * _firstChild;
00197 };
00198 
00199 
00200 
00207 template<class PAYLOAD> class SortedTreeItem: public TreeItem<PAYLOAD>
00208 {
00209 public:
00210 
00215     SortedTreeItem<PAYLOAD>( PAYLOAD                    val,
00216                              SortedTreeItem<PAYLOAD> *  parentItem = 0 )
00217         : TreeItem<PAYLOAD> ( val, false, parentItem )
00218     {
00219         if ( parentItem )
00220         {
00221             // Hopefully we have a SortedTreeItem parent
00222             SortedTreeItem<PAYLOAD> * sortParent =
00223                 dynamic_cast<SortedTreeItem<PAYLOAD> *> ( parentItem );
00224 
00225             if ( sortParent )
00226                 sortParent->insertChildSorted( this );
00227             else // no SortedTreeItem parent - add unsorted
00228                 parentItem->addChild( this );
00229         }
00230     }
00231 
00232 
00236     virtual ~SortedTreeItem<PAYLOAD> () {}
00237 
00238 
00243     void insertChildSorted( SortedTreeItem<PAYLOAD> * newChild )
00244     {
00245         if ( ! newChild )
00246             return;
00247 
00248         if ( ! firstChild() ||
00249              newChild->value() < firstChild()->value() )
00250         {
00251             // Insert as first child
00252 
00253             newChild->setNext( firstChild() );
00254             setFirstChild( newChild );
00255         }
00256         else
00257         {
00258             // Search correct place to insert
00259 
00260             TreeItem<PAYLOAD> * child = firstChild();
00261 
00262             while ( child->next() &&
00263                     child->next()->value() < newChild->value() )
00264             {
00265                 child = child->next();
00266             }
00267 
00268 
00269             // Insert after 'child'
00270 
00271             newChild->setNext( child->next() );
00272             child->setNext( newChild );
00273         }
00274     }
00275 
00276 
00280     SortedTreeItem<PAYLOAD> *   parent()        const
00281         { return ( SortedTreeItem<PAYLOAD> * ) TreeItem<PAYLOAD>::_parent; }
00282 
00286     SortedTreeItem<PAYLOAD> *   next()          const
00287         { return ( SortedTreeItem<PAYLOAD> * ) TreeItem<PAYLOAD>::_next; }
00288 
00292     SortedTreeItem<PAYLOAD> *   firstChild()    const
00293         { return ( SortedTreeItem<PAYLOAD> * ) TreeItem<PAYLOAD>::_firstChild; }
00294 
00295 
00296 private:
00297 
00302     SortedTreeItem<PAYLOAD>             ( const SortedTreeItem<PAYLOAD> & ) {}
00303     SortedTreeItem<PAYLOAD> & operator= ( const SortedTreeItem<PAYLOAD> & ) {}
00304 };
00305 
00306 
00307 
00312 template<class ITEM, class PAYLOAD> inline
00313 ITEM *
00314 findDirectChild( ITEM * item, PAYLOAD searchVal )
00315 {
00316     TreeItem<PAYLOAD> * child = item->firstChild();
00317 
00318     while ( child )
00319     {
00320         if ( child->value() == searchVal )
00321             return dynamic_cast<ITEM *> ( child );
00322 
00323         child = child->next();
00324     }
00325 
00326     return 0;
00327 }
00328 
00329 
00330 
00331 #endif // TreeItem_h
 All Classes Functions Variables Enumerations Friends