EvolvingObjects
|
00001 #ifndef PARSE_TREE_HH 00002 #define PARSE_TREE_HH 00003 00168 #include <vector> 00169 #include <utility> // for swap 00170 00171 #ifdef _MSC_VER 00172 #pragma warning(disable : 4786) // disable this nagging warning about the limitations of the mirkosoft debugger 00173 #endif 00174 00175 namespace gp_parse_tree 00176 { 00177 00178 #include "node_pool.h" 00179 00181 template <class T> 00182 inline void do_the_swap(T& a, T& b) 00183 { 00184 T tmp = a; 00185 a = b; 00186 b = tmp; 00187 } 00188 00189 template <class T> class parse_tree 00190 { 00191 public : 00192 00193 00194 class subtree 00195 { 00196 00202 #if (defined(__GNUC__) || defined(_MSC_VER)) && !(defined(_MT) || defined(MACOSX) || defined(__APPLE__)) // not multithreaded (or MACOSX - J. Eggermont) 00203 Node_alloc<T> node_allocator; 00204 Tree_alloc<subtree> tree_allocator; 00205 #else 00206 Standard_Node_alloc<T> node_allocator; 00207 Standard_alloc<subtree> tree_allocator; 00208 #endif 00209 00210 public : 00211 00212 typedef subtree* iterator; 00213 typedef const subtree* const_iterator; 00214 00215 /* Constructors, assignments */ 00216 00217 subtree(void) : content(node_allocator.allocate()), args(0), parent(0), _cumulative_size(0), _depth(0), _size(1) 00218 {} 00219 subtree(const subtree& s) 00220 : content(node_allocator.allocate()), 00221 args(0), 00222 parent(0), 00223 _cumulative_size(1), 00224 _depth(1), 00225 _size(1) 00226 { 00227 copy(s); 00228 } 00229 00230 subtree(const T& t) : content(node_allocator.allocate()), args(0), parent(0), _cumulative_size(0), _depth(0), _size(1) 00231 { copy(t); } 00232 00233 template <class It> 00234 subtree(It b, It e) : content(node_allocator.allocate()), args(0), parent(0), _cumulative_size(0), _depth(0), _size(1) 00235 { // initialize in prefix order for efficiency reasons 00236 init(b, --e); 00237 } 00238 00239 virtual ~subtree(void) { tree_allocator.deallocate(args, arity()); node_allocator.deallocate(content); } 00240 00241 subtree& operator=(const subtree& s) 00242 { 00243 if (s.get_root() == get_root()) 00244 { // from the same tree, maybe a child. Don't take any chances 00245 subtree anotherS = s; 00246 return copy(anotherS); 00247 } 00248 00249 copy(s); 00250 updateAfterInsert(); 00251 return *this; 00252 } 00253 00254 subtree& operator=(const T& t) { copy(t); updateAfterInsert(); return *this; } 00255 00256 /* Access to the nodes */ 00257 00258 T& operator*(void) { return *content; } 00259 const T& operator*(void) const { return *content; } 00260 T* operator->(void) { return content; } 00261 const T* operator->(void) const { return content; } 00262 00263 /* Equality, inequality check, Node needs to implement operator== */ 00264 00265 bool operator==(const subtree& other) const 00266 { 00267 if (! (*content == *other.content)) 00268 return false; 00269 00270 for (int i = 0; i < arity(); i++) 00271 { 00272 if (!(args[i] == other.args[i])) 00273 return false; 00274 } 00275 00276 return true; 00277 } 00278 00279 bool operator !=(const subtree& other) const 00280 { 00281 return !operator==(other); 00282 } 00283 00284 /* Arity */ 00285 int arity(void) const { return content->arity(); } 00286 00287 /* Evaluation with an increasing amount of user defined arguments */ 00288 template <class RetVal> 00289 void apply(RetVal& v) const { (*content)(v, begin()); } 00290 00291 template <class RetVal, class It> 00292 void apply(RetVal& v, It values) const 00293 { 00294 (*content)(v, begin(), values); 00295 } 00296 00297 template <class RetVal, class It> 00298 void apply_mem_func(RetVal& v, It misc, void (T::* f)(RetVal&, typename subtree::iterator, It)) 00299 { 00300 (content->*f)(v, begin(), misc); 00301 } 00302 00303 00304 /* template <class RetVal, class It, class It2> 00305 void apply(RetVal& v, It values, It2 moreValues) const 00306 { (*content)(v, begin(), values, moreValues); } 00307 00308 template <class RetVal, class It, class It2, class It3> 00309 void apply(RetVal& v, It values, It2 moreValues, It3 evenMoreValues) const 00310 { (*content)(v, begin(), values, moreValues, evenMoreValues); } 00311 */ 00312 00313 template <class Pred> 00314 void find_nodes(std::vector<subtree*>& result, Pred& p) 00315 { 00316 if (p(*content)) 00317 { 00318 result.push_back(this); 00319 } 00320 00321 for (int i = 0; i < arity(); ++i) 00322 { 00323 args[i].find_nodes(result, p); 00324 } 00325 } 00326 00327 template <class Pred> 00328 void find_nodes(std::vector<const subtree*>& result, Pred& p) const 00329 { 00330 if (p(*content)) 00331 { 00332 result.push_back(this); 00333 } 00334 00335 for (int i = 0; i < arity(); ++i) 00336 { 00337 args[i].find_nodes(result, p); 00338 } 00339 } 00340 00341 /* Iterators */ 00342 00343 iterator begin(void) { return args; } 00344 const_iterator begin(void) const { return args; } 00345 00346 iterator end(void) { return args + arity(); } 00347 const_iterator end(void) const { return args + arity(); } 00348 00349 subtree& operator[](int i) { return *(begin() + i); } 00350 const subtree& operator[](int i) const { return *(begin() + i); } 00351 00352 /* Some statistics */ 00353 00354 size_t size(void) const { return _size; } 00355 00356 size_t cumulative_size(void) const { return _cumulative_size; } 00357 size_t depth(void) const { return _depth; } 00358 00359 const subtree& select_cumulative(size_t which) const 00360 { return imp_select_cumulative(which); } 00361 00362 subtree& select_cumulative(size_t which) 00363 { return const_cast<subtree&>(imp_select_cumulative(which)); } 00364 00365 subtree& get_node(size_t which) 00366 { return const_cast<subtree&>(imp_get_node(which));} 00367 const subtree& get_node(size_t which) const 00368 { return imp_get_node(which); } 00369 00370 subtree* get_parent(void) { return parent; } 00371 const subtree* get_parent(void) const { return parent; } 00372 00373 void clear(void) 00374 { tree_allocator.deallocate(args, arity()); args = 0; *content = T(); parent = 0; _cumulative_size = 0; _depth = 0; _size = 0; } 00375 00376 void swap(subtree& y) 00377 { 00378 do_the_swap(content, y.content); 00379 do_the_swap(args, y.args); 00380 00381 adopt(); 00382 y.adopt(); 00383 00384 do_the_swap(parent, y.parent); 00385 00386 do_the_swap(_cumulative_size, y._cumulative_size); 00387 do_the_swap(_depth, y._depth); 00388 do_the_swap(_size, y._size); 00389 updateAfterInsert(); 00390 } 00391 00392 protected : 00393 00394 virtual void updateAfterInsert(void) 00395 { 00396 _depth = 0; 00397 _size = 1; 00398 _cumulative_size = 0; 00399 00400 for (iterator it = begin(); it != end(); ++it) 00401 { 00402 _size += it->size(); 00403 _cumulative_size += it->_cumulative_size; 00404 _depth = it->_depth > _depth? it->_depth: _depth; 00405 } 00406 _cumulative_size += _size; 00407 _depth++; 00408 00409 if (parent) 00410 parent->updateAfterInsert(); 00411 } 00412 00413 private : 00414 00415 const subtree& imp_select_cumulative(size_t which) const 00416 { 00417 if (which >= (_cumulative_size - size())) 00418 return *this; 00419 // else 00420 00421 for (int i = arity() - 1; i >= 0; --i) 00422 { 00423 if (which < args[i]._cumulative_size) 00424 return args[i].imp_select_cumulative(which); 00425 which -= args[i]._cumulative_size; 00426 } 00427 00428 return *this; // error! 00429 } 00430 00431 const subtree& imp_get_node(size_t which) const 00432 { 00433 if (which == size() - 1) 00434 return *this; 00435 00436 for (int i = arity() - 1; i >= 0; --i) 00437 { 00438 unsigned c_size = args[i].size(); 00439 if (which < c_size) 00440 return args[i].imp_get_node(which); 00441 which -= c_size; 00442 } 00443 00444 return *this; // error! 00445 } 00446 00447 const subtree* get_root(void) const 00448 { 00449 if (parent == 0) 00450 return this; 00451 // else 00452 00453 return parent->get_root(); 00454 } 00455 subtree& copy(const subtree& s) 00456 { 00457 int old_arity = arity(); 00458 00459 int new_arity = s.arity(); 00460 00461 if (new_arity != old_arity) 00462 { 00463 tree_allocator.deallocate(args, old_arity); 00464 00465 args = tree_allocator.allocate(new_arity); 00466 } 00467 00468 switch(new_arity) 00469 { 00470 case 3 : args[2].copy(s.args[2]); args[2].parent = this; // no break! 00471 case 2 : args[1].copy(s.args[1]); args[1].parent = this; 00472 case 1 : args[0].copy(s.args[0]); args[0].parent = this; 00473 case 0 : break; 00474 default : 00475 { 00476 for (int i = 0; i < new_arity; ++i) 00477 { 00478 args[i].copy(s.args[i]); 00479 args[i].parent = this; 00480 } 00481 } 00482 } 00483 00484 *content = *s.content; 00485 _size = s._size; 00486 _depth = s._depth; 00487 _cumulative_size = s._cumulative_size; 00488 00489 return *this; 00490 } 00491 00492 subtree& copy(const T& t) 00493 { 00494 int oldArity = arity(); 00495 00496 if (content != &t) 00497 *content = t; 00498 else 00499 oldArity = -1; 00500 00501 int ar = arity(); 00502 00503 if (ar != oldArity) 00504 { 00505 if (oldArity != -1) 00506 tree_allocator.deallocate(args, oldArity); 00507 00508 args = tree_allocator.allocate(ar); 00509 00510 //if (ar > 0) 00511 // args = new subtree [ar]; 00512 //else 00513 // args = 0; 00514 } 00515 00516 adopt(); 00517 updateAfterInsert(); 00518 return *this; 00519 } 00520 00521 void disown(void) 00522 { 00523 switch(arity()) 00524 { 00525 case 3 : args[2].parent = 0; // no break! 00526 case 2 : args[1].parent = 0; 00527 case 1 : args[0].parent = 0; break; 00528 case 0 : break; 00529 default : 00530 { 00531 for (iterator it = begin(); it != end(); ++it) 00532 { 00533 it->parent = 0; 00534 } 00535 } 00536 } 00537 00538 } 00539 00540 void adopt(void) 00541 { 00542 switch(arity()) 00543 { 00544 case 3 : args[2].parent = this; // no break! 00545 case 2 : args[1].parent = this; 00546 case 1 : args[0].parent = this; break; 00547 case 0 : break; 00548 default : 00549 { 00550 for (iterator it = begin(); it != end(); ++it) 00551 { 00552 it->parent = this; 00553 } 00554 } 00555 } 00556 } 00557 00558 template <class It> 00559 void init(It b, It& last) 00560 { 00561 *this = *last; 00562 00563 #ifndef NDEBUG 00564 if (last == b && arity() > 0) 00565 { 00566 throw "subtree::init()"; 00567 } 00568 #endif 00569 00570 for (int i = 0; i < arity(); ++i) 00571 { 00572 args[i].parent = 0; 00573 args[i].init(b, --last); 00574 args[i].parent = this; 00575 } 00576 00577 updateAfterInsert(); 00578 } 00579 00580 T* content; 00581 subtree* args; 00582 subtree* parent; 00583 00584 size_t _cumulative_size; 00585 size_t _depth; 00586 size_t _size; 00587 }; 00588 00589 // Continuing with parse_tree 00590 00591 typedef T value_type; 00592 00593 /* Constructors and Assignments */ 00594 00595 parse_tree(void) : _root(), pushed() {} 00596 parse_tree(const parse_tree& org) : _root(org._root), pushed(org.pushed) { } 00597 parse_tree(const subtree& sub) : _root(sub), pushed() { } 00598 00599 template <class It> 00600 parse_tree(It b, It e) : _root(b, e), pushed() {} 00601 00602 virtual ~parse_tree(void) {} 00603 00604 parse_tree& operator=(const parse_tree& org) { return copy(org); } 00605 parse_tree& operator=(const subtree& sub) 00606 { return copy(sub); } 00607 00608 00609 /* Equality and inequality */ 00610 00611 bool operator==(const parse_tree& other) const 00612 { return _root == other._root; } 00613 00614 bool operator !=(const parse_tree& other) const 00615 { return !operator==(other); } 00616 00617 /* Simple tree statistics */ 00618 00619 size_t size(void) const { return _root.size(); } 00620 size_t depth(void) const { return _root.depth(); } 00621 void clear(void) { _root.clear(); pushed.resize(0); } 00622 00623 /* Evaluation (application), with an increasing number of user defined arguments */ 00624 00625 template <class RetVal> 00626 void apply(RetVal& v) const 00627 { _root.apply(v); } 00628 00629 template <class RetVal, class It> 00630 void apply(RetVal& v, It varValues) const 00631 { _root.apply(v, varValues); } 00632 00633 template <class RetVal, class It> 00634 void apply_mem_func(RetVal& v, It misc, void (T::* f)(RetVal&, typename subtree::iterator, It)) 00635 { 00636 _root.apply_mem_func(v, misc, f); 00637 } 00638 00639 //template <class RetVal, class It, class It2> 00640 // void apply(RetVal& v, It varValues, It2 moreValues) const 00641 // { _root.apply(v, varValues, moreValues); } 00642 00643 //template <class RetVal, class It, class It2, class It3> 00644 // void apply(RetVal& v, It varValues, It2 moreValues, It3 evenMoreValues) const 00645 // { _root.apply(v, varValues, moreValues, evenMoreValues); } 00646 00647 template <class Pred> 00648 void find_nodes(std::vector<subtree*>& result, Pred& p) 00649 { 00650 _root.find_nodes(result, p); 00651 } 00652 00653 template <class Pred> 00654 void find_nodes(std::vector<const subtree*>& result, Pred& p) const 00655 { 00656 _root.find_nodes(p); 00657 } 00658 00659 /* Customized Swap */ 00660 void swap(parse_tree<T>& other) 00661 { 00662 do_the_swap(pushed, other.pushed); 00663 _root.swap(other._root); 00664 } 00665 00666 /* Definitions of the iterators */ 00667 00668 class base_iterator 00669 { 00670 public : 00671 00672 base_iterator() {} 00673 base_iterator(subtree* n) { node = n; } 00674 00675 base_iterator& operator=(const base_iterator& org) 00676 { node = org.node; return *this; } 00677 00678 bool operator==(const base_iterator& org) const 00679 { return node == org.node; } 00680 bool operator!=(const base_iterator& org) const 00681 { return !operator==(org); } 00682 00683 base_iterator operator+(size_t n) const 00684 { 00685 base_iterator tmp = *this; 00686 00687 for(;n != 0; --n) 00688 { 00689 ++tmp; 00690 } 00691 00692 return tmp; 00693 } 00694 00695 base_iterator& operator++(void) 00696 { 00697 subtree* parent = node->get_parent(); 00698 00699 if (parent == 0) 00700 { 00701 node = 0; 00702 return *this; 00703 } 00704 // else 00705 typename subtree::iterator it; 00706 for (it = parent->begin(); it != parent->end(); ++it) 00707 { 00708 if (node == &(*it)) 00709 break; 00710 } 00711 00712 if (it == parent->begin()) 00713 node = parent; 00714 else 00715 { 00716 node = &(--it)->get_node(0); 00717 } 00718 00719 return *this; 00720 } 00721 00722 base_iterator operator++(int) 00723 { 00724 base_iterator tmp = *this; 00725 operator++(); 00726 return tmp; 00727 } 00728 00729 protected : 00730 subtree* node; 00731 }; 00732 00733 class iterator : public base_iterator 00734 { 00735 public: 00736 00737 using base_iterator::node; 00738 00739 typedef std::forward_iterator_tag iterator_category; 00740 typedef subtree value_type; 00741 typedef size_t distance_type; 00742 typedef size_t difference_type; 00743 typedef subtree* pointer; 00744 typedef subtree& reference; 00745 00746 iterator() : base_iterator() {} 00747 iterator(subtree* n): base_iterator(n) {} 00748 iterator& operator=(const iterator& org) 00749 { base_iterator::operator=(org); return *this; } 00750 00751 subtree& operator*(void) { return *node; } 00752 subtree* operator->(void) { return node; } 00753 }; 00754 00755 00756 00757 class embedded_iterator : public base_iterator 00758 { 00759 public: 00760 00761 using base_iterator::node; 00762 00763 typedef std::forward_iterator_tag iterator_category; 00764 typedef T value_type; 00765 typedef size_t distance_type; 00766 typedef size_t difference_type; 00767 typedef T* pointer; 00768 typedef T& reference; 00769 00770 embedded_iterator() : base_iterator() {} 00771 embedded_iterator(subtree* n): base_iterator(n) {} 00772 embedded_iterator& operator=(const embedded_iterator& org) 00773 { base_iterator::operator=(org); return *this; } 00774 00775 T& operator*(void) { return **node; } 00776 T* operator->(void) { return &**node; } 00777 }; 00778 00779 class base_const_iterator 00780 { 00781 public: 00782 00783 base_const_iterator() {} 00784 base_const_iterator(const subtree* n) { node = n; } 00785 00786 base_const_iterator& operator=(const base_const_iterator& org) 00787 { node = org.node; return *this; } 00788 00789 bool operator==(const base_const_iterator& org) const 00790 { return node == org.node; } 00791 bool operator!=(const base_const_iterator& org) const 00792 { return !operator==(org); } 00793 00794 base_const_iterator& operator++(void) 00795 { 00796 const subtree* parent = node->get_parent(); 00797 00798 if (parent == 0) 00799 { 00800 node = 0; 00801 return *this; 00802 } 00803 // else 00804 typename subtree::const_iterator it; 00805 00806 for (it = parent->begin(); it != parent->end(); ++it) 00807 { 00808 if (node == &(*it)) 00809 break; 00810 } 00811 00812 if (it == parent->begin()) 00813 node = parent; 00814 else 00815 node = &(--it)->get_node(0); 00816 return *this; 00817 } 00818 00819 base_const_iterator operator++(int) 00820 { 00821 base_const_iterator tmp = *this; 00822 operator++(); 00823 return tmp; 00824 } 00825 00826 protected : 00827 00828 const subtree* node; 00829 }; 00830 00831 class const_iterator : public base_const_iterator 00832 { 00833 public: 00834 00835 using base_const_iterator::node; 00836 00837 typedef std::forward_iterator_tag iterator_category; 00838 typedef const subtree value_type; 00839 typedef size_t distance_type; 00840 typedef size_t difference_type; 00841 typedef const subtree* pointer; 00842 typedef const subtree& reference; 00843 00844 const_iterator() : base_const_iterator() {} 00845 const_iterator(const subtree* n): base_const_iterator(n) {} 00846 const_iterator& operator=(const const_iterator& org) 00847 { base_const_iterator::operator=(org); return *this; } 00848 00849 const subtree& operator*(void) { return *node; } 00850 const subtree* operator->(void) { return node; } 00851 }; 00852 00853 class embedded_const_iterator : public base_const_iterator 00854 { 00855 public: 00856 00857 using base_const_iterator::node; 00858 00859 typedef std::forward_iterator_tag iterator_category; 00860 typedef const T value_type; 00861 typedef size_t distance_type; 00862 typedef size_t difference_type; 00863 typedef const T* pointer; 00864 typedef const T& reference; 00865 00866 embedded_const_iterator() : base_const_iterator() {} 00867 embedded_const_iterator(const subtree* n): base_const_iterator(n) {} 00868 embedded_const_iterator& operator=(const embedded_const_iterator& org) 00869 { base_const_iterator::operator=(org); return *this; } 00870 00871 embedded_const_iterator operator+(size_t n) const 00872 { 00873 embedded_const_iterator tmp = *this; 00874 00875 for(;n != 0; --n) 00876 { 00877 ++tmp; 00878 } 00879 00880 return tmp; 00881 } 00882 00883 const T& operator*(void) const { return **node; } 00884 const T* operator->(void) const { return node->operator->(); } 00885 }; 00886 00887 /* Iterator access */ 00888 00889 iterator begin(void) { return iterator(&operator[](0)); } 00890 const_iterator begin(void) const { return const_iterator(&operator[](0)); } 00891 iterator end(void) { return iterator(0); } 00892 const_iterator end(void) const { return const_iterator(0);} 00893 00894 embedded_iterator ebegin(void) { return embedded_iterator(&operator[](0)); } 00895 embedded_const_iterator ebegin(void) const { return embedded_const_iterator(&operator[](0)); } 00896 embedded_iterator eend(void) { return embedded_iterator(0); } 00897 embedded_const_iterator eend(void) const { return embedded_const_iterator(0);} 00898 00899 bool empty(void) const { return size() == 0; } 00900 bool valid(void) const { return pushed.empty(); } 00901 00902 /* push_back */ 00903 00904 void push_back(const parse_tree<T>& tree) 00905 { 00906 if (!empty()) 00907 pushed.push_back(_root); 00908 00909 _root = tree.back(); 00910 } 00911 00912 void push_back(const T& t) 00913 { 00914 if (!empty()) 00915 pushed.push_back(_root); 00916 00917 _root = t; 00918 00919 for (typename subtree::iterator it = _root.begin(); it != _root.end(); it++) 00920 { 00921 *it = pushed.back(); 00922 pushed.pop_back(); 00923 } 00924 00925 } 00926 00927 /* Access to subtrees */ 00928 00929 subtree& back(void) { return _root; } 00930 const subtree& back(void) const { return _root; } 00931 subtree& root(void) { return _root; } 00932 const subtree& root(void) const { return _root; } 00933 00934 subtree& front(void) { return _root[0]; } 00935 const subtree& front(void) const { return _root[0]; } 00936 00937 subtree& operator[](size_t i) 00938 { return const_cast<subtree&>(_root.get_node(i)); } 00939 const subtree& operator[](size_t i) const 00940 { return _root.get_node(i); } 00941 00942 subtree& get_cumulative(size_t i) 00943 { return const_cast<subtree&>(_root.get_cumulative(i)); } 00944 const subtree& get_cumulative(size_t i) const 00945 { return get_cumulative(i); } 00946 00947 private : 00948 00949 parse_tree& copy(const parse_tree& org) 00950 { 00951 _root = org._root; 00952 pushed = org.pushed; 00953 00954 return *this; 00955 } 00956 00957 parse_tree& copy(const subtree& sub) 00958 { _root = sub; pushed.resize(0); return *this; } 00959 00960 subtree _root; 00961 std::vector<subtree > pushed; 00962 }; // end class parse_tree 00963 00964 00965 } // end namespace gp_parse_tree 00966 00967 namespace std 00968 { // for use with stlport on MSVC 00969 00970 template <class T> inline 00971 std::forward_iterator_tag iterator_category(typename gp_parse_tree::parse_tree<T>::embedded_iterator) 00972 { 00973 return std::forward_iterator_tag(); 00974 } 00975 00976 template <class T> inline 00977 ptrdiff_t* distance_type(typename gp_parse_tree::parse_tree<T>::embedded_iterator) 00978 { 00979 return 0; 00980 } 00981 00982 template <class T> inline 00983 std::forward_iterator_tag iterator_category(typename gp_parse_tree::parse_tree<T>::iterator) 00984 { 00985 return std::forward_iterator_tag(); 00986 } 00987 00988 template <class T> inline 00989 ptrdiff_t* distance_type(typename gp_parse_tree::parse_tree<T>::iterator) 00990 { 00991 return 0; 00992 } 00993 00994 /* Put customized swaps also in std... 00995 00996 template<class T> inline 00997 void swap(gp_parse_tree::parse_tree<T>& a, gp_parse_tree::parse_tree<T>& b) 00998 { 00999 a.swap(b); 01000 } 01001 01002 template<class T> inline 01003 void iter_swap(std::vector<gp_parse_tree::parse_tree<T> >::iterator a, std::vector<gp_parse_tree::parse_tree<T> > b) 01004 { 01005 a->swap(*b); 01006 }*/ 01007 01008 01009 } // namespace std 01010 01011 01012 #endif