00001
00002
00003
00004
00005
00006
00007
00008
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& )
00314 ;
00315
00322 template <typename T>
00323 const T* getAncestor(const T& ) const ;
00324
00332 template <typename T>
00333 T* getPrevious(const T& ) ;
00334
00342 template <typename T>
00343 const T* getPrevious(const T& dummy) const ;
00344
00352 template <typename T>
00353 T* getNext(const T& ) ;
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
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
01252
01253
01254 if (p == bound_)
01255 {
01256 return 0;
01257 }
01258
01259
01260
01261
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
01278
01279 else if (p->previous_ != 0)
01280 {
01281 p = p->previous_;
01282
01283
01284
01285 while (p->last_child_ != 0)
01286 {
01287 p = p->last_child_;
01288 }
01289 }
01290
01291
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
01303 if (p == 0)
01304 {
01305 return 0;
01306 }
01307
01308
01309 else
01310 {
01311 if (p->first_child_ != 0)
01312 {
01313 p = p->first_child_;
01314 }
01315 else
01316 {
01317
01318 if (p == bound_)
01319 {
01320 return 0;
01321 }
01322
01323 if (p->next_ != 0)
01324 {
01325 p = p->next_;
01326 }
01327
01328
01329
01330
01331 else
01332 {
01333
01334
01335
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
01402
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
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& )
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& ) 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& )
01744
01745 {
01746
01747 CompositeIterator it(getRoot().endComposite());
01748
01749
01750 it.getTraits().setPosition(this);
01751
01752
01753
01754 if (+it)
01755 {
01756 do
01757 {
01758 --it;
01759 }
01760 while (+it && !RTTI::isKindOf<T>(*it));
01761 }
01762
01763
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
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& )
01787
01788 {
01789
01790 CompositeIterator it(getRoot().beginComposite());
01791
01792
01793 it.getTraits().setPosition(this);
01794
01795
01796
01797 do
01798 {
01799 it++;
01800 }
01801 while (it.isValid() && !RTTI::isKindOf<T>(*it));
01802
01803
01804
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
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 }
01839
01840 #endif // BALL_CONCEPT_COMPOSITE_H