00001
00002
00003
00004
00005 #ifndef BALL_CONCEPT_COMPOSITE_H
00006 #define BALL_CONCEPT_COMPOSITE_H
00007
00008 #ifndef BALL_COMMON_H
00009 # include <BALL/common.h>
00010 #endif
00011
00012 #ifndef BALL_CONCEPT_PERSISTENTOBJECT_H
00013 # include <BALL/CONCEPT/persistentObject.h>
00014 #endif
00015
00016 #ifndef BALL_CONCEPT_COMPARATOR_H
00017 # include <BALL/CONCEPT/comparator.h>
00018 #endif
00019
00020 #ifndef BALL_CONCEPT_BIDIRECTIONALITERATOR_H
00021 # include <BALL/CONCEPT/bidirectionalIterator.h>
00022 #endif
00023
00024 #ifndef BALL_CONCEPT_OBJECT_H
00025 # include <BALL/CONCEPT/object.h>
00026 #endif
00027
00028 #ifndef BALL_CONCEPT_SELECTABLE_H
00029 # include <BALL/CONCEPT/selectable.h>
00030 #endif
00031
00032 #ifndef BALL_CONCEPT_VISITOR_H
00033 # include <BALL/CONCEPT/visitor.h>
00034 #endif
00035
00036 #ifndef BALL_CONCEPT_PROCESSOR_H
00037 # include <BALL/CONCEPT/processor.h>
00038 #endif
00039
00040 #ifndef BALL_CONCEPT_TIMESTAMP_H
00041 # include <BALL/CONCEPT/timeStamp.h>
00042 #endif
00043
00045 namespace BALL
00046 {
00069 class BALL_EXPORT Composite
00070 : public PersistentObject,
00071 public Selectable
00072 {
00073 public:
00074
00078
00079 #ifndef BALL_KERNEL_PREDICATE_TYPE
00080 #define BALL_KERNEL_PREDICATE_TYPE
00081
00086 typedef UnaryPredicate<Composite> KernelPredicateType;
00087 #endif
00088
00091 enum StampType
00092 {
00095 MODIFICATION = 1,
00098 SELECTION = 2,
00101 BOTH = 3
00102 };
00104
00105 BALL_CREATE_DEEP(Composite)
00106
00107 static UnaryProcessor<Composite> DEFAULT_PROCESSOR;
00108 static KernelPredicateType DEFAULT_UNARY_PREDICATE;
00109
00113
00117 Composite()
00118 ;
00119
00128 Composite(const Composite& composite, bool deep = true)
00129 ;
00130
00136 virtual ~Composite()
00137 ;
00138
00150 virtual void clear()
00151 ;
00152
00162 virtual void destroy()
00163 ;
00164
00177 void destroy(bool virtual_destroy)
00178 ;
00179
00187 void* clone(Composite& root) const
00188 ;
00189
00191
00195
00200 virtual void persistentWrite(PersistenceManager& pm,
00201 const char* name = 0) const
00202 throw(Exception::GeneralException);
00203
00207 virtual void persistentRead(PersistenceManager& pm)
00208 throw(Exception::GeneralException);
00209
00211
00215
00221 void set(const Composite& composite, bool deep = true) ;
00222
00227 Composite& operator = (const Composite& composite) ;
00228
00235 void get(Composite& composite, bool deep = true) const ;
00236
00241 Size getDegree() const ;
00242
00247 Size count(const KernelPredicateType& predicate) const ;
00248
00252 Size countDescendants() const ;
00253
00259 Size getPathLength(const Composite& composite) const ;
00260
00265 Size getDepth() const ;
00266
00271 Size getHeight() const
00272 ;
00273
00277 Composite& getRoot() ;
00278
00282 const Composite& getRoot() const ;
00283
00288 Composite* getLowestCommonAncestor(const Composite& composite)
00289 ;
00290
00295 const Composite* getLowestCommonAncestor(const Composite& composite) const
00296 ;
00297
00306 template <typename T>
00307 T* getAncestor(const T& )
00308 ;
00309
00316 template <typename T>
00317 const T* getAncestor(const T& ) const ;
00318
00326 template <typename T>
00327 T* getPrevious(const T& ) ;
00328
00336 template <typename T>
00337 const T* getPrevious(const T& dummy) const ;
00338
00346 template <typename T>
00347 T* getNext(const T& ) ;
00348
00356 template <typename T>
00357 const T* getNext(const T& dummy) const ;
00358
00362 Composite* getParent() ;
00363
00367 const Composite* getParent() const ;
00368
00375 Composite* getChild(Index index) ;
00376
00383 const Composite* getChild(Index index) const ;
00384
00393 Composite* getSibling(Index index) ;
00394
00403 const Composite* getSibling(Index index) const ;
00404
00408 Composite* getFirstChild() ;
00409
00413 const Composite* getFirstChild() const ;
00414
00418 Composite* getLastChild() ;
00419
00423 const Composite* getLastChild() const ;
00424
00428 const PreciseTime& getModificationTime() const ;
00429
00433 const PreciseTime& getSelectionTime() const ;
00434
00444 void stamp(StampType stamp = BOTH) ;
00445
00451 void prependChild(Composite& composite) ;
00452
00460 void appendChild(Composite& composite) ;
00461
00481 static bool insertParent(Composite& parent, Composite& first,
00482 Composite& last, bool destroy_parent = true)
00483 ;
00484
00494 void insertBefore(Composite& composite) ;
00495
00505 void insertAfter(Composite& composite) ;
00506
00515 void spliceBefore(Composite& composite) ;
00516
00525 void spliceAfter(Composite& composite) ;
00526
00536 void splice(Composite& composite) ;
00537
00546 bool removeChild(Composite& child) ;
00547
00548
00561 Size removeSelected() ;
00562
00575 Size removeUnselected();
00576
00585 void replace(Composite& composite) ;
00586
00595 void swap(Composite& composite) ;
00596
00605 virtual void select() ;
00606
00615 virtual void deselect() ;
00617
00620
00627 bool operator == (const Composite& composite) const ;
00628
00632 bool operator != (const Composite& composite) const
00633 ;
00634
00638 bool isEmpty() const ;
00639
00643 bool isRoot() const ;
00644
00647 bool isRootOf(const Composite& composite) const ;
00648
00651 bool isInterior() const ;
00652
00655 bool hasChild() const ;
00656
00659 bool isChildOf(const Composite& composite) const ;
00660
00663 bool isFirstChild() const ;
00664
00667 bool isFirstChildOf(const Composite& composite) const ;
00668
00671 bool isLastChild() const ;
00672
00675 bool isLastChildOf(const Composite& composite) const ;
00676
00679 bool hasParent() const ;
00680
00683 bool isParentOf(const Composite& composite) const ;
00684
00688 bool hasSibling() const ;
00689
00692 bool isSiblingOf(const Composite& composite) const ;
00693
00697 bool hasPreviousSibling() const ;
00698
00701 bool isPreviousSiblingOf(const Composite& composite) const ;
00702
00706 bool hasNextSibling() const ;
00707
00710 bool isNextSiblingOf(const Composite& composite) const ;
00711
00714 bool isDescendantOf(const Composite& composite) const ;
00715
00718 template <typename T>
00719 bool hasAncestor(const T& dummy) const ;
00720
00723 bool isAncestorOf(const Composite& composite) const ;
00724
00728 bool isRelatedWith(const Composite& composite) const ;
00729
00733 bool isHomomorph(const Composite& composite) const ;
00734
00744 bool containsSelection() const ;
00746
00752 virtual bool isValid() const ;
00753
00758 virtual void dump(std::ostream& s = std::cout, Size depth = 0) const
00759 ;
00760
00762
00764
00770 void host(Visitor<Composite>& visitor)
00771 throw(Exception::GeneralException);
00772
00776 template <typename T>
00777 bool applyAncestor(UnaryProcessor<T>& processor)
00778 throw(Exception::GeneralException);
00779
00783 template <typename T>
00784 bool applyChild(UnaryProcessor<T>& processor)
00785 throw(Exception::GeneralException);
00786
00793 template <typename T>
00794 bool applyDescendantPreorder(UnaryProcessor<T>& processor)
00795 throw(Exception::GeneralException);
00796
00803 template <typename T>
00804 bool applyDescendantPostorder(UnaryProcessor<T>& processor)
00805 throw(Exception::GeneralException);
00806
00813 template <typename T>
00814 bool applyDescendant(UnaryProcessor<T>& processor)
00815 throw(Exception::GeneralException);
00816
00822 template <typename T>
00823 bool applyPreorder(UnaryProcessor<T>& processor)
00824 throw(Exception::GeneralException);
00825
00831 template <typename T>
00832 bool applyPostorder(UnaryProcessor<T>& processor)
00833 throw(Exception::GeneralException);
00834
00840 template <typename T>
00841 bool apply(UnaryProcessor<T>& processor)
00842 throw(Exception::GeneralException);
00843
00847 template <typename T>
00848 bool applyLevel(UnaryProcessor<T>& processor, long level)
00849 throw(Exception::GeneralException);
00851
00852
00853
00854 class BALL_EXPORT AncestorIteratorTraits
00855 {
00856 public:
00857
00858 BALL_INLINE
00859 AncestorIteratorTraits()
00860
00861 : bound_(0),
00862 ancestor_(0)
00863 {
00864 }
00865
00866 BALL_INLINE
00867 AncestorIteratorTraits(const Composite& composite)
00868
00869 : bound_(const_cast<Composite*>(&composite)),
00870 ancestor_(0)
00871 {
00872 }
00873
00874 BALL_INLINE
00875 AncestorIteratorTraits(const AncestorIteratorTraits& traits)
00876
00877 : bound_(traits.bound_),
00878 ancestor_(traits.ancestor_)
00879 {
00880 }
00881
00882 BALL_INLINE
00883 const AncestorIteratorTraits& operator = (const AncestorIteratorTraits& traits)
00884
00885 {
00886 bound_ = traits.bound_;
00887 ancestor_ = traits.ancestor_;
00888 return *this;
00889 }
00890
00891 BALL_INLINE Composite* getContainer() { return bound_; }
00892
00893 BALL_INLINE const Composite* getContainer() const { return bound_; }
00894
00895 BALL_INLINE bool isSingular() const { return (bound_ == 0); }
00896
00897 BALL_INLINE Composite* getPosition() { return ancestor_; }
00898
00899 BALL_INLINE Composite* const& getPosition() const { return ancestor_; }
00900
00901 BALL_INLINE bool operator == (const AncestorIteratorTraits& traits) const { return (ancestor_ == traits.ancestor_); }
00902
00903 BALL_INLINE bool operator != (const AncestorIteratorTraits& traits) const { return !(ancestor_ == traits.ancestor_); }
00904
00905 BALL_INLINE bool isValid() const { return (bound_ != 0 && ancestor_ != 0); }
00906
00907 BALL_INLINE void invalidate() { bound_ = ancestor_ = 0; }
00908
00909 BALL_INLINE void toBegin() { ancestor_ = bound_->parent_; }
00910
00911 BALL_INLINE bool isBegin() const { return (ancestor_ == bound_->parent_); }
00912
00913 BALL_INLINE void toEnd() { ancestor_ = 0; }
00914
00915 BALL_INLINE bool isEnd() const { return (ancestor_ == 0); }
00916
00917 BALL_INLINE Composite& getData() { return *ancestor_; }
00918
00919 BALL_INLINE const Composite& getData() const { return *ancestor_; }
00920
00921 BALL_INLINE void forward() { ancestor_ = ancestor_->parent_; }
00922
00923 private:
00924
00925 Composite* bound_;
00926 Composite* ancestor_;
00927 };
00928
00929 friend class AncestorIteratorTraits;
00930
00931 typedef ForwardIterator <Composite, Composite, Composite*, AncestorIteratorTraits>
00932 AncestorIterator;
00933
00934 AncestorIterator beginAncestor()
00935 {
00936 return AncestorIterator::begin(*this);
00937 }
00938
00939 AncestorIterator endAncestor()
00940 {
00941 return AncestorIterator::end(*this);
00942 }
00943
00944 typedef ConstForwardIterator<Composite, Composite, Composite*, AncestorIteratorTraits>
00945 AncestorConstIterator;
00946
00947 AncestorConstIterator beginAncestor() const
00948 {
00949 return AncestorConstIterator::begin(*this);
00950 }
00951
00952 AncestorConstIterator endAncestor() const
00953 {
00954 return AncestorConstIterator::end(*this);
00955 }
00956
00957 class BALL_EXPORT ChildCompositeIteratorTraits
00958 {
00959 public:
00960
00961 ChildCompositeIteratorTraits()
00962
00963 : bound_(0),
00964 child_(0)
00965 {
00966 }
00967
00968 ChildCompositeIteratorTraits(const Composite& composite)
00969
00970 : bound_((Composite *)&composite),
00971 child_(0)
00972 {
00973 }
00974
00975 ChildCompositeIteratorTraits(const ChildCompositeIteratorTraits& traits)
00976
00977 : bound_(traits.bound_),
00978 child_(traits.child_)
00979 {
00980 }
00981
00982 const ChildCompositeIteratorTraits& operator = (const ChildCompositeIteratorTraits& traits)
00983
00984 {
00985 bound_ = traits.bound_;
00986 child_ = traits.child_;
00987 return *this;
00988 }
00989
00990 BALL_INLINE Composite* getContainer() { return bound_; }
00991
00992 BALL_INLINE const Composite* getContainer() const { return bound_; }
00993
00994 BALL_INLINE bool isSingular() const { return (bound_ == 0); }
00995
00996 BALL_INLINE Composite* getPosition() { return child_; }
00997
00998 BALL_INLINE Composite* const& getPosition() const { return child_; }
00999
01000 BALL_INLINE bool operator == (const ChildCompositeIteratorTraits& traits) const { return (child_ == traits.child_); }
01001
01002 BALL_INLINE bool operator != (const ChildCompositeIteratorTraits& traits) const { return !(child_ == traits.child_); }
01003
01004 BALL_INLINE bool isValid() const { return (bound_ != 0 && child_ != 0); }
01005
01006 BALL_INLINE void invalidate() { bound_ = child_ = 0; }
01007
01008 BALL_INLINE void toBegin() { child_ = bound_->first_child_; }
01009
01010 BALL_INLINE bool isBegin() const { return (child_ == bound_->first_child_); }
01011
01012 BALL_INLINE void toEnd() { child_ = 0; }
01013
01014 BALL_INLINE bool isEnd() const { return (child_ == 0); }
01015
01016 BALL_INLINE void toRBegin() { child_ = bound_->last_child_; }
01017
01018 BALL_INLINE bool isRBegin() const { return (child_ == bound_->last_child_); }
01019
01020 BALL_INLINE void toREnd() { child_ = 0; }
01021
01022 BALL_INLINE bool isREnd() const { return (child_ == 0); }
01023
01024 BALL_INLINE Composite& getData() { return *child_; }
01025
01026 BALL_INLINE const Composite& getData() const { return *child_; }
01027
01028 BALL_INLINE void forward() { child_ = child_->next_; }
01029
01030 BALL_INLINE void backward()
01031 {
01032 if (child_ == 0)
01033 {
01034
01035 child_ = bound_->last_child_;
01036 }
01037 else
01038 {
01039 child_ = child_->previous_;
01040 }
01041 }
01042
01043 private:
01044
01045 Composite* bound_;
01046 Composite* child_;
01047 };
01048
01049 friend class ChildCompositeIteratorTraits;
01050
01051 typedef BidirectionalIterator<Composite, Composite, Composite *, ChildCompositeIteratorTraits>
01052 ChildCompositeIterator;
01053
01054 ChildCompositeIterator beginChildComposite()
01055
01056 {
01057 return ChildCompositeIterator::begin(*this);
01058 }
01059
01060 ChildCompositeIterator endChildComposite()
01061
01062 {
01063 return ChildCompositeIterator::end(*this);
01064 }
01065
01066
01067
01068 typedef ConstBidirectionalIterator<Composite, Composite, Composite *, ChildCompositeIteratorTraits>
01069 ChildCompositeConstIterator;
01070
01071 ChildCompositeConstIterator beginChildComposite() const
01072
01073 {
01074 return ChildCompositeConstIterator::begin(*this);
01075 }
01076
01077 ChildCompositeConstIterator endChildComposite() const
01078
01079 {
01080 return ChildCompositeConstIterator::end(*this);
01081 }
01082
01083
01084
01085 typedef std::reverse_iterator<ChildCompositeIterator> ChildCompositeReverseIterator;
01086
01087 ChildCompositeReverseIterator rbeginChildComposite()
01088 {
01089 return ChildCompositeReverseIterator(endChildComposite());
01090 }
01091
01092 ChildCompositeReverseIterator rendChildComposite()
01093 {
01094 return ChildCompositeReverseIterator(beginChildComposite());
01095 }
01096
01097
01098
01099 typedef std::reverse_iterator<ChildCompositeConstIterator> ChildCompositeConstReverseIterator;
01100
01101 ChildCompositeConstReverseIterator rbeginChildComposite() const
01102 {
01103 return ChildCompositeConstReverseIterator(endChildComposite());
01104 }
01105
01106 ChildCompositeConstReverseIterator rendChildComposite() const
01107 {
01108 return ChildCompositeConstReverseIterator(beginChildComposite());
01109 }
01110
01111 class BALL_EXPORT CompositeIteratorTraits
01112 {
01113 public:
01114
01115 BALL_INLINE CompositeIteratorTraits()
01116
01117 : bound_(0),
01118 position_(0)
01119 {
01120 }
01121
01122 CompositeIteratorTraits(const Composite& composite)
01123
01124 : bound_(const_cast<Composite*>(&composite)),
01125 position_(0)
01126 {
01127 }
01128
01129 CompositeIteratorTraits(const CompositeIteratorTraits& traits)
01130
01131 : bound_(traits.bound_),
01132 position_(traits.position_)
01133 {
01134 }
01135
01136 BALL_INLINE ~CompositeIteratorTraits() {}
01137
01138 BALL_INLINE bool isValid() const
01139 {
01140 return ((bound_ != 0) && (position_ != 0));
01141 }
01142
01143 BALL_INLINE CompositeIteratorTraits& operator = (const CompositeIteratorTraits& traits)
01144 {
01145 bound_ = traits.bound_;
01146 position_ = traits.position_;
01147 return *this;
01148 }
01149
01150 BALL_INLINE Composite* getContainer() { return bound_; }
01151
01152 BALL_INLINE const Composite* getContainer() const { return bound_; }
01153
01154 BALL_INLINE bool isSingular() const { return (bound_ == 0); }
01155
01156 BALL_INLINE Composite* getPosition() { return position_; }
01157
01158 BALL_INLINE const Composite* getPosition() const { return position_; }
01159 BALL_INLINE void setPosition(Composite* position) { position_ = position; }
01160
01161
01162 BALL_INLINE Composite& getData() { return *position_; }
01163
01164 BALL_INLINE const Composite& getData() const { return *position_; }
01165
01166 BALL_INLINE bool operator == (const CompositeIteratorTraits& traits) const
01167 {
01168 return (position_ == traits.position_);
01169 }
01170
01171 BALL_INLINE bool operator != (const CompositeIteratorTraits& traits) const
01172 {
01173 return !(position_ == traits.position_);
01174 }
01175
01176 BALL_INLINE void invalidate()
01177 {
01178 bound_ = 0;
01179 position_ = 0;
01180 }
01181
01182 BALL_INLINE void toBegin()
01183 {
01184 position_ = bound_;
01185 }
01186
01187 BALL_INLINE bool isBegin() const
01188 {
01189 return (position_ == bound_);
01190 }
01191
01192 BALL_INLINE void toEnd()
01193 {
01194 position_ = 0;
01195 }
01196
01197 BALL_INLINE bool isEnd() const
01198 {
01199 return (position_ == 0);
01200 }
01201
01202 BALL_INLINE void toRBegin()
01203 {
01204 if (bound_ != 0)
01205 {
01206 position_ = findPreviousPosition(0);
01207 }
01208 }
01209
01210 BALL_INLINE bool isRBegin() const
01211 {
01212 return (position_ == findPreviousPosition(0));
01213 }
01214
01215 BALL_INLINE void toREnd()
01216 {
01217 position_ = bound_;
01218 }
01219
01220 BALL_INLINE bool isREnd() const
01221 {
01222 return (position_ == bound_);
01223 }
01224
01225 BALL_INLINE void forward()
01226 {
01227 position_ = findNextPosition(position_);
01228 }
01229
01230 BALL_INLINE void backward()
01231 {
01232 position_ = findPreviousPosition(position_);
01233 }
01234
01235 protected:
01236
01238 Composite* bound_;
01239
01241 Composite* position_;
01242
01243 Composite* findPreviousPosition(Composite* p) const
01244 {
01245
01246
01247
01248 if (p == bound_)
01249 {
01250 return 0;
01251 }
01252
01253
01254
01255
01256 else if (p == 0)
01257 {
01258 if (bound_->last_child_ == 0)
01259 {
01260 return bound_;
01261 }
01262 else
01263 {
01264 p = bound_->last_child_;
01265 }
01266 while (p->last_child_ != 0)
01267 {
01268 p = p->last_child_;
01269 }
01270 }
01271
01272
01273 else if (p->previous_ != 0)
01274 {
01275 p = p->previous_;
01276
01277
01278
01279 while (p->last_child_ != 0)
01280 {
01281 p = p->last_child_;
01282 }
01283 }
01284
01285
01286 else if (p != bound_)
01287 {
01288 p = p->parent_;
01289 }
01290
01291 return p;
01292 }
01293
01294 Composite* findNextPosition(Composite* p) const
01295 {
01296
01297 if (p == 0)
01298 {
01299 return 0;
01300 }
01301
01302
01303 else
01304 {
01305 if (p->first_child_ != 0)
01306 {
01307 p = p->first_child_;
01308 }
01309 else
01310 {
01311
01312 if (p == bound_)
01313 {
01314 return 0;
01315 }
01316
01317 if (p->next_ != 0)
01318 {
01319 p = p->next_;
01320 }
01321
01322
01323
01324
01325 else
01326 {
01327
01328
01329
01330 while (p->next_ == 0)
01331 {
01332 p = p->parent_;
01333 if ((p == bound_) || (p == 0))
01334 {
01335 return 0;
01336 }
01337 }
01338 p = p->next_;
01339 }
01340 }
01341 }
01342 return p;
01343 }
01344 };
01345
01346 friend class CompositeIteratorTraits;
01347
01348 typedef BidirectionalIterator<Composite, Composite, Composite*, CompositeIteratorTraits>
01349 CompositeIterator;
01350
01351 CompositeIterator beginComposite() { return CompositeIterator::begin(*this); }
01352
01353 CompositeIterator endComposite() { return CompositeIterator::end(*this); }
01354
01355 typedef ConstBidirectionalIterator<Composite, Composite, Composite*, CompositeIteratorTraits>
01356 CompositeConstIterator;
01357
01358 CompositeConstIterator beginComposite() const
01359 {
01360 return CompositeConstIterator::begin(*this);
01361 }
01362
01363 CompositeConstIterator endComposite() const
01364 {
01365 return CompositeConstIterator::end(*this);
01366 }
01367
01368
01369 typedef std::reverse_iterator<CompositeIterator> CompositeReverseIterator;
01370
01371 CompositeReverseIterator rbeginComposite()
01372 {
01373 return CompositeReverseIterator(endComposite());
01374 }
01375
01376 CompositeReverseIterator rendComposite()
01377 {
01378 return CompositeReverseIterator(beginComposite());
01379 }
01380
01381
01382 typedef std::reverse_iterator<CompositeConstIterator> CompositeConstReverseIterator;
01383
01384 CompositeConstReverseIterator rbeginComposite() const
01385 {
01386 return CompositeConstReverseIterator(endComposite());
01387 }
01388
01389 CompositeConstReverseIterator rendComposite() const
01390 {
01391 return CompositeConstReverseIterator(beginComposite());
01392 }
01393
01394
01395
01396
01397
01398 void deleteChildrenList_(std::list<Composite*>& composites);
01399
01400 private:
01401
01403 Size getHeight_(Size size, Size& max_height) const ;
01404
01406 Size countDescendants_() const ;
01407
01409 void clone_(Composite& parent, Composite& stack) const ;
01410
01411 template <typename T>
01412 bool applyLevelNostart_(UnaryProcessor<T>& processor, long level)
01413 throw(Exception::GeneralException);
01414
01415 template <typename T>
01416 bool applyChildNostart_(UnaryProcessor<T>& processor)
01417 throw(Exception::GeneralException);
01418
01419 template <typename T>
01420 bool applyPreorderNostart_(UnaryProcessor<T>& processor)
01421 throw(Exception::GeneralException);
01422
01423 template <typename T>
01424 bool applyDescendantPreorderNostart_(UnaryProcessor<T>& processor)
01425 throw(Exception::GeneralException);
01426
01427 template <typename T>
01428 bool applyDescendantPostorderNostart_(UnaryProcessor<T>& processor)
01429 throw(Exception::GeneralException);
01430
01431
01432 void updateSelection_() ;
01433 void determineSelection_() ;
01434 void select_(bool update_parent = true) ;
01435 void deselect_(bool update_parent = true) ;
01436
01437
01438
01439 Size number_of_children_;
01440 Composite* parent_;
01441 Composite* previous_;
01442 Composite* next_;
01443 Composite* first_child_;
01444 Composite* last_child_;
01445 unsigned char properties_;
01446 bool contains_selection_;
01447 Size number_of_selected_children_;
01448 Size number_of_children_containing_selection_;
01449 TimeStamp selection_stamp_;
01450 TimeStamp modification_stamp_;
01451 };
01452
01453 template <typename T>
01454 bool Composite::applyAncestor(UnaryProcessor<T>& processor)
01455 throw(Exception::GeneralException)
01456 {
01457 if (processor.start() == false)
01458 {
01459 return false;
01460 }
01461
01462 Processor::Result result;
01463
01464 for (Composite* composite = parent_; composite != 0; composite = composite->parent_)
01465 {
01466 T* t_ptr;
01467 if ((t_ptr = dynamic_cast<T*>(composite)) != 0)
01468 {
01469 result = processor(*t_ptr);
01470 if (result <= Processor::BREAK)
01471 {
01472 return (result == Processor::BREAK);
01473 }
01474 }
01475 }
01476
01477 return processor.finish();
01478 }
01479
01480 template <typename T>
01481 bool Composite::applyChild(UnaryProcessor<T>& processor)
01482 throw(Exception::GeneralException)
01483 {
01484 return processor.start() && applyChildNostart_(processor) && processor.finish();
01485 }
01486
01487 template <typename T>
01488 bool Composite::applyChildNostart_(UnaryProcessor<T>& processor)
01489 throw(Exception::GeneralException)
01490 {
01491 Processor::Result result = Processor::CONTINUE;
01492
01493 for (Composite* composite = first_child_;
01494 composite != 0; composite = composite->next_)
01495 {
01496 T* t_ptr;
01497 if ((t_ptr = dynamic_cast<T*>(composite)) != 0)
01498 {
01499 result = processor(*t_ptr);
01500 if (result <= Processor::BREAK)
01501 {
01502 break;
01503 }
01504 }
01505 }
01506
01507 return (result >= Processor::BREAK);
01508 }
01509
01510 template <typename T>
01511 bool Composite::applyDescendantPreorder(UnaryProcessor<T>& processor)
01512 throw(Exception::GeneralException)
01513 {
01514 return processor.start() && applyDescendantPreorderNostart_(processor) && processor.finish();
01515 }
01516
01517 template <typename T>
01518 bool Composite::applyDescendantPreorderNostart_(UnaryProcessor<T>& processor)
01519 throw(Exception::GeneralException)
01520 {
01521 Processor::Result result;
01522
01523 for (Composite* composite = first_child_;
01524 composite != 0; composite = composite->next_)
01525 {
01526 T* t_ptr;
01527 if ((t_ptr = dynamic_cast<T*>(composite)) != 0)
01528 {
01529 result = processor(*t_ptr);
01530
01531 if (result <= Processor::BREAK)
01532 {
01533 return (result == Processor::BREAK);
01534 }
01535 }
01536
01537 if (composite->first_child_ != 0 && composite->applyDescendantPreorderNostart_(processor) == false)
01538 {
01539 return false;
01540 }
01541 }
01542
01543 return true;
01544 }
01545
01546 template <typename T>
01547 bool Composite::applyDescendantPostorder(UnaryProcessor<T>& processor)
01548 throw(Exception::GeneralException)
01549 {
01550 return processor.start() && applyDescendantPostorderNostart_(processor) && processor.finish();
01551 }
01552
01553 template <typename T>
01554 bool Composite::applyDescendantPostorderNostart_(UnaryProcessor<T>& processor)
01555 throw(Exception::GeneralException)
01556 {
01557 Processor::Result result;
01558
01559 for (Composite* composite = first_child_;
01560 composite != 0; composite = composite->next_)
01561 {
01562 if (composite->first_child_ != 0 &&
01563 composite->applyDescendantPostorderNostart_(processor) == false)
01564 {
01565 return false;
01566 }
01567
01568 T* t_ptr = dynamic_cast<T*>(composite);
01569 if (t_ptr != 0)
01570 {
01571 result = processor(*t_ptr);
01572
01573 if (result <= Processor::BREAK)
01574 {
01575 return (result == Processor::BREAK);
01576 }
01577 }
01578 }
01579
01580 return true;
01581 }
01582
01583 template <typename T>
01584 bool Composite::applyPostorder(UnaryProcessor<T>& processor)
01585 throw(Exception::GeneralException)
01586 {
01587 if (!processor.start() || !applyDescendantPostorderNostart_(processor))
01588 {
01589 return false;
01590 }
01591
01592 T* t_ptr = dynamic_cast<T*>(this);
01593
01594 return (t_ptr != 0 &&
01595 processor(*t_ptr) >= Processor::BREAK &&
01596 processor.finish() );
01597 }
01598
01599 template <typename T>
01600 bool Composite::applyLevel(UnaryProcessor<T>& processor, long level)
01601 throw(Exception::GeneralException)
01602 {
01603 return processor.start() && applyLevelNostart_(processor, level) && processor.finish();
01604 }
01605
01606 template <typename T>
01607 bool Composite::applyLevelNostart_(UnaryProcessor<T>& processor, long level)
01608 throw(Exception::GeneralException)
01609 {
01610 if (level == 0)
01611 {
01612 T* t_ptr = dynamic_cast<T*>(this);
01613 if (t_ptr != 0)
01614 {
01615 Processor::Result result = processor(*t_ptr);
01616
01617 if (result <= Processor::BREAK)
01618 {
01619 return (result == Processor::BREAK);
01620 }
01621 }
01622 }
01623 else
01624 {
01625 if (--level == 0)
01626 {
01627 return applyChildNostart_(processor);
01628 }
01629 else
01630 {
01631 if (level > 0)
01632 {
01633 for (Composite* composite = first_child_;
01634 composite != 0; composite = composite->next_)
01635 {
01636 if (composite->first_child_ != 0 && composite->applyLevelNostart_(processor, level) == false)
01637 {
01638 return false;
01639 }
01640 }
01641 }
01642 }
01643 }
01644 return true;
01645 }
01646
01647 template <typename T>
01648 bool Composite::applyPreorderNostart_(UnaryProcessor<T>& processor)
01649 throw(Exception::GeneralException)
01650 {
01651 Processor::Result result;
01652 bool return_value;
01653 T* t_ptr = dynamic_cast<T*>(this);
01654 if (t_ptr != 0)
01655 {
01656 result = processor(*t_ptr);
01657
01658 if (result <= Processor::BREAK)
01659 {
01660 return_value = (result == Processor::BREAK);
01661 }
01662 else
01663 {
01664 return_value = applyDescendantPreorderNostart_(processor);
01665 }
01666 }
01667 else
01668 {
01669 return_value = applyDescendantPreorderNostart_(processor);
01670 }
01671
01672 return return_value;
01673 }
01674
01675 template <typename T>
01676 bool Composite::applyDescendant(UnaryProcessor<T>& processor)
01677 throw(Exception::GeneralException)
01678 {
01679 return applyDescendantPreorder(processor);
01680 }
01681
01682 template <typename T>
01683 bool Composite::applyPreorder(UnaryProcessor<T>& processor)
01684 throw(Exception::GeneralException)
01685 {
01686 return processor.start() && applyPreorderNostart_(processor) && processor.finish();
01687 }
01688
01689 template <typename T>
01690 BALL_INLINE
01691 bool Composite::apply(UnaryProcessor<T>& processor)
01692 throw(Exception::GeneralException)
01693 {
01694 return applyPreorder(processor);
01695 }
01696
01697 template <typename T>
01698 BALL_INLINE
01699 T* Composite::getAncestor(const T& )
01700
01701 {
01702 T* T_ptr = 0;
01703
01704 for (Composite* composite_ptr = parent_;
01705 composite_ptr != 0; composite_ptr = composite_ptr->parent_)
01706 {
01707 T_ptr = dynamic_cast<T*>(composite_ptr);
01708 if (T_ptr != 0)
01709 {
01710 break;
01711 }
01712 }
01713
01714 return T_ptr;
01715 }
01716
01717 template <typename T>
01718 BALL_INLINE
01719 const T* Composite::getAncestor(const T& ) const
01720
01721 {
01722 T* t_ptr = 0;
01723 for (Composite* composite_ptr = parent_;
01724 composite_ptr != 0; composite_ptr = composite_ptr->parent_)
01725 {
01726 if ((t_ptr = dynamic_cast<T*>(composite_ptr)) != 0)
01727 {
01728 break;
01729 }
01730 }
01731
01732 return const_cast<const T*>(t_ptr);
01733 }
01734
01735 template <typename T>
01736 BALL_INLINE
01737 T* Composite::getPrevious(const T& )
01738
01739 {
01740
01741 CompositeIterator it(getRoot().endComposite());
01742
01743
01744 it.getTraits().setPosition(this);
01745
01746
01747
01748 if (+it)
01749 {
01750 do
01751 {
01752 --it;
01753 }
01754 while (+it && !RTTI::isKindOf<T>(*it));
01755 }
01756
01757
01758 Composite* ptr = 0;
01759 if (+it)
01760 {
01761 ptr = &*it;
01762 }
01763
01764 return dynamic_cast<T*>(ptr);
01765 }
01766
01767 template <typename T>
01768 BALL_INLINE
01769 const T* Composite::getPrevious(const T& dummy) const
01770
01771 {
01772
01773 Composite* nonconst_this = const_cast<Composite*>(this);
01774
01775 return const_cast<const T*>(nonconst_this->getPrevious(dummy));
01776 }
01777
01778 template <typename T>
01779 BALL_INLINE
01780 T* Composite::getNext(const T& )
01781
01782 {
01783
01784 CompositeIterator it(getRoot().beginComposite());
01785
01786
01787 it.getTraits().setPosition(this);
01788
01789
01790
01791 do
01792 {
01793 it++;
01794 }
01795 while (it.isValid() && !RTTI::isKindOf<T>(*it));
01796
01797
01798
01799 Composite* ptr = 0;
01800 if (+it)
01801 {
01802 ptr = &*it;
01803 }
01804
01805 return dynamic_cast<T*>(ptr);
01806 }
01807
01808 template <typename T>
01809 BALL_INLINE
01810 const T* Composite::getNext(const T& dummy) const
01811
01812 {
01813
01814 Composite* nonconst_this = const_cast<Composite*>(this);
01815
01816 return const_cast<const T*>(nonconst_this->getNext(dummy));
01817 }
01818
01819 template <typename T>
01820 BALL_INLINE
01821 bool Composite::hasAncestor(const T& dummy ) const
01822
01823 {
01824 return (getAncestor(dummy) != 0);
01825 }
01826
01827 # ifndef BALL_NO_INLINE_FUNCTIONS
01828 # include <BALL/CONCEPT/composite.iC>
01829 # endif
01830
01831
01832 }
01833
01834 #endif // BALL_CONCEPT_COMPOSITE_H