00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef NODEVISITOR_H
00021 #define NODEVISITOR_H
00022
00023 #include <vector>
00024
00025 #include "node.h"
00026 #include "nodeiterator.h"
00027 #include "nodeutil.h"
00028 #include "nodeoutputstrategy.h"
00029
00030
00031 namespace treecomp
00032 {
00033
00034
00035 template<class _TContent>
00036 class Node;
00037 template<class _TContent>
00038 class NormalNode;
00039 template<class _TContent>
00040 class RootNode;
00041
00042 template<class _TContent>
00043 class OutputStrategy;
00044 template<class _TContent>
00045 class NullOutputStrategy;
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 template<class _Node, class _NormalNode, class _RootNode>
00062 class NodeVisitorBase
00063 {
00064 public:
00065 typedef NodeVisitorBase<_Node,_NormalNode,_RootNode> _Self;
00066
00067 explicit NodeVisitorBase() {}
00068
00069
00070
00071 virtual ~NodeVisitorBase(){}
00072
00073 virtual void visitNormalNode(_NormalNode* node) = 0;
00074 virtual void visitRootNode(_RootNode* node) = 0;
00075 };
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 template<class _TIter,
00092 class _Node,
00093 class _NormalNode,
00094 class _RootNode>
00095 class NodeVisitor : public NodeVisitorBase<_Node, _NormalNode, _RootNode>
00096 {
00097 public:
00098 typedef NodeVisitor<_TIter,_Node,_NormalNode,_RootNode> _Self;
00099 typedef NodeVisitorBase<_Node,_NormalNode,_RootNode> _Base;
00100
00101
00102 explicit NodeVisitor()
00103 : _Base(), m_start(0), m_iter(new _TIter), m_recursive(true)
00104 {}
00105
00106
00107 explicit NodeVisitor(const _Self& nv)
00108 : _Base(), m_start(nv.m_start), m_iter(nv.m_iter->clone()), m_recursive(nv.m_recursive)
00109 {}
00110
00111
00112
00113 virtual ~NodeVisitor();
00114
00115
00116 virtual void operator()(_TIter& iter) = 0;
00117 virtual void operator()(_Node* node) { _TIter iter(node); this->operator()(iter); }
00118
00119 virtual void visitNormalNode(_NormalNode* node) = 0;
00120 virtual void visitRootNode(_RootNode* node) = 0;
00121
00122
00123 virtual void setRecursive(bool recursive) { m_recursive = recursive; }
00124 virtual bool isRecursive() const { return m_recursive; }
00125
00126 protected:
00127
00128 virtual void iterate(NodeVisitorBase<_Node,_NormalNode,_RootNode>* self);
00129
00130 virtual void init(_TIter& iter);
00131
00132 _Node* m_start;
00133
00134 _TIter* m_iter;
00135
00136 private:
00137
00138 _Self& operator=(const _Self& nv){return *this;}
00139
00140 bool m_recursive;
00141 };
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 template<class _TContent, class _TIter>
00158 class OutputVisitor
00159 : public NodeVisitor<typename _TIter::const_iterator,const Node<_TContent>,
00160 const NormalNode<_TContent>,const RootNode<_TContent> >
00161 {
00162 public:
00163 typedef OutputVisitor<_TContent,_TIter> _Self;
00164 typedef NodeVisitor<typename _TIter::const_iterator,
00165 const Node<_TContent>,const NormalNode<_TContent>,const RootNode<_TContent> >
00166 _Base;
00167 typedef OutputStrategy<_TContent> strategy_type;
00168
00169
00170
00171 explicit OutputVisitor(strategy_type* os=0);
00172 virtual ~OutputVisitor() {}
00173
00174 virtual _Self* construct() const { return new _Self; }
00175 virtual _Self* clone() const { return new _Self(*this); }
00176
00177 virtual void operator()(const Node<_TContent>* node) { typename _TIter::const_iterator iter(node); this->operator()(iter); }
00178
00179 virtual void operator()(_TIter& iter);
00180 virtual void visitNormalNode(const NormalNode<_TContent>* node);
00181 virtual void visitRootNode(const RootNode<_TContent>* node);
00182
00183 void setOutputStrategy(strategy_type* os);
00184 void setNullOutputStrategy();
00185 virtual strategy_type* outputStrategy() { return m_outputStrategy; }
00186
00187 protected:
00188 explicit OutputVisitor(const OutputVisitor& ov)
00189 : _Base(ov), m_outputStrategy(ov.m_outputStrategy) {}
00190
00191 strategy_type* m_outputStrategy;
00192 NullOutputStrategy<_TContent> m_nulloutputstrategy;
00193
00194 private:
00195 virtual OutputVisitor& operator=(const OutputVisitor&) {return *this;}
00196 };
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 template<class _TContent, class _TIter, class _TContainer=std::vector<Node<_TContent>*> >
00210 class CollectVisitor
00211 : public NodeVisitor<_TIter, Node<_TContent>, NormalNode<_TContent>, RootNode<_TContent> >
00212 {
00213 public:
00214 typedef CollectVisitor<_TContent,_TIter,_TContainer> _Self;
00215 typedef NodeVisitor<_TIter,Node<_TContent>, NormalNode<_TContent>, RootNode<_TContent> >
00216 _Base;
00217
00218
00219 explicit CollectVisitor() : _Base() {}
00220 virtual _Self* construct() const { return new _Self(); }
00221 virtual _Self* clone() const { return new _Self(*this); }
00222
00223 virtual void operator()(_TIter& iter);
00224 virtual void visitNormalNode(NormalNode<_TContent>* node);
00225 virtual void visitRootNode(RootNode<_TContent>* node);
00226
00227 virtual _TContainer getCollected() { return m_container; }
00228
00229 protected:
00230 explicit CollectVisitor(const CollectVisitor& cv)
00231 : _Base(cv) {}
00232 void addNode(Node<_TContent>* node);
00233 _TContainer m_container;
00234 private:
00235 virtual CollectVisitor& operator=(const CollectVisitor&) {return *this;}
00236 };
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 template<class _TContent, class _TIter>
00251 class DepthVisitor
00252 : public NodeVisitor<typename _TIter::const_iterator,const Node<_TContent>,
00253 const NormalNode<_TContent>,const RootNode<_TContent> >
00254 {
00255 public:
00256 typedef DepthVisitor<_TContent,_TIter> _Self;
00257 typedef NodeVisitor<typename _TIter::const_iterator,
00258 const Node<_TContent>,const NormalNode<_TContent>,const RootNode<_TContent> >
00259 _Base;
00260
00261
00262 explicit DepthVisitor()
00263 : _Base(), m_curDepth(0), m_maxDepth(0), m_curParent(0), m_isLeave(false)
00264 {}
00265
00266 virtual _Self* construct() const { return new _Self(); }
00267 virtual _Self* clone() const { return new _Self(*this); }
00268
00269 virtual void operator()(_TIter& iter);
00270 virtual void visitNormalNode(const NormalNode<_TContent>* node);
00271 virtual void visitRootNode(const RootNode<_TContent>* node);
00272
00273 virtual int getDepth() { return m_maxDepth; }
00274
00275 protected:
00276 explicit DepthVisitor(const DepthVisitor& cv)
00277 : _Base(cv) {}
00278 void measure(const Node<_TContent>* node);
00279 int m_curDepth;
00280 int m_maxDepth;
00281 const Node<_TContent>* m_curParent;
00282 bool m_isLeave;
00283 private:
00284 virtual DepthVisitor& operator=(const DepthVisitor&) {return *this;}
00285 };
00286
00287
00288
00289
00290
00291
00292
00293 template<class _TIter, class _Node, class _NormalNode, class _RootNode>
00294 void
00295 NodeVisitor<_TIter,_Node,_NormalNode,_RootNode>::iterate(
00296 NodeVisitorBase<_Node,_NormalNode,_RootNode>* self)
00297 {
00298 _Node* node=0;
00299 if (m_recursive && m_iter)
00300 while(!m_iter->isEnd())
00301 {
00302 node = &(m_iter->operator*());
00303 assert(node!=0);
00304 node->acceptVisitor(self);
00305
00306 m_iter->operator++();
00307 }
00308 else
00309 {
00310 assert(m_start!=0);
00311 m_start->acceptVisitor(self);
00312
00313 }
00314 }
00315
00316 template<class _TIter, class _Node, class _NormalNode, class _RootNode>
00317
00318 void
00319 NodeVisitor<_TIter,_Node,_NormalNode,_RootNode>::init(_TIter& iter)
00320 {
00321
00322 if (m_iter)
00323 {
00324 delete m_iter;
00325 m_iter=0;
00326 }
00327 m_iter = new _TIter(iter);
00328 m_start = &(m_iter->operator*());
00329 assert(m_start!=0);
00330 }
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346 template<class _TIter, class _Node, class _NormalNode, class _RootNode>
00347 NodeVisitor<_TIter,_Node,_NormalNode,_RootNode>::~NodeVisitor<_TIter,_Node,_NormalNode,_RootNode>()
00348 {
00349 if (m_iter)
00350 delete m_iter;
00351 }
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365 template<class _TContent, class _TIter>
00366 OutputVisitor<_TContent,_TIter>::OutputVisitor(strategy_type* os)
00367 : _Base(), m_nulloutputstrategy(&cout)
00368 {
00369 if (os == 0)
00370 m_outputStrategy = &m_nulloutputstrategy;
00371 else
00372 m_outputStrategy = os;
00373 assert(m_outputStrategy!=0);
00374 }
00375
00376
00377
00378
00379
00380
00381
00382 template<class _TContent, class _TIter>
00383 void OutputVisitor<_TContent,_TIter>::operator()(_TIter& iter)
00384 {
00385 init(iter);
00386 assert(m_outputStrategy!=0);
00387 m_outputStrategy->writeHeader();
00388 iterate(this);
00389 m_outputStrategy->writeFooter();
00390 }
00391
00392
00393
00394
00395
00396
00397 template<class _TContent, class _TIter>
00398 void OutputVisitor<_TContent,_TIter>::visitNormalNode(const NormalNode<_TContent>* node)
00399 {
00400 assert(m_outputStrategy!=0);
00401 m_outputStrategy->writeNormalNode(node);
00402 }
00403
00404
00405
00406
00407
00408 template<class _TContent, class _TIter>
00409 void OutputVisitor<_TContent,_TIter>::visitRootNode(const RootNode<_TContent>* node)
00410 {
00411 assert(m_outputStrategy!=0);
00412 m_outputStrategy->writeRootNode(node);
00413 }
00414
00415
00416
00417
00418
00419 template<class _TContent, class _TIter>
00420 void OutputVisitor<_TContent,_TIter>::setOutputStrategy(strategy_type* os)
00421 {
00422 if (os)
00423 m_outputStrategy = os;
00424 else
00425 m_outputStrategy = &m_nulloutputstrategy;
00426 assert(m_outputStrategy!=0);
00427 }
00428
00429
00430
00431
00432 template<class _TContent, class _TIter>
00433 void OutputVisitor<_TContent,_TIter>::setNullOutputStrategy()
00434 {
00435
00436 setOutputStrategy(0);
00437 assert(m_outputStrategy->isNull()==true);
00438 }
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449 template<class _TContent, class _TIter, class _TContainer>
00450 void CollectVisitor<_TContent,_TIter,_TContainer>::operator()(_TIter& iter)
00451 {
00452 init(iter);
00453 m_container.clear();
00454 iterate(this);
00455 }
00456
00457
00458
00459
00460
00461 template<class _TContent, class _TIter, class _TContainer>
00462 void CollectVisitor<_TContent,_TIter,_TContainer>::visitNormalNode(NormalNode<_TContent>* node)
00463 {
00464 addNode(node);
00465 }
00466
00467
00468
00469
00470
00471 template<class _TContent, class _TIter, class _TContainer>
00472 void CollectVisitor<_TContent,_TIter,_TContainer>::visitRootNode(RootNode<_TContent>* node)
00473 {
00474 addNode(node);
00475 }
00476
00477
00478
00479
00480
00481 template<class _TContent, class _TIter, class _TContainer>
00482 void CollectVisitor<_TContent,_TIter,_TContainer>::addNode(Node<_TContent>* node)
00483 {
00484 m_container.push_back(node);
00485 }
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498 template<class _TContent, class _TIter>
00499
00500 void DepthVisitor<_TContent,_TIter>::operator()(_TIter& iter)
00501 {
00502 init(iter);
00503 m_curDepth = 1;
00504 m_maxDepth = 1;
00505 m_isLeave = false;
00506 m_curParent = 0;
00507
00508 iterate(this);
00509 }
00510
00511
00512
00513
00514
00515 template<class _TContent, class _TIter>
00516 void DepthVisitor<_TContent,_TIter>::visitNormalNode(const NormalNode<_TContent>* node)
00517 {
00518 measure(node);
00519 }
00520
00521
00522
00523
00524
00525 template<class _TContent, class _TIter>
00526 void DepthVisitor<_TContent,_TIter>::visitRootNode(const RootNode<_TContent>* node)
00527 {
00528 measure(node);
00529 }
00530
00531
00532
00533
00534
00535 template<class _TContent, class _TIter>
00536 void DepthVisitor<_TContent,_TIter>::measure(const Node<_TContent>* node)
00537 {
00538 if (node->getParent() != m_curParent)
00539 {
00540
00541 if (!m_isLeave)
00542 {
00543
00544
00545 ++m_curDepth;
00546 }
00547 else
00548 {
00549
00550
00551 --m_curDepth;
00552 }
00553 if (m_curDepth > m_maxDepth)
00554 m_maxDepth = m_curDepth;
00555 m_curParent = node->getParent();
00556 }
00557 if (node->getNumChildren())
00558 m_isLeave = false;
00559 else
00560 m_isLeave = true;
00561 }
00562
00563 }
00564
00565 #endif //NODEVISITOR_H