composite.h

Go to the documentation of this file.
00001 // -*- Mode: C++; tab-width: 2; -*-
00002 // vi: set ts=2:
00003 //
00004 // $Id: composite.h,v 1.62.14.1 2007/03/25 21:23:37 oliver Exp $
00005 //
00006 // Author:
00007 //   Nicolas Boghossian
00008 //   Oliver Kohlbacher
00009 //
00010 
00011 #ifndef BALL_CONCEPT_COMPOSITE_H
00012 #define BALL_CONCEPT_COMPOSITE_H
00013 
00014 #ifndef BALL_COMMON_H
00015 # include <BALL/common.h>
00016 #endif
00017 
00018 #ifndef BALL_CONCEPT_PERSISTENTOBJECT_H
00019 # include <BALL/CONCEPT/persistentObject.h>
00020 #endif
00021 
00022 #ifndef BALL_CONCEPT_COMPARATOR_H
00023 # include <BALL/CONCEPT/comparator.h>
00024 #endif
00025 
00026 #ifndef BALL_CONCEPT_BIDIRECTIONALITERATOR_H
00027 # include <BALL/CONCEPT/bidirectionalIterator.h>
00028 #endif
00029 
00030 #ifndef BALL_CONCEPT_OBJECT_H
00031 # include <BALL/CONCEPT/object.h>
00032 #endif
00033 
00034 #ifndef BALL_CONCEPT_SELECTABLE_H
00035 # include <BALL/CONCEPT/selectable.h>
00036 #endif
00037 
00038 #ifndef BALL_CONCEPT_VISITOR_H
00039 # include <BALL/CONCEPT/visitor.h>
00040 #endif
00041 
00042 #ifndef BALL_CONCEPT_PROCESSOR_H
00043 # include <BALL/CONCEPT/processor.h>
00044 #endif
00045 
00046 #ifndef BALL_CONCEPT_TIMESTAMP_H
00047 # include <BALL/CONCEPT/timeStamp.h>
00048 #endif
00049 
00051 namespace BALL 
00052 {
00075   class BALL_EXPORT Composite
00076     : public PersistentObject,
00077       public Selectable
00078   {
00079     public:
00080 
00084 
00085 #ifndef BALL_KERNEL_PREDICATE_TYPE
00086 #define BALL_KERNEL_PREDICATE_TYPE
00087 
00092     typedef UnaryPredicate<Composite> KernelPredicateType;
00093 #endif
00094 
00097     enum StampType
00098     {
00101       MODIFICATION = 1,
00104       SELECTION = 2,
00107       BOTH = 3
00108     };
00110         
00111     BALL_CREATE_DEEP(Composite)
00112 
00113     static UnaryProcessor<Composite> DEFAULT_PROCESSOR;
00114     static KernelPredicateType DEFAULT_UNARY_PREDICATE;
00115     
00119     
00123     Composite()
00124       ;
00125 
00134     Composite(const Composite& composite, bool deep = true)
00135       ;
00136 
00142     virtual ~Composite() 
00143       ;
00144 
00156     virtual void clear()
00157       ;
00158   
00168     virtual void destroy()
00169       ;
00170 
00183     void destroy(bool virtual_destroy)
00184       ;
00185 
00193     void* clone(Composite& root) const
00194       ;
00195 
00197 
00201     
00206     virtual void persistentWrite(PersistenceManager& pm,
00207         const char* name = 0) const
00208       throw(Exception::GeneralException);
00209 
00213     virtual void persistentRead(PersistenceManager& pm)
00214       throw(Exception::GeneralException);
00215 
00217 
00221 
00227     void set(const Composite& composite, bool deep = true) ;
00228 
00233     Composite& operator = (const Composite& composite) ;
00234 
00241     void get(Composite& composite, bool deep = true) const ;
00242 
00247     Size getDegree() const ;
00248 
00253     Size count(const KernelPredicateType& predicate) const ;
00254 
00258     Size countDescendants() const ;
00259 
00265     Size getPathLength(const Composite& composite) const ;
00266 
00271     Size getDepth() const ;
00272 
00277     Size getHeight() const
00278       ;
00279 
00283     Composite& getRoot() ;
00284 
00288     const Composite& getRoot() const ;
00289 
00294     Composite* getLowestCommonAncestor(const Composite& composite)
00295       ;
00296 
00301     const Composite* getLowestCommonAncestor(const Composite& composite) const
00302       ;
00303 
00312     template <typename T>
00313     T* getAncestor(const T& /* dummy */)
00314       ;
00315 
00322     template <typename T>
00323     const T* getAncestor(const T& /* dummy */) const ;
00324 
00332     template <typename T>
00333     T* getPrevious(const T& /* dummy */) ;
00334 
00342     template <typename T>
00343     const T* getPrevious(const T& dummy) const ;
00344 
00352     template <typename T>
00353     T* getNext(const T& /* dummy */) ;
00354 
00362     template <typename T>
00363     const T* getNext(const T& dummy) const ;
00364 
00368     Composite* getParent() ;
00369 
00373     const Composite* getParent() const ;
00374 
00381     Composite* getChild(Index index) ;
00382   
00389     const Composite* getChild(Index index) const ;
00390   
00399     Composite* getSibling(Index index) ;
00400 
00409     const Composite* getSibling(Index index) const ;
00410 
00414     Composite* getFirstChild() ;
00415 
00419     const Composite* getFirstChild() const ;
00420 
00424     Composite* getLastChild() ;
00425 
00429     const Composite* getLastChild() const ;
00430       
00434     const PreciseTime& getModificationTime() const ;
00435 
00439     const PreciseTime& getSelectionTime() const ;
00440 
00450     void stamp(StampType stamp = BOTH) ;
00451       
00457     void prependChild(Composite& composite) ;
00458 
00466     void appendChild(Composite& composite) ;
00467 
00487     static bool insertParent(Composite& parent, Composite& first,  
00488                              Composite& last, bool destroy_parent = true)
00489       ;
00490 
00500     void insertBefore(Composite& composite) ;
00501 
00511     void insertAfter(Composite& composite) ;
00512 
00521     void spliceBefore(Composite& composite) ;
00522 
00531     void spliceAfter(Composite& composite) ;
00532 
00542     void splice(Composite& composite) ;
00543 
00552     bool removeChild(Composite& child) ;
00553 
00554 
00567     Size removeSelected() ;
00568 
00581     Size removeUnselected();
00582 
00591     void replace(Composite& composite) ;
00592 
00601     void swap(Composite& composite) ;
00602 
00611     virtual void select() ;
00612 
00621     virtual void deselect() ;
00623 
00626 
00633     bool operator == (const Composite& composite) const ;
00634 
00638     bool operator != (const Composite& composite) const
00639       ;
00640 
00644     bool isEmpty() const ;
00645 
00649     bool isRoot() const ;
00650   
00653     bool isRootOf(const Composite& composite) const ;
00654   
00657     bool isInterior() const ;
00658   
00661     bool hasChild() const ;
00662   
00665     bool isChildOf(const Composite& composite) const ;
00666   
00669     bool isFirstChild() const ;
00670   
00673     bool isFirstChildOf(const Composite& composite) const ;
00674   
00677     bool isLastChild() const ;
00678   
00681     bool isLastChildOf(const Composite& composite) const ;
00682   
00685     bool hasParent() const ;
00686 
00689     bool isParentOf(const Composite& composite) const ;
00690 
00694     bool hasSibling() const ;
00695       
00698     bool isSiblingOf(const Composite& composite) const ;
00699       
00703     bool hasPreviousSibling() const ;
00704   
00707     bool isPreviousSiblingOf(const Composite& composite) const ;
00708   
00712     bool hasNextSibling() const ;
00713 
00716     bool isNextSiblingOf(const Composite& composite) const ;
00717     
00720     bool isDescendantOf(const Composite& composite) const ;
00721 
00724     template <typename T>
00725     bool hasAncestor(const T& dummy) const  ;
00726 
00729     bool isAncestorOf(const Composite& composite) const ;
00730 
00734     bool isRelatedWith(const Composite& composite) const ;
00735   
00739     bool isHomomorph(const Composite& composite) const ;
00740 
00750     bool containsSelection() const ;
00752 
00758     virtual bool isValid() const ;
00759 
00764     virtual void dump(std::ostream& s = std::cout, Size depth = 0) const
00765       ;
00766 
00768 
00770 
00776     void host(Visitor<Composite>& visitor)
00777       throw(Exception::GeneralException);
00778 
00782     template <typename T>
00783     bool applyAncestor(UnaryProcessor<T>& processor)
00784       throw(Exception::GeneralException);
00785 
00789     template <typename T>
00790     bool applyChild(UnaryProcessor<T>& processor)
00791       throw(Exception::GeneralException);
00792     
00799     template <typename T>
00800     bool applyDescendantPreorder(UnaryProcessor<T>& processor)
00801       throw(Exception::GeneralException);
00802 
00809     template <typename T>
00810     bool applyDescendantPostorder(UnaryProcessor<T>& processor)
00811       throw(Exception::GeneralException);
00812   
00819     template <typename T>
00820     bool applyDescendant(UnaryProcessor<T>& processor)
00821       throw(Exception::GeneralException);
00822     
00828     template <typename T>
00829     bool applyPreorder(UnaryProcessor<T>& processor)
00830       throw(Exception::GeneralException);
00831     
00837     template <typename T>
00838     bool applyPostorder(UnaryProcessor<T>& processor)
00839       throw(Exception::GeneralException);
00840 
00846     template <typename T>
00847     bool apply(UnaryProcessor<T>& processor)
00848       throw(Exception::GeneralException);
00849     
00853     template <typename T>
00854     bool applyLevel(UnaryProcessor<T>& processor, long level)
00855       throw(Exception::GeneralException);
00857 
00858 
00859   
00860     class BALL_EXPORT AncestorIteratorTraits
00861     {
00862       public:
00863 
00864       BALL_INLINE
00865       AncestorIteratorTraits()
00866         
00867         : bound_(0),
00868           ancestor_(0)
00869       {
00870       }
00871     
00872       BALL_INLINE
00873       AncestorIteratorTraits(const Composite& composite)
00874         
00875         : bound_(const_cast<Composite*>(&composite)),
00876           ancestor_(0)
00877       {
00878       }
00879     
00880       BALL_INLINE
00881       AncestorIteratorTraits(const AncestorIteratorTraits& traits)
00882         
00883         : bound_(traits.bound_),
00884           ancestor_(traits.ancestor_)
00885       {
00886       }
00887     
00888       BALL_INLINE
00889       const AncestorIteratorTraits& operator = (const AncestorIteratorTraits& traits)
00890         
00891       {
00892         bound_ = traits.bound_;
00893         ancestor_ = traits.ancestor_;
00894         return *this;
00895       }
00896 
00897       BALL_INLINE Composite* getContainer()  { return bound_; }
00898 
00899       BALL_INLINE const Composite* getContainer() const  { return bound_; }
00900 
00901       BALL_INLINE bool isSingular() const   { return (bound_ == 0); }
00902 
00903       BALL_INLINE Composite* getPosition()    { return ancestor_; }
00904 
00905       BALL_INLINE Composite* const& getPosition() const  {  return ancestor_; }
00906 
00907       BALL_INLINE bool operator == (const AncestorIteratorTraits& traits) const   { return (ancestor_ == traits.ancestor_); }
00908     
00909       BALL_INLINE bool operator != (const AncestorIteratorTraits& traits) const   { return !(ancestor_ == traits.ancestor_); }
00910 
00911       BALL_INLINE bool isValid() const    { return (bound_ != 0 && ancestor_ != 0); }
00912 
00913       BALL_INLINE void invalidate()   { bound_  = ancestor_ = 0; }
00914       
00915       BALL_INLINE void toBegin()    { ancestor_ = bound_->parent_; }
00916 
00917       BALL_INLINE bool isBegin() const  { return (ancestor_ == bound_->parent_); }
00918 
00919       BALL_INLINE void toEnd()  { ancestor_ = 0;  }
00920 
00921       BALL_INLINE bool isEnd() const  { return (ancestor_ == 0); }
00922 
00923       BALL_INLINE Composite& getData()  { return *ancestor_;  }
00924 
00925       BALL_INLINE const Composite& getData() const  { return *ancestor_; }
00926 
00927       BALL_INLINE void forward()  { ancestor_ = ancestor_->parent_; }
00928 
00929       private:
00930 
00931       Composite* bound_;
00932       Composite* ancestor_;
00933     };
00934 
00935     friend class AncestorIteratorTraits;
00936 
00937     typedef ForwardIterator <Composite, Composite, Composite*, AncestorIteratorTraits>
00938       AncestorIterator;
00939 
00940     AncestorIterator beginAncestor() 
00941     {
00942       return AncestorIterator::begin(*this);
00943     }
00944 
00945     AncestorIterator endAncestor() 
00946     {
00947       return AncestorIterator::end(*this);
00948     }
00949 
00950     typedef ConstForwardIterator<Composite, Composite, Composite*, AncestorIteratorTraits>
00951       AncestorConstIterator;
00952 
00953     AncestorConstIterator beginAncestor() const 
00954     {
00955       return AncestorConstIterator::begin(*this);
00956     }
00957 
00958     AncestorConstIterator endAncestor() const 
00959     {
00960       return AncestorConstIterator::end(*this);
00961     }
00962 
00963     class BALL_EXPORT ChildCompositeIteratorTraits
00964     {
00965       public:
00966 
00967       ChildCompositeIteratorTraits()
00968         
00969         : bound_(0),
00970           child_(0)
00971       {
00972       }
00973       
00974       ChildCompositeIteratorTraits(const Composite& composite)
00975         
00976         : bound_((Composite *)&composite),
00977           child_(0)
00978       {
00979       }
00980     
00981       ChildCompositeIteratorTraits(const ChildCompositeIteratorTraits& traits)
00982         
00983         : bound_(traits.bound_),
00984           child_(traits.child_)
00985       {
00986       }
00987     
00988       const ChildCompositeIteratorTraits& operator = (const ChildCompositeIteratorTraits& traits)
00989         
00990       {
00991         bound_ = traits.bound_;
00992         child_ = traits.child_;
00993         return *this;
00994       }
00995 
00996       BALL_INLINE Composite* getContainer()  {  return bound_; }
00997 
00998       BALL_INLINE const Composite* getContainer() const   { return bound_; }
00999 
01000       BALL_INLINE bool isSingular() const   { return (bound_ == 0); }
01001 
01002       BALL_INLINE Composite* getPosition()  { return child_; }
01003 
01004       BALL_INLINE Composite* const& getPosition() const   { return child_; }
01005 
01006       BALL_INLINE bool operator == (const ChildCompositeIteratorTraits& traits) const  { return (child_ == traits.child_); }
01007     
01008       BALL_INLINE bool operator != (const ChildCompositeIteratorTraits& traits) const  { return !(child_ == traits.child_); }
01009     
01010       BALL_INLINE bool isValid() const  { return (bound_ != 0 && child_ != 0); }
01011 
01012       BALL_INLINE void invalidate()  { bound_ = child_ = 0; }
01013 
01014       BALL_INLINE void toBegin()  { child_ = bound_->first_child_; }
01015 
01016       BALL_INLINE bool isBegin() const  { return (child_ == bound_->first_child_); }
01017 
01018       BALL_INLINE void toEnd()  { child_ = 0; }
01019 
01020       BALL_INLINE bool isEnd() const  { return (child_ == 0); }
01021 
01022       BALL_INLINE void toRBegin()  { child_ = bound_->last_child_; }
01023 
01024       BALL_INLINE bool isRBegin() const  { return (child_ == bound_->last_child_); }
01025 
01026       BALL_INLINE void toREnd()  { child_ = 0; }
01027 
01028       BALL_INLINE bool isREnd() const  { return (child_ == 0); }
01029 
01030       BALL_INLINE Composite& getData()  { return *child_; }
01031 
01032       BALL_INLINE const Composite& getData() const  { return *child_; }
01033 
01034       BALL_INLINE void forward()  { child_ = child_->next_; }
01035 
01036       BALL_INLINE void backward()   
01037       {   
01038         if (child_ == 0) 
01039         { 
01040           // Allow decrementation for past-the-end iterators
01041           child_ = bound_->last_child_; 
01042         }
01043         else  
01044         { 
01045           child_ = child_->previous_; 
01046         } 
01047       }
01048 
01049       private:
01050 
01051       Composite* bound_;
01052       Composite* child_;
01053     };
01054 
01055     friend class ChildCompositeIteratorTraits;
01056 
01057     typedef BidirectionalIterator<Composite, Composite, Composite *, ChildCompositeIteratorTraits>
01058       ChildCompositeIterator;
01059 
01060     ChildCompositeIterator beginChildComposite()
01061       
01062     {
01063       return ChildCompositeIterator::begin(*this);
01064     }
01065 
01066     ChildCompositeIterator endChildComposite()
01067       
01068     {
01069       return ChildCompositeIterator::end(*this);
01070     }
01071 
01072 
01073 
01074     typedef ConstBidirectionalIterator<Composite, Composite, Composite *, ChildCompositeIteratorTraits>
01075       ChildCompositeConstIterator;
01076 
01077     ChildCompositeConstIterator beginChildComposite() const
01078       
01079     {
01080       return ChildCompositeConstIterator::begin(*this);
01081     }
01082 
01083     ChildCompositeConstIterator endChildComposite() const
01084       
01085     {
01086       return ChildCompositeConstIterator::end(*this);
01087     }
01088 
01089 
01090 
01091     typedef std::reverse_iterator<ChildCompositeIterator> ChildCompositeReverseIterator;
01092 
01093     ChildCompositeReverseIterator rbeginChildComposite() 
01094     {
01095       return ChildCompositeReverseIterator(endChildComposite());
01096     }
01097 
01098     ChildCompositeReverseIterator rendChildComposite() 
01099     {
01100       return ChildCompositeReverseIterator(beginChildComposite());
01101     }
01102 
01103 
01104 
01105     typedef std::reverse_iterator<ChildCompositeConstIterator> ChildCompositeConstReverseIterator;
01106 
01107     ChildCompositeConstReverseIterator rbeginChildComposite() const 
01108     {
01109       return ChildCompositeConstReverseIterator(endChildComposite());
01110     }
01111 
01112     ChildCompositeConstReverseIterator rendChildComposite() const 
01113     {
01114       return ChildCompositeConstReverseIterator(beginChildComposite());
01115     }
01116 
01117     class BALL_EXPORT CompositeIteratorTraits
01118     {
01119       public:
01120 
01121       BALL_INLINE CompositeIteratorTraits()
01122         
01123         : bound_(0),
01124           position_(0)
01125       {
01126       }
01127     
01128       CompositeIteratorTraits(const Composite& composite)
01129         
01130         : bound_(const_cast<Composite*>(&composite)),
01131           position_(0)
01132       {
01133       }
01134     
01135       CompositeIteratorTraits(const CompositeIteratorTraits& traits)
01136         
01137         : bound_(traits.bound_),
01138           position_(traits.position_)
01139       {
01140       }
01141 
01142       BALL_INLINE ~CompositeIteratorTraits()  {}
01143     
01144       BALL_INLINE bool isValid() const  
01145       { 
01146         return ((bound_ != 0) && (position_ != 0)); 
01147       }
01148 
01149       BALL_INLINE CompositeIteratorTraits& operator = (const CompositeIteratorTraits& traits) 
01150       {
01151         bound_ = traits.bound_;
01152         position_ = traits.position_;
01153         return *this;
01154       }
01155 
01156       BALL_INLINE Composite* getContainer()   { return bound_; }
01157 
01158       BALL_INLINE const Composite* getContainer() const  { return bound_; }
01159     
01160       BALL_INLINE bool isSingular() const   { return (bound_ == 0); }
01161     
01162       BALL_INLINE Composite* getPosition()  { return position_; }
01163       
01164       BALL_INLINE const Composite* getPosition() const  { return position_; }
01165       BALL_INLINE void setPosition(Composite* position)  { position_ = position; }
01166 
01167 
01168       BALL_INLINE Composite& getData()  { return *position_; }
01169 
01170       BALL_INLINE const Composite& getData() const  { return *position_; }
01171 
01172       BALL_INLINE bool operator == (const CompositeIteratorTraits& traits) const  
01173       { 
01174         return (position_ == traits.position_); 
01175       }
01176     
01177       BALL_INLINE bool operator != (const CompositeIteratorTraits& traits) const  
01178       { 
01179         return !(position_ == traits.position_); 
01180       }
01181     
01182       BALL_INLINE void invalidate()   
01183       { 
01184         bound_ = 0; 
01185         position_ = 0;
01186       }
01187 
01188       BALL_INLINE void toBegin() 
01189       {
01190         position_ = bound_;
01191       }
01192 
01193       BALL_INLINE bool isBegin() const 
01194       {
01195         return (position_ == bound_);
01196       }
01197 
01198       BALL_INLINE void toEnd()  
01199       {
01200         position_ = 0;
01201       }
01202 
01203       BALL_INLINE bool isEnd() const 
01204       {
01205         return (position_ == 0);
01206       }
01207 
01208       BALL_INLINE void toRBegin() 
01209       {
01210         if (bound_ != 0)
01211         {
01212           position_ = findPreviousPosition(0);
01213         }
01214       }
01215 
01216       BALL_INLINE bool isRBegin() const 
01217       {
01218         return (position_ == findPreviousPosition(0));
01219       }
01220     
01221       BALL_INLINE void toREnd() 
01222       { 
01223         position_ = bound_;
01224       }
01225 
01226       BALL_INLINE bool isREnd() const 
01227       {
01228         return (position_ == bound_);
01229       }
01230     
01231       BALL_INLINE void forward() 
01232       {
01233         position_ = findNextPosition(position_);
01234       }
01235 
01236       BALL_INLINE void backward() 
01237       {
01238         position_ = findPreviousPosition(position_);
01239       }
01240 
01241       protected:
01242 
01244       Composite* bound_;
01245 
01247       Composite* position_;
01248 
01249       Composite* findPreviousPosition(Composite* p) const
01250       {
01251         // If we are at the root of the iterator, the 
01252         // decrementing it results in an invalid iterator
01253         // (past-the-end).
01254         if (p == bound_)
01255         {
01256           return 0;
01257         }
01258         // If we decrement a past-the-end-iterator, we
01259         // start at the root and "fall down" on the right
01260         // hand side following the last_child_ pointers
01261         // until we hit bottom.
01262         else if (p == 0)
01263         {
01264           if (bound_->last_child_ == 0)
01265           {
01266             return bound_;
01267           }
01268           else
01269           {
01270             p = bound_->last_child_;
01271           }
01272           while (p->last_child_ != 0)
01273           {
01274             p = p->last_child_;
01275           }
01276         }
01277         // Normally, we just grab the guy to the
01278         // left in the doubly-linked child list.
01279         else if (p->previous_ != 0)
01280         {
01281           p = p->previous_;
01282 
01283           // If the guy to the left hast children,
01284           // we do the drop on the rigth again.
01285           while (p->last_child_ != 0)
01286           {
01287             p = p->last_child_;
01288           }
01289         }
01290         // Finally, if we can't go down and we can't go 
01291         // left, we have to go upwards.
01292         else if (p != bound_)
01293         {
01294           p = p->parent_;
01295         }
01296 
01297         return p;
01298       }
01299 
01300       Composite* findNextPosition(Composite* p) const
01301       {
01302         // If we are in a past-the-end position, we stay put.
01303         if (p == 0)
01304         {
01305           return 0;
01306         }
01307         // Otherwise, we try the first child. If there's one,
01308         // that's our next position.
01309         else 
01310         {
01311           if (p->first_child_ != 0)
01312           {
01313             p = p->first_child_;
01314           }
01315           else 
01316           {
01317             // If we are already in the root node, we are done.
01318             if (p == bound_)
01319             {
01320               return 0;
01321             }
01322             // Otherwise, we try to walk to the right at the current level.
01323             if (p->next_ != 0)
01324             {
01325               p = p->next_;
01326             }
01327             // If that doesn't work out, we'll have to climb up again.
01328             // Now, we either revisit a node we have already been to, or we
01329             // are trying to climb up *beyond* our iteration root (bound_).
01330             // In the latter case, we return a past-the-end-iterator (0).
01331             else
01332             {
01333               // If we could not walk left or right and we are at the root
01334               // again, then we are done with the iteration (this is the
01335               // case if bound_ is a leaf node).
01336               while (p->next_ == 0)
01337               {
01338                 p = p->parent_;
01339                 if ((p == bound_) || (p == 0))
01340                 {
01341                   return 0;
01342                 }
01343               }
01344               p = p->next_;
01345             }
01346           }
01347         }
01348         return p;
01349       }
01350     };
01351 
01352     friend class CompositeIteratorTraits;
01353 
01354     typedef BidirectionalIterator<Composite, Composite, Composite*, CompositeIteratorTraits>
01355       CompositeIterator;
01356 
01357     CompositeIterator beginComposite()  { return CompositeIterator::begin(*this); }
01358 
01359     CompositeIterator endComposite()  { return CompositeIterator::end(*this); }
01360 
01361     typedef ConstBidirectionalIterator<Composite, Composite, Composite*, CompositeIteratorTraits>
01362       CompositeConstIterator;
01363 
01364     CompositeConstIterator beginComposite() const  
01365     { 
01366       return CompositeConstIterator::begin(*this);
01367     }
01368 
01369     CompositeConstIterator endComposite() const 
01370     {
01371       return CompositeConstIterator::end(*this);
01372     }
01373 
01374 
01375     typedef std::reverse_iterator<CompositeIterator> CompositeReverseIterator;
01376 
01377     CompositeReverseIterator rbeginComposite() 
01378     {
01379       return CompositeReverseIterator(endComposite());
01380     }
01381 
01382     CompositeReverseIterator rendComposite() 
01383     {
01384       return CompositeReverseIterator(beginComposite());
01385     }
01386 
01387 
01388     typedef std::reverse_iterator<CompositeConstIterator> CompositeConstReverseIterator;
01389 
01390     CompositeConstReverseIterator rbeginComposite() const 
01391     {
01392       return CompositeConstReverseIterator(endComposite());
01393     }
01394 
01395     CompositeConstReverseIterator rendComposite() const 
01396     {
01397       return CompositeConstReverseIterator(beginComposite());
01398     }
01399 
01400     /*
01401      * This function removes and deletes all composites that are
01402      * supplied in the list of children.
01403      */
01404     void deleteChildrenList_(std::list<Composite*>& composites);
01405 
01406     private:
01407     
01409     Size getHeight_(Size size, Size& max_height) const ;
01410   
01412     Size countDescendants_() const ;
01413 
01415     void clone_(Composite& parent, Composite& stack) const ;
01416 
01417     template <typename T>
01418     bool applyLevelNostart_(UnaryProcessor<T>& processor, long level)
01419       throw(Exception::GeneralException);
01420 
01421     template <typename T>
01422     bool applyChildNostart_(UnaryProcessor<T>& processor)
01423       throw(Exception::GeneralException);
01424 
01425     template <typename T>
01426     bool applyPreorderNostart_(UnaryProcessor<T>& processor)
01427       throw(Exception::GeneralException);
01428 
01429     template <typename T>
01430     bool applyDescendantPreorderNostart_(UnaryProcessor<T>& processor)
01431       throw(Exception::GeneralException);
01432 
01433     template <typename T>
01434     bool applyDescendantPostorderNostart_(UnaryProcessor<T>& processor)
01435       throw(Exception::GeneralException);
01436 
01437 
01438     void updateSelection_() ;
01439     void determineSelection_() ;
01440     void select_(bool update_parent = true) ;
01441     void deselect_(bool update_parent = true) ;
01442 
01443     // private attributes
01444     
01445     Size            number_of_children_;
01446     Composite*      parent_;
01447     Composite*      previous_;
01448     Composite*      next_;
01449     Composite*      first_child_;
01450     Composite*      last_child_;
01451     unsigned char   properties_;
01452     bool            contains_selection_;
01453     Size            number_of_selected_children_;
01454     Size            number_of_children_containing_selection_;
01455     TimeStamp       selection_stamp_;
01456     TimeStamp       modification_stamp_;
01457   };
01458 
01459   template <typename T>
01460   bool Composite::applyAncestor(UnaryProcessor<T>& processor)
01461     throw(Exception::GeneralException)
01462   {
01463     if (processor.start() == false)
01464     {
01465       return false;
01466     }
01467 
01468     Processor::Result result;
01469 
01470     for (Composite* composite = parent_; composite != 0; composite = composite->parent_)
01471     {
01472       T* t_ptr;
01473       if ((t_ptr = dynamic_cast<T*>(composite)) != 0)
01474       { 
01475         result = processor(*t_ptr);
01476         if (result <= Processor::BREAK)
01477         {
01478           return (result == Processor::BREAK);
01479         }
01480       }
01481     }
01482 
01483     return processor.finish();
01484   }
01485   
01486   template <typename T>
01487   bool Composite::applyChild(UnaryProcessor<T>& processor)
01488     throw(Exception::GeneralException)
01489   {
01490     return processor.start() && applyChildNostart_(processor) && processor.finish();
01491   }
01492 
01493   template <typename T>
01494   bool Composite::applyChildNostart_(UnaryProcessor<T>& processor)
01495     throw(Exception::GeneralException)
01496   {
01497     Processor::Result result = Processor::CONTINUE;
01498 
01499     for (Composite* composite = first_child_;
01500          composite != 0; composite = composite->next_)
01501     {
01502       T* t_ptr;
01503       if ((t_ptr = dynamic_cast<T*>(composite)) != 0)
01504       {
01505         result = processor(*t_ptr);
01506         if (result <= Processor::BREAK)
01507         {
01508           break;
01509         }
01510       }
01511     }
01512 
01513     return (result >= Processor::BREAK);
01514   }
01515  
01516   template <typename T>
01517   bool Composite::applyDescendantPreorder(UnaryProcessor<T>& processor)
01518     throw(Exception::GeneralException)
01519   {
01520     return processor.start() && applyDescendantPreorderNostart_(processor) && processor.finish();
01521   }
01522 
01523   template <typename T>
01524   bool Composite::applyDescendantPreorderNostart_(UnaryProcessor<T>& processor)
01525     throw(Exception::GeneralException)
01526   {
01527     Processor::Result result;
01528 
01529     for (Composite* composite = first_child_;
01530          composite != 0; composite = composite->next_)
01531     {
01532       T* t_ptr;
01533       if ((t_ptr = dynamic_cast<T*>(composite)) != 0)
01534       { 
01535         result = processor(*t_ptr);
01536 
01537         if (result <= Processor::BREAK)
01538         {
01539           return (result == Processor::BREAK);
01540         }
01541       }
01542 
01543       if (composite->first_child_ != 0  && composite->applyDescendantPreorderNostart_(processor) == false)
01544       {
01545         return false;
01546       }
01547     }
01548 
01549     return true;
01550   }
01551 
01552   template <typename T>
01553   bool Composite::applyDescendantPostorder(UnaryProcessor<T>& processor)
01554     throw(Exception::GeneralException)
01555   {
01556     return processor.start() && applyDescendantPostorderNostart_(processor) && processor.finish();
01557   }
01558 
01559   template <typename T>
01560   bool Composite::applyDescendantPostorderNostart_(UnaryProcessor<T>& processor)
01561     throw(Exception::GeneralException)
01562   {
01563     Processor::Result result;
01564 
01565     for (Composite* composite = first_child_;
01566          composite != 0; composite = composite->next_)
01567     {
01568       if (composite->first_child_ != 0 && 
01569           composite->applyDescendantPostorderNostart_(processor) == false)
01570       {
01571         return false;
01572       }
01573 
01574       T* t_ptr = dynamic_cast<T*>(composite);
01575       if (t_ptr != 0)
01576       {
01577         result = processor(*t_ptr);
01578 
01579         if (result <= Processor::BREAK)
01580         {
01581           return (result == Processor::BREAK);
01582         }
01583       }
01584     }
01585 
01586     return true;
01587   }
01588 
01589   template <typename T>  
01590   bool Composite::applyPostorder(UnaryProcessor<T>& processor)
01591     throw(Exception::GeneralException)
01592   { 
01593     if (!processor.start() || !applyDescendantPostorderNostart_(processor))
01594     {
01595       return false;
01596     }
01597 
01598     T* t_ptr = dynamic_cast<T*>(this);
01599 
01600     return (t_ptr != 0                            && 
01601             processor(*t_ptr) >= Processor::BREAK && 
01602             processor.finish()                      );
01603   }
01604 
01605   template <typename T>
01606   bool Composite::applyLevel(UnaryProcessor<T>& processor, long level)
01607     throw(Exception::GeneralException)
01608   {
01609     return processor.start() && applyLevelNostart_(processor, level) && processor.finish();
01610   }
01611 
01612   template <typename T>
01613   bool Composite::applyLevelNostart_(UnaryProcessor<T>& processor, long level)
01614     throw(Exception::GeneralException)
01615   {
01616     if (level == 0)
01617     {
01618       T* t_ptr = dynamic_cast<T*>(this);
01619       if (t_ptr != 0)
01620       {
01621        Processor::Result result = processor(*t_ptr);
01622 
01623         if (result <= Processor::BREAK)
01624         {
01625           return (result == Processor::BREAK);
01626         }
01627       }
01628     }
01629     else 
01630     {
01631       if (--level == 0)
01632       {
01633         return applyChildNostart_(processor);
01634       }
01635       else 
01636       {
01637         if (level > 0)
01638         {
01639           for (Composite* composite = first_child_;
01640                composite != 0; composite = composite->next_)
01641           {
01642             if (composite->first_child_ != 0 && composite->applyLevelNostart_(processor, level) == false)
01643             {
01644               return false;
01645             }
01646           }
01647         }
01648       }
01649     }
01650     return true;
01651   }
01652 
01653   template <typename T>
01654   bool Composite::applyPreorderNostart_(UnaryProcessor<T>& processor)
01655     throw(Exception::GeneralException)
01656   {
01657     Processor::Result result;
01658     bool return_value;
01659     T* t_ptr = dynamic_cast<T*>(this);
01660     if (t_ptr != 0)
01661     {
01662       result = processor(*t_ptr);
01663   
01664       if (result <= Processor::BREAK)
01665       {
01666         return_value = (result == Processor::BREAK);
01667       } 
01668       else 
01669       {
01670         return_value =  applyDescendantPreorderNostart_(processor);
01671       }
01672     } 
01673     else 
01674     {
01675       return_value =  applyDescendantPreorderNostart_(processor);
01676     }
01677     
01678     return return_value;
01679   }
01680 
01681   template <typename T>
01682   bool Composite::applyDescendant(UnaryProcessor<T>& processor)
01683     throw(Exception::GeneralException)
01684   {
01685     return applyDescendantPreorder(processor);
01686   }
01687 
01688   template <typename T>
01689   bool Composite::applyPreorder(UnaryProcessor<T>& processor)
01690     throw(Exception::GeneralException)
01691   {
01692     return processor.start() && applyPreorderNostart_(processor) && processor.finish();
01693   }
01694 
01695   template <typename T>
01696   BALL_INLINE 
01697   bool Composite::apply(UnaryProcessor<T>& processor)
01698     throw(Exception::GeneralException)
01699   {
01700     return applyPreorder(processor);
01701   }
01702 
01703   template <typename T>
01704   BALL_INLINE 
01705   T* Composite::getAncestor(const T& /* dummy */)
01706     
01707   {
01708     T* T_ptr = 0;
01709     
01710     for (Composite* composite_ptr = parent_;
01711          composite_ptr != 0; composite_ptr = composite_ptr->parent_)
01712     {
01713       T_ptr = dynamic_cast<T*>(composite_ptr);
01714       if (T_ptr != 0)
01715       {
01716         break;
01717       } 
01718     }
01719     
01720     return T_ptr;
01721   }
01722 
01723   template <typename T>
01724   BALL_INLINE 
01725   const T* Composite::getAncestor(const T& /* dummy */) const
01726     
01727   {
01728     T* t_ptr = 0;
01729     for (Composite* composite_ptr = parent_;
01730          composite_ptr != 0; composite_ptr = composite_ptr->parent_)
01731     {
01732       if ((t_ptr = dynamic_cast<T*>(composite_ptr)) != 0)
01733       {
01734         break;
01735       } 
01736     }
01737     
01738     return const_cast<const T*>(t_ptr);
01739   }
01740 
01741   template <typename T>
01742   BALL_INLINE 
01743   T* Composite::getPrevious(const T& /* dummy */)
01744     
01745   {
01746     // create an iterator bound to the root of the subtree
01747     CompositeIterator it(getRoot().endComposite());
01748 
01749     // set its position to the current composite
01750     it.getTraits().setPosition(this);
01751 
01752     // walk back until we find something  
01753     // or we cannot walk any further
01754     if (+it)
01755     {
01756       do 
01757       {
01758         --it;
01759       } 
01760       while (+it && !RTTI::isKindOf<T>(*it));
01761     }
01762 
01763     // return a NULL pointer if nothing was found
01764     Composite* ptr = 0;
01765     if (+it)
01766     {
01767       ptr = &*it;
01768     }
01769     
01770     return dynamic_cast<T*>(ptr);
01771   }
01772 
01773   template <typename T>
01774   BALL_INLINE 
01775   const T* Composite::getPrevious(const T& dummy) const
01776     
01777   {
01778     // cast away the constness of this and call the non-const method
01779     Composite* nonconst_this = const_cast<Composite*>(this);
01780 
01781     return const_cast<const T*>(nonconst_this->getPrevious(dummy));
01782   }
01783 
01784   template <typename T>
01785   BALL_INLINE 
01786   T* Composite::getNext(const T& /* dummy */)
01787     
01788   {
01789     // create an iterator bound to the root of the subtree
01790     CompositeIterator it(getRoot().beginComposite());
01791 
01792     // set its position to the current composite
01793     it.getTraits().setPosition(this);
01794 
01795     // walk forward until we find something 
01796     // or we cannot walk any further
01797     do 
01798     {
01799       it++;
01800     } 
01801     while (it.isValid() && !RTTI::isKindOf<T>(*it));
01802 
01803 
01804     // return a NULL pointer if nothing was found
01805     Composite* ptr = 0;
01806     if (+it)
01807     {
01808       ptr = &*it;
01809     }
01810     
01811     return dynamic_cast<T*>(ptr);
01812   }
01813 
01814   template <typename T>
01815   BALL_INLINE 
01816   const T* Composite::getNext(const T& dummy) const
01817     
01818   {
01819     // cast away the constness of this and call the non-const method
01820     Composite* nonconst_this = const_cast<Composite*>(this);
01821 
01822     return const_cast<const T*>(nonconst_this->getNext(dummy));
01823   }
01824 
01825   template <typename T>
01826   BALL_INLINE 
01827   bool Composite::hasAncestor(const T& dummy ) const 
01828     
01829   {
01830     return (getAncestor(dummy) != 0); 
01831   }
01832 
01833 # ifndef BALL_NO_INLINE_FUNCTIONS
01834 #   include <BALL/CONCEPT/composite.iC>
01835 # endif
01836 
01837 
01838 } // namespace BALL
01839 
01840 #endif // BALL_CONCEPT_COMPOSITE_H