00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00031 #ifndef __VGTL_DAG_H_
00032 #define __VGTL_DAG_H_
00033
00034 #include <vector>
00035 #include <map>
00036 #include <list>
00037 #include <algorithm>
00038 #include <iterator>
00039 #include <string>
00040 #include <utility>
00041
00042 #include <vgtl_helpers.h>
00043 #include <vgtl_intadapt.h>
00044
00045 #include <vgtl_dagbase.h>
00046
00047 __VGTL_BEGIN_NAMESPACE
00048
00049
00050 template <class _Tp, class _Ref, class _Ptr, class _Ctr, class _Iterator,
00051 class _CIterator>
00052 class _DG_iterator;
00053
00055
00060 template <class _Tp, class _Ref, class _Ptr, class _Ctr, class _Iterator,
00061 class _CIterator>
00062 class _DG_walker
00063 {
00064 public:
00065 typedef _DG_walker<_Tp,_Tp&,_Tp*,_Ctr,_Iterator,_CIterator> walker;
00066 typedef _DG_walker<_Tp,const _Tp&,const _Tp*,_Ctr,_Iterator,_CIterator>
00067 const_walker;
00068
00069 private:
00070 typedef _DG_walker<_Tp,_Ref,_Ptr,_Ctr,_Iterator,_CIterator> _Self;
00071 typedef _DG_iterator<_Tp,_Ref,_Ptr,_Ctr,_Iterator,_CIterator> _Itr;
00072
00073 public:
00075
00076 typedef _Tp value_type;
00077 typedef _Ptr pointer;
00078 typedef _Ref reference;
00080
00081 private:
00082 typedef _DG_node<_Tp,_Ctr,_Iterator> _Node;
00083 typedef _Iterator _Ctr_iterator;
00084 typedef _CIterator _Ctr_const_iterator;
00085
00086 public:
00088
00089 typedef _Ctr_iterator children_iterator;
00090 typedef _Ctr_iterator parents_iterator;
00091 typedef _Ctr_const_iterator children_const_iterator;
00092 typedef _Ctr_const_iterator parents_const_iterator;
00093 typedef _Node node_type;
00094
00095 typedef size_t size_type;
00096 typedef ptrdiff_t difference_type;
00098
00099 public:
00101 _Node* _C_w_cur;
00102
00103 public:
00105 _DG_walker() {}
00106
00107 public:
00109 _DG_walker(_Node* __x) : _C_w_cur(__x) { }
00110
00112 _DG_walker(const walker& __x) : _C_w_cur(__x._C_w_cur) {}
00113
00115 reference operator*() const { return (*_C_w_cur)._C_data; }
00116
00117 #ifndef __SGI_STL_NO_ARROW_OPERATOR
00118
00119 pointer operator->() const { return &(operator*()); }
00120 #endif
00121
00122 public:
00124 const _Node* node() { return _C_w_cur; }
00125
00127 size_type n_children() const { return (*_C_w_cur)._C_children.size(); }
00129 size_type n_parents() const { return (*_C_w_cur)._C_parents.size(); }
00130
00132 bool is_root() const
00133 { if(n_parents() != 1)
00134 return false;
00135 else
00136 {
00137 _Node* __help = (_Node*)*((*_C_w_cur)._C_parents.begin());
00138 return (*__help)._C_parents.empty();
00139 }
00140 }
00142 bool is_leaf() const
00143 { if(n_children() != 1)
00144 return false;
00145 else
00146 {
00147 _Node* __help = (_Node*)*((*_C_w_cur)._C_children.begin());
00148 return (*__help)._C_children.empty();
00149 }
00150 }
00151
00153 bool is_ground() const { return (*_C_w_cur)._C_parents.empty(); }
00155 bool is_sky() const { return _C_w_cur ? (*_C_w_cur)._C_children.empty() : true; }
00156
00158 children_iterator child_begin() { return (*_C_w_cur)._C_children.begin(); }
00159 children_const_iterator child_begin() const
00160 { return (*_C_w_cur)._C_children.begin(); }
00162 children_iterator child_end() { return (*_C_w_cur)._C_children.end(); }
00163 children_const_iterator child_end() const
00164 { return (*_C_w_cur)._C_children.end(); }
00165
00167 parents_iterator parent_begin() { return (*_C_w_cur)._C_parents.begin(); }
00168 parents_const_iterator parent_begin() const
00169 { return (*_C_w_cur)._C_parents.begin(); }
00171 parents_iterator parent_end() { return (*_C_w_cur)._C_parents.end(); }
00172 parents_const_iterator parent_end() const
00173 { return (*_C_w_cur)._C_parents.end(); }
00174
00176 template <class _Function>
00177 _Function for_each_child(_Function __f)
00178 {
00179 return for_each(child_begin(), child_end(), __f);
00180 }
00182 template <class _Function>
00183 _Function for_each_parent(_Function __f)
00184 {
00185 return for_each(parent_begin(), parent_end(), __f);
00186 }
00187
00188 public:
00190
00191 bool operator==(const _Self& __x) const
00192 { return _C_w_cur == __x._C_w_cur; }
00193 bool operator!=(const _Self& __x) const
00194 { return _C_w_cur != __x._C_w_cur; }
00196
00198 _Self operator<<(parents_iterator __i) {
00199 _Self __tmp = *this;
00200 __tmp._C_w_cur = (_Node*) *__i;
00201 return __tmp;
00202 }
00203
00205 _Self operator>>(children_iterator __i) {
00206 _Self __tmp = *this;
00207 __tmp._C_w_cur = (_Node*) *__i;
00208 return __tmp;
00209 }
00210
00212 _Self& operator<<=(parents_iterator __i) {
00213 _C_w_cur = (_Node*) *__i;
00214 return *this;
00215 }
00216
00218 _Self& operator>>=(children_iterator __i) {
00219 _C_w_cur = (_Node*) *__i;
00220 return *this;
00221 }
00222
00224 _Self operator<<(parents_const_iterator __i) {
00225 _Self __tmp = *this;
00226 __tmp._C_w_cur = (_Node*) *__i;
00227 return __tmp;
00228 }
00229
00231 _Self operator>>(children_const_iterator __i) {
00232 _Self __tmp = *this;
00233 __tmp._C_w_cur = (_Node*) *__i;
00234 return __tmp;
00235 }
00236
00238 _Self& operator<<=(parents_const_iterator __i) {
00239 _C_w_cur = (_Node*) *__i;
00240 return *this;
00241 }
00242
00244 _Self& operator>>=(children_const_iterator __i) {
00245 _C_w_cur = (_Node*) *__i;
00246 return *this;
00247 }
00248
00250 _Self& operator=(const _Itr& __x) {
00251 _C_w_cur = __x._C_i_cur;
00252 return *this;
00253 }
00254
00256 _Self& operator=(const _Self& __x) {
00257 _C_w_cur = __x._C_w_cur;
00258 return *this;
00259 }
00260
00262 _Self& operator=(const _Node& __n) {
00263 _C_w_cur = &__n;
00264 return *this;
00265 }
00266 };
00267
00269
00275 template <class _Tp, class _Ref, class _Ptr, class _Ctr, class _Iterator,
00276 class _CIterator>
00277 class _DG_iterator
00278 {
00279 public:
00280 typedef _DG_iterator<_Tp,_Tp&,_Tp*,_Ctr,_Iterator,_CIterator> iterator;
00281 typedef _DG_iterator<_Tp,const _Tp&,const _Tp*,_Ctr,_Iterator,_CIterator>
00282 const_iterator;
00283 typedef _DG_iterator<_Tp,_Ref,_Ptr,_Ctr,_Iterator,_CIterator> _Self;
00284 typedef _DG_walker<_Tp,_Ref,_Ptr,_Ctr,_Iterator,_CIterator> _Walk;
00285
00287
00288 typedef std::bidirectional_iterator_tag iterator_category;
00289 typedef _Tp value_type;
00290 typedef _Ptr pointer;
00291 typedef _Ref reference;
00292 typedef _DG_node<_Tp,_Ctr,_Iterator> _Node;
00293 typedef size_t size_type;
00294 typedef ptrdiff_t difference_type;
00296 typedef _Iterator _Ctr_iterator;
00297 typedef _CIterator _Ctr_const_iterator;
00298
00299 protected:
00301 _Node* _C_i_cur;
00303 std::vector<_Ctr_iterator> _C_i_cur_it;
00304
00305 public:
00307 _DG_iterator() : _C_i_cur_it() {_C_i_cur_it.reserve(32);}
00309 _DG_iterator(const iterator& __x) : _C_i_cur(__x._C_i_cur),
00310 _C_i_cur_it(__x._C_i_cur_it) {}
00311
00313
00314 bool operator==(const _Self& __x) const
00315 { return (_C_i_cur->_C_parents.empty() &&
00316 __x._C_i_cur->_C_parents.empty()) ||
00317 (_C_i_cur->_C_children.empty() &&
00318 __x._C_i_cur->_C_children.empty()) ||
00319 ( _C_i_cur == __x._C_i_cur &&
00320 _C_i_cur_it == __x._C_i_cur_it);
00321 }
00322 bool operator!=(const _Self& __x) const
00323 { return (!_C_i_cur->_C_parents.empty() ||
00324 !__x._C_i_cur->_C_parents.empty()) &&
00325 (!_C_i_cur->_C_children.empty() ||
00326 !__x._C_i_cur->_C_children.empty()) &&
00327 ( _C_i_cur != __x._C_i_cur ||
00328 _C_i_cur_it != __x._C_i_cur_it);
00329 }
00331
00332 reference operator*() const { return (*_C_i_cur)._C_data; }
00333
00334 #ifndef __SGI_STL_NO_ARROW_OPERATOR
00335
00336 pointer operator->() const { return &(operator*()); }
00337 #endif
00338
00339 private:
00341 void find_start_node();
00343 void find_next_node();
00345 void find_prev_node();
00346
00347 public:
00349 _Self& operator=(const _Walk& __x) {
00350 _C_i_cur = __x._C_w_cur;
00351 _C_i_cur_it.erase(_C_i_cur_it.begin(), _C_i_cur_it.end());
00352
00353
00354 find_start_node();
00355 return *this;
00356 }
00357
00359
00360 _Self& operator++() {
00361 find_next_node();
00362 return *this;
00363 }
00364 _Self operator++(int) {
00365 _Self __tmp = *this;
00366 ++*this;
00367 return __tmp;
00368 }
00369
00370 _Self& operator--() {
00371 find_prev_node();
00372 return *this;
00373 }
00374 _Self operator--(int) {
00375 _Self __tmp = *this;
00376 --*this;
00377 return __tmp;
00378 }
00380 };
00381
00382 #ifndef __VGTL_CLASS_PARTIAL_SPECIALIZATION // Specifies the iterator to be bi-directional.
00383 template <class _Tp, class _Ref, class _Ptr, class _Ctr, class _Iterator,
00384 class _CIterator>
00385 inline bidirectional_iterator_tag
00386 iterator_category(const _DG_iterator<_Tp,_Ref,_Ptr,_Ctr,_Iterator,_CIterator>&)
00387 {
00388 return bidirectional_iterator_tag();
00389 }
00390
00391 template <class _Tp, class _Ref, class _Ptr, class _Ct, class _Iterator,
00392 class _CIterator>
00393 inline _Tp*
00394 value_type(const _DG_iterator<_Tp,_Ref,_Ptr,_Ctr,_Iterator,_CIterator>&)
00395 {
00396 return 0;
00397 }
00398
00399
00400
00401
00402
00403 template <class _Tp, class _Ref, class _Ptr, class _Ctr, class _Iterator,
00404 class _CIterator>
00405 inline ptrdiff_t*
00406 distance_type(const _DG_iterator<_Tp,_Ref,_Ptr,_Ctr,_Iterator,_CIterator>&)
00407 {
00408 return 0;
00409 }
00410
00411 #endif
00412
00413
00414
00415
00416
00417 template <class _Tp, class _Ref, class _Ptr, class _Ctr, class _Iterator,
00418 class _CIterator>
00419 void
00420 _DG_iterator<_Tp,_Ref,_Ptr,_Ctr,_Iterator,_CIterator>::find_start_node()
00421 {
00422 _Node* __s = _C_i_cur;
00423 _Ctr_iterator __help;
00424
00425 while(!__s->_C_parents.empty())
00426 {
00427 __help = ((_Node*)*__s->_C_parents.begin());
00428 _C_i_cur_it.insert(_C_i_cur_it.begin(),
00429 __help->get_entry_iterator((void*)__s));
00430 __s = __help;
00431 }
00432 while(!_C_i_cur->_C_children.empty())
00433 {
00434
00435 for(__help = _C_i_cur->_C_children.begin();
00436 __help != _C_i_cur->_C_children.end(); ++__help)
00437 {
00438 __s = (_Node*)*__help;
00439 if(*(__s->_C_parents.begin()) == (void*)_C_i_cur)
00440 break;
00441 }
00442 if(__help == _C_i_cur->_C_children.end())
00443 break;
00444 _C_i_cur = __s;
00445 _C_i_cur_it.push_back(__help);
00446 }
00447 if(_C_i_cur->_C_children.empty())
00448 {
00449 __help = _C_i_cur_it.back();
00450 _C_i_cur_it.pop_back();
00451 _C_i_cur = (_Node*)*__help;
00452 }
00453 }
00454
00455
00456
00457
00458
00459 template <class _Tp, class _Ref, class _Ptr, class _Ctr, class _Iterator,
00460 class _CIterator>
00461 void
00462 _DG_iterator<_Tp,_Ref,_Ptr,_Ctr,_Iterator,_CIterator>::find_next_node()
00463 {
00464 if(!_C_i_cur->_C_parents.empty())
00465 {
00466 _Ctr_iterator __help(_C_i_cur_it.back());
00467 _Node* __par;
00468
00469 _C_i_cur_it.pop_back();
00470 __par = (_Node*)*(_C_i_cur->_C_parents.begin());
00471
00472 for(++__help; __help != __par->_C_children.end(); ++__help)
00473 {
00474 _Node* __s = (_Node*)*__help;
00475 if(*(__s->_C_parents.begin()) == (void*)_C_i_cur)
00476 {
00477 _C_i_cur_it.push_back(__help);
00478 _C_i_cur = __s;
00479 while(!_C_i_cur->_C_children.empty());
00480 {
00481 for(__help = _C_i_cur->_C_children.begin();
00482 __help != _C_i_cur->_C_children.end(); ++__help)
00483 {
00484 __s = (_Node*)*__help;
00485 if(*(__s->_C_parents.begin()) == (void*)_C_i_cur)
00486 break;
00487 }
00488 if(__help == _C_i_cur->_C_children.end())
00489 break;
00490 _C_i_cur = __s;
00491 _C_i_cur_it.push_back(__help);
00492 }
00493 break;
00494 }
00495 }
00496 if(__help == __par->_C_children.end())
00497 {
00498 _C_i_cur = __par;
00499 }
00500 else if(_C_i_cur->_C_children.empty())
00501 {
00502 __help = _C_i_cur_it.back();
00503 _C_i_cur_it.pop_back();
00504 _C_i_cur = (_Node*)*__help;
00505 }
00506 }
00507 }
00508
00509
00510
00511
00512 template <class _Tp, class _Ref, class _Ptr, class _Ctr, class _Iterator,
00513 class _CIterator>
00514 void
00515 _DG_iterator<_Tp,_Ref,_Ptr,_Ctr,_Iterator,_CIterator>::find_prev_node()
00516 {
00517 #if 0
00519 _Ctr_iterator help;
00520
00521 if(_C_i_cur->_C_children.empty())
00522 {
00523 while(1)
00524 {
00525 if(_C_i_cur->_C_parent == NULL)
00526 break;
00527 help = _C_i_cur_it.back();
00528 _C_i_cur_it.pop_back();
00529 _C_i_cur = (_Node*)_C_i_cur->_C_parent;
00530 if(help != _C_i_cur->_C_children.begin())
00531 {
00532 --help;
00533 _C_i_cur_it.push_back(help);
00534 _C_i_cur = (_Node*)*help;
00535 break;
00536 }
00537 }
00538 }
00539 else
00540 {
00541 help = _C_i_cur->_C_children.end();
00542 --help;
00543 _C_i_cur_it.push_back(help);
00544 _C_i_cur = (_Node*)*help;
00545 }
00546 #endif
00547 }
00548
00550
00555 template <class _Tp, class _Ctr, class _Iterator, class _CIterator,
00556 class _Inserter, class _Alloc>
00557 class __DG : public _DG_base<_Tp, _Ctr, _Iterator, _CIterator, _Alloc>
00558 {
00559 public:
00560 typedef _Ctr container_type;
00561 typedef _Iterator children_iterator;
00562 typedef _Iterator parents_iterator;
00563 typedef _CIterator children_const_iterator;
00564 typedef _CIterator parents_const_iterator;
00565 typedef _Inserter container_insert_arg;
00566
00567 protected:
00568 typedef void* _Void_pointer;
00569 typedef _DG_base<_Tp, container_type, children_iterator,
00570 children_const_iterator, _Alloc> _Base;
00571 typedef _DG_node<_Tp, container_type, children_iterator> _Node;
00572 typedef __DG<_Tp,_Ctr,_Iterator,_CIterator,_Inserter,_Alloc> _Self;
00573 typedef std::pair<_Node*,_Node*> _RV_DG;
00574 typedef _Iterator container_iterator;
00575 typedef _CIterator container_const_iterator;
00576
00577 public:
00579
00580 typedef _Tp value_type;
00581 typedef _Node node_type;
00582 typedef value_type* pointer;
00583 typedef const value_type* const_pointer;
00584 typedef value_type& reference;
00585 typedef const value_type& const_reference;
00586 typedef size_t size_type;
00587 typedef ptrdiff_t difference_type;
00589
00590 typedef typename _Base::allocator_type allocator_type;
00592 allocator_type get_allocator() const { return _Base::get_allocator(); }
00593
00594 public:
00596 typedef _DG_iterator<_Tp,_Tp&,_Tp*,container_type,children_iterator,
00597 children_const_iterator> iterator;
00599 typedef _DG_iterator<_Tp,const _Tp&,const _Tp*,container_type,
00600 children_iterator,children_const_iterator> const_iterator;
00601
00602 #ifdef __VGTL_CLASS_PARTIAL_SPECIALIZATION
00603
00604 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00606 typedef std::reverse_iterator<iterator> reverse_iterator;
00607 #else
00608
00609 typedef std::reverse_bidirectional_iterator<const_iterator,value_type,
00610 const_reference,difference_type>
00611 const_reverse_iterator;
00613 typedef std::reverse_bidirectional_iterator<iterator,value_type,reference,
00614 difference_type>
00615 reverse_iterator;
00616 #endif
00617
00619 typedef _DG_walker<_Tp,_Tp&,_Tp*,container_type,children_iterator,
00620 children_const_iterator> walker;
00622 typedef _DG_walker<_Tp,const _Tp&,const _Tp*,container_type,children_iterator,
00623 children_const_iterator> const_walker;
00624
00626 typedef std::pair<walker,walker> edge;
00628 typedef std::pair<edge,bool> enhanced_edge;
00629
00630 protected:
00632 typedef std::pair<_RV_DG, std::vector<enhanced_edge> > erased_part;
00633
00634 protected:
00635 #ifdef __VGTL_HAS_NAMESPACES
00636 using _Base::_C_ground;
00637 using _Base::_C_sky;
00638 using _Base::_C_mark;
00639 using _Base::_C_put_node;
00640 using _Base::_C_get_node;
00641 #endif
00642
00643 protected:
00645 _Node* _C_create_node(const _Tp& __x)
00646 {
00647 _Node* __p = _C_get_node();
00648 __p->_C_visited = 0;
00649 __VGTL_TRY {
00650 _VGTL_Construct_2(&__p->_C_data, __x);
00651 _VGTL_Construct_1(&__p->_C_children);
00652 _VGTL_Construct_1(&__p->_C_parents);
00653 }
00654 __VGTL_UNWIND(_C_put_node(__p));
00655 return __p;
00656 }
00657
00659 _Node* _C_create_node()
00660 {
00661 _Node* __p = _C_get_node();
00662 __p->_C_visited = 0;
00663 __VGTL_TRY {
00664 _VGTL_Construct_1(&__p->_C_data);
00665 _VGTL_Construct_1(&__p->_C_children);
00666 _VGTL_Construct_1(&__p->_C_parents);
00667 }
00668 __VGTL_UNWIND(_C_put_node(__p));
00669 return __p;
00670 }
00671
00673 void _C_destroy_node(_Node* __p)
00674 {
00675 __p->_C_visited = 0;
00676 _VGTL_Destroy(&__p->_C_data);
00677 _VGTL_Destroy(&__p->_C_children);
00678 _VGTL_Destroy(&__p->_C_parents);
00679 _C_put_node(__p);
00680 }
00681
00682 public:
00684 explicit __DG(const allocator_type& __a = allocator_type()) : _Base(__a) {}
00685
00687 walker ground()
00688 { walker __help(this->_C_ground);
00689 return __help; }
00690
00692 walker sky()
00693 { walker __help(this->_C_sky);
00694 return __help; }
00695
00697 const_walker ground() const
00698 { const_walker __help(this->_C_ground);
00699 return __help; }
00700
00702 const_walker sky() const
00703 { const_walker __help(this->_C_sky);
00704 return __help; }
00705
00707 children_iterator root_begin()
00708 { return this->_C_ground->_C_children.begin(); }
00710 children_iterator root_end()
00711 { return this->_C_ground->_C_children.end(); }
00712
00714 children_const_iterator root_begin() const
00715 { return this->_C_ground->_C_children.begin(); }
00717 children_const_iterator root_end() const
00718 { return this->_C_ground->_C_children.end(); }
00719
00721 parents_iterator leaf_begin()
00722 { return this->_C_sky->_C_parents.begin(); }
00724 parents_iterator leaf_end()
00725 { return this->_C_sky->_C_parents.end(); }
00726
00728 parents_const_iterator leaf_begin() const
00729 { return this->_C_sky->_C_parents.begin(); }
00731 parents_const_iterator leaf_end() const
00732 { return this->_C_sky->_C_parents.end(); }
00733
00734 iterator begin()
00735 {
00736 iterator __help(this->_C_ground);
00737 return __help;
00738 }
00739 const_iterator begin() const
00740 {
00741 const_iterator __help(this->_C_ground);
00742 return __help;
00743 }
00744
00745 iterator end()
00746 {
00747 iterator __help(this->_C_sky);
00748 return --__help;
00749 }
00750 const_iterator end() const
00751 {
00752 const_iterator __help(this->_C_sky);
00753 return --__help;
00754 }
00755
00756 reverse_iterator rbegin()
00757 { return reverse_iterator(end()); }
00758 reverse_iterator rend()
00759 { return reverse_iterator(begin()); }
00760
00761 const_reverse_iterator rbegin() const
00762 { return const_reverse_iterator(end()); }
00763 const_reverse_iterator rend() const
00764 { return const_reverse_iterator(begin()); }
00765
00767 bool empty() const
00768 { return *((*this->_C_ground)._C_children.begin()) == (void*)this->_C_sky; }
00769
00771 size_type size() const {
00772 size_type __result = 0;
00773 distance(begin(), end(), __result);
00774 return __result;
00775 }
00776
00778 size_type max_size() const { return size_type(-1); }
00779
00781 void swap(_Self& __x)
00782 { __STD::swap(this->_C_ground, __x._C_ground);
00783 __STD::swap(this->_C_sky, __x._C_sky);
00784 __STD::swap(_C_mark, __x._C_mark); }
00785
00791 walker insert_node_in_graph(_Node* __n, const walker& __parent,
00792 const walker& __child,
00793 const container_insert_arg& __Itc,
00794 const container_insert_arg& __Itp)
00795 { __parent._C_w_cur->_C_children.insert(__Itc, (void*)__n);
00796 __child._C_w_cur->_C_parents.insert(__Itp, (void*)__n);
00797 __n->_C_children.push_back((void*)__child._C_w_cur);
00798 __n->_C_parents.push_back((void*)__parent._C_w_cur);
00799 return walker(__n);
00800 }
00801
00807 walker insert_in_graph(const _Tp& __x, const walker& __parent,
00808 const walker& __child,
00809 const container_insert_arg& __Itc,
00810 const container_insert_arg& __Itp)
00811 {
00812 _Node* __tmp = _C_create_node(__x);
00813 return insert_node_in_graph(__tmp, __parent, __child, __Itc, __Itp);
00814 }
00815
00821 walker insert_in_graph(const walker& __parent,
00822 const walker& __child,
00823 const container_insert_arg& __Itc,
00824 const container_insert_arg& __Itp)
00825 { return insert_in_graph(_Tp(), __parent, __child, __Itc, __Itp); }
00826
00832 void insert_subgraph(_Self& __subgraph,
00833 const walker& __parent,
00834 const walker& __child,
00835 const container_insert_arg& __Itc,
00836 const container_insert_arg& __Itp)
00837 {
00838 __subgraph.add_all_children(inserter(__parent._C_w_cur->_C_children,
00839 __Itc), __parent._C_w_cur);
00840 __subgraph.add_all_parents(inserter(__child._C_w_cur->_C_parents,
00841 __Itp), __child._C_w_cur);
00842 __subgraph.clear_children();
00843 __subgraph.clear_parents();
00844 }
00845
00846 #ifdef __VGTL_MEMBER_TEMPLATES
00847
00851 template <template <class __Tp, class __AllocTp> class __SequenceCtr1,
00852 template <class __Tp, class __AllocTp> class __SequenceCtr2,
00853 class _Allocator1, class _Allocator2>
00854 walker insert_node_in_graph(_Node* __node,
00855 const __SequenceCtr1<walker,_Allocator1>& __parents,
00856 const __SequenceCtr2<walker,_Allocator2>& __children)
00857 {
00858 typedef typename __SequenceCtr1<walker,_Allocator1>::const_iterator
00859 _Sequ_itp;
00860 typedef typename __SequenceCtr2<walker,_Allocator2>::const_iterator
00861 _Sequ_itc;
00862
00863 for(_Sequ_itp __b = __parents.begin(); __b != __parents.end(); ++__b)
00864 {
00865 __node->_C_parents.insert(__node->_C_parents.end(), (void*)(*__b).node());
00866 (*__b)._C_w_cur->_C_children.insert((*__b)._C_w_cur->_C_children.end(),
00867 (void*)__node);
00868 }
00869 for(_Sequ_itc __b = __children.begin(); __b != __children.end(); ++__b)
00870 {
00871 __node->_C_children.insert(__node->_C_children.end(), (void*)(*__b).node());
00872 (*__b)._C_w_cur->_C_parents.insert((*__b)._C_w_cur->_C_parents.end(),
00873 (void*)__node);
00874 }
00875 return walker(__node);
00876 }
00877
00882 template <template <class __Tp, class __AllocTp> class __SequenceCtr1,
00883 template <class __Tp, class __AllocTp> class __SequenceCtr2,
00884 class _Allocator1, class _Allocator2>
00885 walker insert_in_graph(const _Tp& __x,
00886 const __SequenceCtr1<walker,_Allocator1>& __parents,
00887 const __SequenceCtr2<walker,_Allocator2>& __children)
00888 {
00889 _Node* __tmp = _C_create_node(__x);
00890 return insert_node_in_graph(__tmp, __parents, __children);
00891 }
00892
00897 template <template <class __Tp, class __AllocTp> class __SequenceCtr1,
00898 template <class __Tp, class __AllocTp> class __SequenceCtr2,
00899 class _Allocator1, class _Allocator2>
00900 walker insert_in_graph(const __SequenceCtr1<walker,_Allocator1>& __parents,
00901 const __SequenceCtr2<walker,_Allocator2>& __children)
00902 {
00903 _Node* __tmp = _C_create_node();
00904 return insert_node_in_graph(__tmp, __parents, __children);
00905 }
00906
00911 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
00912 class _Allocator>
00913 walker insert_node_in_graph(_Node* __node, const walker& __parent,
00914 const container_insert_arg& __pref,
00915 const __SequenceCtr<walker,_Allocator>& __children)
00916 {
00917 typedef typename __SequenceCtr<walker,_Allocator>::const_iterator _Sequ_it;
00918 _Sequ_it __b;
00919
00920 __node->_C_parents.insert(__node->_C_parents.end(), (void*)__parent._C_w_cur);
00921 __parent._C_w_cur->_C_children.insert(__pref, (void*)__node);
00922 for(__b = __children.begin(); __b != __children.end(); ++__b)
00923 {
00924 __node->_C_children.insert(__node->_C_children.end(),
00925 (void*)(*__b)._C_w_cur);
00926 (*__b)._C_w_cur->_C_parents.insert((*__b)._C_w_cur->_C_parents.end(),
00927 (void*)__node);
00928 }
00929 return walker(__node);
00930 }
00931
00936 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
00937 class _Allocator>
00938 walker insert_in_graph(const _Tp& __x, const walker& __parent,
00939 const container_insert_arg& __pref,
00940 const __SequenceCtr<walker,_Allocator>& __children)
00941 {
00942 _Node* __tmp = _C_create_node(__x);
00943 return insert_node_in_graph(__tmp, __parent, __pref, __children);
00944 }
00945
00950 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
00951 class _Allocator>
00952 walker insert_in_graph(const walker& __parent,
00953 const container_insert_arg& __pref,
00954 const __SequenceCtr<walker,_Allocator>& __children)
00955 {
00956 _Node* __tmp = _C_create_node();
00957 return insert_node_in_graph(__tmp, __parent, __pref, __children);
00958 }
00959
00964 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
00965 class _Allocator>
00966 walker insert_node_in_graph(_Node* __node,
00967 const __SequenceCtr<walker,_Allocator>& __parents,
00968 const walker& __child,
00969 const container_insert_arg& __cref)
00970 {
00971 typedef typename __SequenceCtr<walker,_Allocator>::const_iterator _Sequ_it;
00972 _Sequ_it __b;
00973
00974 __node->_C_children.insert(__node->_C_children.end(), (void*)__child.node());
00975 __child._C_w_cur->_C_parents.insert(__cref, (void*)__node);
00976 for(__b = __parents.begin(); __b != __parents.end(); ++__b)
00977 {
00978 __node->_C_parents.insert(__node->_C_parents.end(), (void*)(*__b).node());
00979 (*__b)._C_w_cur->_C_children.insert((*__b)._C_w_cur->_C_children.end(),
00980 (void*)__node);
00981 }
00982 return walker(__node);
00983 }
00984
00989 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
00990 class _Allocator>
00991 walker insert_in_graph(const _Tp& __x,
00992 const __SequenceCtr<walker,_Allocator>& __parents,
00993 const walker& __child,
00994 const container_insert_arg& __cref)
00995 {
00996 _Node* __tmp = _C_create_node(__x);
00997 return insert_node_in_graph(__tmp, __parents, __child, __cref);
00998 }
00999
01004 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
01005 class _Allocator>
01006 walker insert_in_graph(const __SequenceCtr<walker,_Allocator>& __parents,
01007 const walker& __child,
01008 const container_insert_arg& __cref)
01009 {
01010 _Node* __tmp = _C_create_node();
01011 return insert_node_in_graph(__tmp, __parents, __child, __cref);
01012 }
01013
01017 template <template <class __Tp, class __AllocTp> class __SequenceCtr1,
01018 template <class __Tp, class __AllocTp> class __SequenceCtr2,
01019 class _Allocator1, class _Allocator2>
01020 void insert_subgraph(_Self& __subgraph,
01021 const __SequenceCtr1<walker,_Allocator1>& __parents,
01022 const __SequenceCtr2<walker,_Allocator2>& __children)
01023 {
01024 typedef typename __SequenceCtr1<walker,_Allocator1>::const_iterator
01025 _Sequ_itp;
01026 typedef typename __SequenceCtr2<walker,_Allocator2>::const_iterator
01027 _Sequ_itc;
01028 _Sequ_itp __sitp;
01029 _Sequ_itc __sitc;
01030 children_iterator __b;
01031 walker __wb;
01032 _Node* __n;
01033
01034 __sitp = __parents.begin();
01035 for(__b = __subgraph._C_ground->_C_children.begin();
01036 __b != __subgraph._C_ground->_C_children.end();
01037 ++__b)
01038 {
01039 if(__sitp == __parents.end())
01040 __wb = (*this)._C_ground;
01041 else
01042 __wb = *__sitp++;
01043 __n = __wb.node();
01044 __n->_C_children.insert(__n->_C_children.end(), *__b);
01045 ((_Node*)*__b)->_C_parents.insert(((_Node*)*__b)->_C_parents.end(),
01046 (void*)__n);
01047 }
01048 __sitc = __children.begin();
01049 for(__b = __subgraph._C_sky->_C_parents.begin();
01050 __b != __subgraph._C_sky->_C_parents.end();
01051 ++__b)
01052 {
01053 if(__sitc == __children.end())
01054 __wb = (*this)._C_sky;
01055 else
01056 __wb = *__sitc++;
01057 __n = __wb.node();
01058 __n->_C_parents.insert(__n->_C_parents.end(), *__b);
01059 ((_Node*)*__b)->_C_children.insert(((_Node*)*__b)->_C_children.end(),
01060 (void*)__n);
01061 }
01062 __subgraph.clear_children();
01063 __subgraph.clear_parents();
01064 }
01065 #endif
01066
01070 void add_edge(const edge& __edge,
01071 const container_insert_arg& __Itc,
01072 const container_insert_arg& __Itp)
01073 { add_edge(__edge.first, __edge.second, __Itc, __Itp); }
01074
01079 void add_edge(const walker& __parent, const walker& __child,
01080 const container_insert_arg& __Itc,
01081 const container_insert_arg& __Itp)
01082 {
01083 int do_remove(0);
01084 if(__parent._C_w_cur->_C_children.size() == 1)
01085 {
01086 container_iterator __it;
01087 __it = __parent._C_w_cur->_C_children.begin();
01088 if(*__it == (void*)this->_C_sky)
01089 do_remove += 1;
01090 }
01091 if(__child._C_w_cur->_C_parents.size() == 1)
01092 {
01093 container_iterator __it;
01094 __it = __child._C_w_cur->_C_parents.begin();
01095 if(*__it == (void*)this->_C_ground)
01096 do_remove += 2;
01097 }
01098 __parent._C_w_cur->_C_children.insert(__Itc, (void*)__child._C_w_cur);
01099 __child._C_w_cur->_C_parents.insert(__Itp, (void*)__parent._C_w_cur);
01100 if(do_remove & 1)
01101 {
01102 container_iterator __it;
01103 __it = __parent._C_w_cur->get_childentry_iterator((void*)this->_C_sky);
01104 __parent._C_w_cur->_C_children.erase(__it);
01105 __it = this->_C_sky->get_parententry_iterator((void*)__parent._C_w_cur);
01106 this->_C_sky->_C_parents.erase(__it);
01107 }
01108 if(do_remove & 2 &&
01109 (__parent._C_w_cur != (void*)this->_C_ground ||
01110 __child._C_w_cur != (void*)this->_C_sky))
01111
01112 {
01113 container_iterator __it;
01114 __it = __child._C_w_cur->get_parententry_iterator((void*)this->_C_ground);
01115 __child._C_w_cur->_C_parents.erase(__it);
01116 __it = this->_C_ground->get_childentry_iterator((void*)__child._C_w_cur);
01117 this->_C_ground->_C_children.erase(__it);
01118 }
01119 }
01120
01125 void replace_edge_to_child(const walker& __parent,
01126 const walker& __child_old,
01127 const walker& __child_new)
01128 { container_iterator __it;
01129 __it = __parent._C_w_cur->get_childentry_iterator((void*) __child_old._C_w_cur);
01130 if(__it == __parent._C_w_cur->_C_children.end())
01131 return;
01132 (*__it) = (void*) __child_new._C_w_cur;
01133 __it = __child_old._C_w_cur->get_parententry_iterator((void*) __parent._C_w_cur);
01134 if(__it == __child_old._C_w_cur->_C_parents.end())
01135 return;
01136 __child_old._C_w_cur->_C_parents.erase(__it);
01137 if(__child_old._C_w_cur->_C_parents.empty())
01138 {
01139 __child_old._C_w_cur->_C_parents.insert(
01140 __child_old._C_w_cur->_C_parents.end(), (void*)this->_C_ground);
01141 this->_C_ground->_C_children.insert(this->_C_ground->_C_children.end(),
01142 (void*)__child_old._C_w_cur);
01143 }
01144 if(__child_new._C_w_cur->_C_parents.size() == 1)
01145 {
01146 if(*__child_new._C_w_cur->_C_parents.begin() == (void*)this->_C_ground)
01147 {
01148 __it = this->_C_ground->get_childentry_iterator((void*) __child_new._C_w_cur);
01149 if(__it != this->_C_ground->_C_children.end())
01150 this->_C_ground->_C_children.erase(__it);
01151 __child_new._C_w_cur->_C_parents.erase(__child_new._C_w_cur->
01152 _C_parents.begin());
01153 }
01154 }
01155 __child_new._C_w_cur->_C_parents.insert(
01156 __child_new._C_w_cur->_C_parents.end(), (void*)__parent._C_w_cur);
01157 }
01158
01163 void replace_edge_to_parent(const walker& __parent_old,
01164 const walker& __parent_new, const walker& __child)
01165 { container_iterator __it;
01166 __it = __child._C_w_cur->get_parententry_iterator((void*) __parent_old._C_w_cur);
01167 if(__it == __child._C_w_cur->_C_parents.end())
01168 return;
01169 (*__it) = (void*) __parent_new._C_w_cur;
01170 __it = __parent_old._C_w_cur->get_childentry_iterator((void*) __child._C_w_cur);
01171 if(__it == __parent_old._C_w_cur->_C_children.end())
01172 return;
01173 __parent_old._C_w_cur->_C_children.erase(__it);
01174 if(__parent_old._C_w_cur->_C_children.empty())
01175 {
01176 __parent_old._C_w_cur->_C_children.insert(
01177 __parent_old._C_w_cur->_C_children.end(), (void*)this->_C_sky);
01178 this->_C_sky->_C_parents.insert(this->_C_sky->_C_parents.end(),
01179 (void*)__parent_old._C_w_cur);
01180 }
01181 if(__parent_new._C_w_cur->_C_children.size() == 1)
01182 {
01183 if(*__parent_new._C_w_cur->_C_children.begin() == (void*)this->_C_sky)
01184 {
01185 __it = this->_C_sky->get_parententry_iterator((void*) __parent_new._C_w_cur);
01186 if(__it != this->_C_sky->_C_parents.end())
01187 this->_C_sky->_C_parents.erase(__it);
01188 __parent_new._C_w_cur->_C_children.erase(__parent_new._C_w_cur->
01189 _C_children.begin());
01190 }
01191 }
01192 __parent_new._C_w_cur->_C_children.insert(
01193 __parent_new._C_w_cur->_C_children.end(), (void*)__child._C_w_cur);
01194 }
01195
01197 void remove_edge(const edge& __edge)
01198 { remove_edge(__edge.first, __edge.second); }
01199
01201 void remove_edge_and_deattach(const walker& __parent, const walker& __child)
01202 { container_iterator __it;
01203 __it = __parent._C_w_cur->get_childentry_iterator((void*) __child._C_w_cur);
01204 if(__it == __parent._C_w_cur->_C_children.end())
01205 return;
01206 __parent._C_w_cur->_C_children.erase(__it);
01207 __it = __child._C_w_cur->get_parententry_iterator((void*) __parent._C_w_cur);
01208 if(__it == __child._C_w_cur->_C_parents.end())
01209 return;
01210 __child._C_w_cur->_C_parents.erase(__it);
01211 }
01212
01214 void remove_edge(const walker& __parent, const walker& __child)
01215 {
01216 remove_edge_and_deattach(__parent, __child);
01217
01218
01219
01220 if(__parent._C_w_cur->_C_children.empty())
01221 {
01222 __parent._C_w_cur->_C_children.insert(
01223 __parent._C_w_cur->_C_children.end(), (void*)this->_C_sky);
01224 this->_C_sky->_C_parents.insert(this->_C_sky->_C_parents.end(),
01225 (void*)__parent._C_w_cur);
01226 }
01227 if(__child._C_w_cur->_C_parents.empty())
01228 {
01229 __child._C_w_cur->_C_parents.insert(
01230 __child._C_w_cur->_C_parents.end(), (void*)this->_C_ground);
01231 this->_C_ground->_C_children.insert(this->_C_ground->_C_children.end(),
01232 (void*)__child._C_w_cur);
01233 }
01234 }
01235
01237 template <class Compare>
01238 void sort_child_edges(walker __position, children_iterator first,
01239 children_iterator last, Compare comp)
01240 { (*__position._C_w_cur).sort_child_edges(first, last, comp); }
01241
01243 template <class Compare>
01244 void sort_parent_edges(walker __position, parents_iterator first,
01245 parents_iterator last, Compare comp)
01246 { (*__position._C_w_cur).sort_parent_edges(first, last, comp); }
01247
01249 template <class Compare>
01250 void sort_child_edges(walker __position, Compare comp)
01251 { (*__position._C_w_cur).sort_child_edges(__position.child_begin(),
01252 __position.child_end(), comp); }
01253
01255 template <class Compare>
01256 void sort_parent_edges(walker __position, Compare comp)
01257 { (*__position._C_w_cur).sort_parent_edges(__position.parent_begin(),
01258 __position.parent_end(), comp); }
01259
01261 walker insert_node(_Node* _node, const walker& __position,
01262 const container_insert_arg& __It)
01263 { if(__position.sky())
01264 return;
01265 __position._C_w_cur->add_all_children(
01266 inserter(_node->_C_children, __It), _node);
01267 __position._C_w_cur->clear_children();
01268 __position._C_w_cur->_C_children.insert(
01269 __position._C_w_cur->_C_children.end(), _node);
01270 _node->_C_parents.insert(_node->_C_parents.end(),__position._C_w_cur);
01271 return walker(_node);
01272 }
01273
01275 walker insert_node(const _Tp& __x, const walker& __position,
01276 const container_insert_arg& __It)
01277 { return insert_node(_C_create_node(__x), __position, __It); }
01278
01279
01281 walker insert_node(const walker& __position,
01282 const container_insert_arg& __It)
01283 { return insert_node(_Tp(), __position, __It); }
01284
01286 walker insert_node_before(_Node* _node, const walker& __position,
01287 const container_insert_arg& __It)
01288 { if(__position.ground())
01289 return;
01290 __position._C_w_cur->add_all_parents(
01291 back_inserter(_node->_C_parents), _node);
01292 __position._C_w_cur->clear_parents();
01293 __position._C_w_cur->_C_parents.insert(
01294 __position._C_w_cur->_C_parents.end(), _node);
01295 _node->_C_children.push_back(__position.C_w_cur);
01296 return walker(_node);
01297 }
01298
01300 void insert_node_before(const _Tp& __x, const walker& __position,
01301 const container_insert_arg& __It)
01302 { return insert_node_before(_C_create_node(__x), __position, __It); }
01303
01305 void insert_node_before(const walker& __position,
01306 const container_insert_arg& __It)
01307 { return insert_node_before(_Tp(), __position, __It); }
01308
01309
01311 void merge(const walker& __position, const walker& __second,
01312 bool merge_parent_edges = true, bool merge_child_edges = true)
01313 { _Node* __tp = __position._C_w_cur;
01314 _Node* __ts = __second._C_w_cur;
01315 _Node* __p;
01316
01317 if(__position.is_sky() || __position.is_ground() ||
01318 __second.is_sky() || __second.is_ground() ||
01319 __position == __second)
01320
01321 return;
01322
01323 container_iterator __i, __j;
01324 bool mrg_it;
01325 bool __is_root = __position.is_root();
01326 bool __is_leaf = __position.is_leaf();
01327
01328 for(__i = __ts->_C_children.begin();
01329 __i != __ts->_C_children.end(); ++__i)
01330 {
01331 mrg_it = 0;
01332 __p = (_Node*)*__i;
01333 if(merge_child_edges)
01334 {
01335 for(__j = __tp->_C_children.begin();
01336 __j != __tp->_C_children.end(); ++__j)
01337 {
01338 if(*__i == *__j)
01339 {
01340 mrg_it = 1;
01341 break;
01342 }
01343 }
01344 }
01345 __j = __p->get_parententry_iterator(__ts);
01346 if(__p == this->_C_sky || mrg_it)
01347 __p->_C_parents.erase(__j);
01348 else
01349 *__j = (void *)__tp;
01350 if(!mrg_it && __p != this->_C_sky)
01351 __tp->_C_children.insert(__tp->_C_children.end(), (void*)__p);
01352 }
01353 if(__is_leaf && __tp->_C_children.size() > 1)
01354 {
01355 __j = this->_C_sky->get_parententry_iterator(__tp);
01356 this->_C_sky->_C_parents.erase(__j);
01357 __j = __tp->get_childentry_iterator(this->_C_sky);
01358 __tp->_C_children.erase(__j);
01359 }
01360 for(__i = __ts->_C_parents.begin();
01361 __i != __ts->_C_parents.end(); ++__i)
01362 {
01363 mrg_it = 0;
01364 __p = (_Node*)*__i;
01365 if(merge_parent_edges)
01366 {
01367 for(__j = __tp->_C_parents.begin();
01368 __j != __tp->_C_parents.end(); ++__j)
01369 {
01370 if(*__i == *__j)
01371 {
01372 mrg_it = 1;
01373 break;
01374 }
01375 }
01376 }
01377 __j = __p->get_childentry_iterator(__ts);
01378 if(__p == this->_C_ground || mrg_it)
01379 __p->_C_children.erase(__j);
01380 else
01381 *__j = (void *)__tp;
01382 if(!mrg_it && __p != this->_C_ground)
01383 __tp->_C_parents.insert(__tp->_C_parents.end(), (void*)__p);
01384 }
01385 if(__is_root && __tp->_C_parents.size() > 1)
01386 {
01387 __j = this->_C_ground->get_childentry_iterator(__tp);
01388 this->_C_ground->_C_children.erase(__j);
01389 __j = __tp->get_parententry_iterator(this->_C_ground);
01390 __tp->_C_parents.erase(__j);
01391 }
01392
01393 (__tp->_C_data).merge(__ts->_C_data);
01394 __ts->clear_children();
01395 __ts->clear_parents();
01396 _C_destroy_node(__ts);
01397 }
01398
01400 void erase(const walker& __position)
01401 { _Node* __tmp = __position._C_w_cur;
01402
01403 if(!__tmp->_C_children.empty() && !__tmp->_C_parents.empty())
01404 {
01405 container_iterator __ip, __ic;
01406 _Node* __p;
01407 bool do_it;
01408
01409 do_it = !__position.is_leaf();
01410 for(__ip = __tmp->_C_parents.begin();
01411 __ip != __tmp->_C_parents.end(); ++__ip)
01412 {
01413 __p = (_Node*)*__ip;
01414 __ic = __p->get_childentry_iterator(__tmp);
01415 ++__ic;
01416 if(__position.is_root())
01417 {
01418 std::list<void*> __clst;
01419 for(container_iterator __icc = __tmp->_C_children.begin();
01420 __icc != __tmp->_C_children.end(); ++__icc)
01421 {
01422 _Node* __c = (_Node*)*__icc;
01423 if(__c->_C_parents.size() == 1)
01424 {
01425 __c->_C_parents.insert(__c->_C_parents.end(), (void*)__p);
01426 __clst.push_back((void*)__c);
01427 }
01428 }
01429 __p->_C_children.insert(__ic, __clst.begin(), __clst.end());
01430 }
01431 else if(do_it || __p->_C_children.size() == 1)
01432 __tmp->add_all_children(inserter(__p->_C_children, __ic), __p);
01433
01434
01435
01436
01437 __ic = __p->get_childentry_iterator(__tmp);
01438 __p->_C_children.erase(__ic);
01439 if(__p->_C_children.empty())
01440 __p->_C_children.insert(__p->_C_children.end(),
01441 (void*) this->_C_sky);
01442 }
01443 for(__ic = __tmp->_C_children.begin();
01444 __ic != __tmp->_C_children.end(); ++__ic)
01445 {
01446 __p = (_Node*)*__ic;
01447 __ip = __p->get_parententry_iterator(__tmp);
01448 __p->_C_parents.erase(__ip);
01449 if(__p->_C_parents.empty())
01450 __p->_C_parents.insert(__p->_C_parents.end(),
01451 (void*) this->_C_ground);
01452 }
01453 __tmp->clear_parents();
01454 __tmp->clear_children();
01455 _C_destroy_node(__tmp);
01456 }
01457 }
01458
01461 void partial_erase_to_parent(const walker& __position, const walker& __parent, unsigned int idx)
01462 { _Node* __tmp = __position._C_w_cur;
01463 _Node* __p = __parent._C_w_cur;
01464
01465 if(!__tmp->_C_children.empty() && !__tmp->_C_parents.empty())
01466 {
01467 container_iterator __ic;
01468 bool do_it;
01469
01470 do_it = !__position.is_leaf();
01471 __ic = __p->_C_children.begin()+idx;
01472 if(*__ic != (void*)__tmp)
01473 return;
01474 ++__ic;
01475 if(__position.is_root())
01476 {
01477 std::list<void*> __clst;
01478 for(container_iterator __icc = __tmp->_C_children.begin();
01479 __icc != __tmp->_C_children.end(); ++__icc)
01480 {
01481 _Node* __c = (_Node*)*__icc;
01482 if(__c->_C_parents.size() == 1)
01483 {
01484 __c->_C_parents.insert(__c->_C_parents.end(), (void*)__p);
01485 __clst.push_back((void*)__c);
01486 }
01487 }
01488 __p->_C_children.insert(__ic, __clst.begin(), __clst.end());
01489 }
01490 else if(do_it || __p->_C_children.size() == 1)
01491 __tmp->add_all_children(inserter(__p->_C_children, __ic), __p);
01492
01493
01494
01495
01496 __ic = __p->_C_children.begin()+idx;
01497 __p->_C_children.erase(__ic);
01498 if(__p->_C_children.empty())
01499 __p->_C_children.insert(__p->_C_children.end(),
01500 (void*) this->_C_sky);
01501
01502 parents_iterator __ip;
01503 __ip = __tmp->get_parententry_iterator((void*)__parent._C_w_cur);
01504 __tmp->_C_parents.erase(__ip);
01505
01506 if(__tmp->_C_parents.empty())
01507 {
01508 for(__ic = __tmp->_C_children.begin();
01509 __ic != __tmp->_C_children.end(); ++__ic)
01510 {
01511 __p = (_Node*)*__ic;
01512 __ip = __p->get_parententry_iterator(__tmp);
01513 __p->_C_parents.erase(__ip);
01514 if(__p->_C_parents.empty())
01515 __p->_C_parents.insert(__p->_C_parents.end(),
01516 (void*) this->_C_ground);
01517 }
01518 __tmp->clear_children();
01519 _C_destroy_node(__tmp);
01520 }
01521 }
01522 }
01523
01524
01525 private:
01527 void cut_excess_edges(const walker& __position, _Node* __ngrd, _Node* __nsky,
01528 bool maximal, bool upwards, std::vector<enhanced_edge>& __ev)
01529 {
01530 std::vector<walker> __v(1);
01531 __v[0] = __position;
01532 cut_excess_edges(__v, __ngrd, __nsky, maximal, upwards, __ev);
01533 }
01534
01536 bool parents_are_marked(int __mark, const walker& __pson)
01537 {
01538 parents_iterator _pit;
01539 const_walker __pr;
01540 walker __position(__pson);
01541
01542 for(_pit = __position.parent_begin(); _pit != __position.parent_end();
01543 ++_pit)
01544 {
01545 __pr = __position << _pit;
01546 if(__pr.node()->_C_visited < __mark && !__pr.is_ground())
01547 return false;
01548 }
01549 return true;
01550 }
01551
01553 bool children_are_marked(int __mark, const walker& __pson)
01554 {
01555 children_iterator _cit;
01556 const_walker __ch;
01557 walker __position(__pson);
01558
01559 for(_cit = __position.child_begin(); _cit != __position.child_end();
01560 ++_cit)
01561 {
01562 __ch = __position >> _cit;
01563 if(__ch.node()->_C_visited < __mark && !__ch.is_sky())
01564 return false;
01565 }
01566 return true;
01567 }
01568
01570 void dnrecursive_mark_node(int __mark, const walker& __pson,
01571 bool maximal)
01572 {
01573 children_iterator _cit;
01574 walker __position(__pson);
01575
01576 if(__position._C_w_cur->_C_visited == __mark ||
01577 __position.is_ground() || __position.is_sky())
01578 return;
01579 if(!maximal && !parents_are_marked(__mark, __position))
01580
01581
01582 return;
01583 __position._C_w_cur->_C_visited = __mark;
01584 for(_cit = __position.child_begin();
01585 _cit != __position.child_end(); ++_cit)
01586 dnrecursive_mark_node(__mark, __position>>_cit, maximal);
01587 }
01588
01590 void uprecursive_mark_node(int __mark, const walker& __pson,
01591 bool maximal)
01592 {
01593 walker __position(__pson);
01594 parents_iterator _pit;
01595
01596 if(__position._C_w_cur->_C_visited == __mark ||
01597 __position.is_ground() || __position.is_sky())
01598 return;
01599 if(!maximal && !children_are_marked(__mark, __position))
01600
01601
01602 return;
01603 __position._C_w_cur->_C_visited = __mark;
01604 for(_pit = __position.parent_begin();
01605 _pit != __position.parent_end(); ++_pit)
01606 dnrecursive_mark_node(__mark, __position<<_pit, maximal);
01607 }
01608
01610 void recursive_cut_edges(int __mark, const walker& __pson,
01611 _Node* __ngrd, _Node* __nsky, std::vector<enhanced_edge>& __ev)
01612
01613
01614 {
01615 children_iterator _cit;
01616 _Node* _h;
01617 walker _w;
01618 walker __position(__pson);
01619 edge _e;
01620 bool _rcf(false);
01621 std::list<children_iterator> _er_cit;
01622
01623 for(_cit = __position.child_begin(); _cit != __position.child_end(); ++_cit)
01624 {
01625 _h = (_Node*)(*_cit);
01626 _w = __position >> _cit;
01627 if((__position._C_w_cur->_C_visited == __mark && _h->_C_visited < __mark)
01628 ||(__position._C_w_cur->_C_visited < __mark && _h->_C_visited == __mark))
01629
01630
01631 {
01632 container_iterator __it;
01633
01634
01635 _e = make_pair(__position, _w);
01636
01637 _er_cit.push_back(_cit);
01638
01639 __it = _h->get_parententry_iterator((void*)__position._C_w_cur);
01640 if(__it != _h->_C_parents.end())
01641 _h->_C_parents.erase(__it);
01642 if(__position._C_w_cur->_C_visited == __mark)
01643
01644 {
01645
01646
01647
01648 if(_h->_C_parents.empty())
01649 {
01650 _h->_C_parents.insert(_h->_C_parents.end(), (void*)this->_C_ground);
01651 this->_C_ground->_C_children.insert(this->_C_ground->_C_children.end(),
01652 (void*)_h);
01653 _rcf = true;
01654 }
01655 else
01656 _rcf = false;
01657 }
01658 else
01659
01660 {
01661 if(_h->_C_parents.empty())
01662 {
01663 _h->_C_parents.insert(_h->_C_parents.end(), (void*)__ngrd);
01664 __ngrd->_C_children.insert(__ngrd->_C_children.end(), (void*)_h);
01665 }
01666 }
01667 __ev.push_back(make_pair(_e, _rcf));
01668 }
01669 recursive_cut_edges(__mark, _w, __ngrd, __nsky, __ev);
01670 }
01671 if(!_er_cit.empty())
01672 {
01673
01674
01675
01676
01677
01678 children_iterator _hit, _eit;
01679 typename std::list<children_iterator>::iterator _erc;
01680
01681 _erc = _er_cit.begin();;
01682 _eit = __position._C_w_cur->_C_children.end();
01683 for(_hit = _cit = __position._C_w_cur->_C_children.begin();
01684 _cit != _eit; ++_cit)
01685 {
01686 if(_cit == *_erc)
01687 ++_erc;
01688 else
01689 {
01690 if(_cit != _hit)
01691 *_hit = *_cit;
01692 ++_hit;
01693 }
01694 }
01695 __position._C_w_cur->_C_children.erase(_hit, _eit);
01696
01697 if(__position._C_w_cur->_C_visited == __mark)
01698 {
01699
01700 if(__position._C_w_cur->_C_children.empty())
01701 {
01702 __position._C_w_cur->_C_children.insert(
01703 __position._C_w_cur->_C_children.end(), (void*)__nsky);
01704 __nsky->_C_parents.insert(__nsky->_C_parents.end(),
01705 (void*)__position._C_w_cur);
01706 }
01707 }
01708 else
01709 {
01710
01711
01712
01713 if(__position._C_w_cur->_C_children.empty())
01714 {
01715 __position._C_w_cur->_C_children.insert(
01716 __position._C_w_cur->_C_children.end(), (void*)this->_C_sky);
01717 this->_C_sky->_C_parents.insert(this->_C_sky->_C_parents.end(),
01718 (void*)__position._C_w_cur);
01719 }
01720 }
01721 }
01722 }
01723
01724 #ifdef __VGTL_MEMBER_TEMPLATES
01726 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
01727 class _Allocator>
01728 void cut_excess_edges(const __SequenceCtr<walker,_Allocator>& __positions,
01729 _Node* __ngrd, _Node* __nsky, bool maximal,
01730 bool upwards, std::vector<enhanced_edge>& __ev)
01731 {
01732 int _actmark = ++_C_mark;
01733 typename __SequenceCtr<walker,_Allocator>::const_iterator _pit;
01734 walker _w;
01735
01736 for(_pit = __positions.begin(); _pit != __positions.end(); ++_pit)
01737 {
01738 _w = *_pit;
01739 if(upwards)
01740 uprecursive_mark_node(_actmark, _w, maximal);
01741 else
01742 dnrecursive_mark_node(_actmark, _w, maximal);
01743 }
01744 recursive_cut_edges(_actmark, ground(), __ngrd, __nsky, __ev);
01745 }
01746 #endif
01747
01748
01749 public:
01751 void clear_erased_part(erased_part& _ep)
01752 {
01753 _ep.second.clear();
01754 clear_graph(_ep.first.first);
01755 }
01756
01763 erased_part erase_maximal_subgraph(const walker& __position)
01764 { _RV_DG __rv(_C_create_node(),_C_create_node());
01765 std::vector<enhanced_edge> __ev;
01766
01767 cut_excess_edges(__position, __rv.first, __rv.second, true, false,
01768 __ev);
01769 return make_pair(__rv,__ev);
01770 }
01771
01779 erased_part erase_minimal_subgraph(const walker& __position)
01780 { _RV_DG __rv(_C_create_node(),_C_create_node());
01781 std::vector<enhanced_edge> __ev;
01782
01783 cut_excess_edges(__position, __rv.first, __rv.second, false, false,
01784 __ev);
01785 return make_pair(__rv,__ev);
01786 }
01787
01788 #ifdef __VGTL_MEMBER_TEMPLATES
01789
01795 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
01796 class _Allocator>
01797 erased_part erase_maximal_subgraph(
01798 const __SequenceCtr<walker,_Allocator>& __positions)
01799 { _RV_DG __rv(_C_create_node(),_C_create_node());
01800 std::vector<enhanced_edge> __ev;
01801
01802 cut_excess_edges(__positions, __rv.first, __rv.second, true, false,
01803 __ev);
01804 return make_pair(__rv,__ev);
01805 }
01806
01815 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
01816 class _Allocator>
01817 erased_part erase_minimal_subgraph(
01818 const __SequenceCtr<walker,_Allocator>& __positions)
01819 { _RV_DG __rv(_C_create_node(),_C_create_node());
01820 std::vector<enhanced_edge> __ev;
01821
01822 cut_excess_edges(__positions, __rv.first, __rv.second, false, false,
01823 __ev);
01824 return make_pair(__rv,__ev);
01825 }
01826 #endif
01827
01834 erased_part erase_maximal_pregraph(const walker& __position)
01835 { _RV_DG __rv(_C_create_node(),_C_create_node());
01836 std::vector<enhanced_edge> __ev;
01837
01838 cut_excess_edges(__position, __rv.first, __rv.second, true, true,
01839 __ev);
01840 return make_pair(__rv,__ev);
01841 }
01842
01850 erased_part erase_minimal_pregraph(const walker& __position)
01851 { _RV_DG __rv(_C_create_node(),_C_create_node());
01852 std::vector<enhanced_edge> __ev;
01853
01854 cut_excess_edges(__position, __rv.first, __rv.second, false, true,
01855 __ev);
01856 return make_pair(__rv,__ev);
01857 }
01858
01859 #ifdef __VGTL_MEMBER_TEMPLATES
01860
01866 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
01867 class _Allocator>
01868 erased_part erase_maximal_pregraph(
01869 const __SequenceCtr<walker,_Allocator>& __positions)
01870 { _RV_DG __rv(_C_create_node(),_C_create_node());
01871 std::vector<enhanced_edge> __ev;
01872
01873 cut_excess_edges(__positions, __rv.first, __rv.second, true, true,
01874 __ev);
01875 return make_pair(__rv,__ev);
01876 }
01877
01886 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
01887 class _Allocator>
01888 erased_part erase_minimal_pregraph(
01889 const __SequenceCtr<walker,_Allocator>& __positions)
01890 { _RV_DG __rv(_C_create_node(),_C_create_node());
01891 std::vector<enhanced_edge> __ev;
01892
01893 cut_excess_edges(__positions, __rv.first, __rv.second, false, true,
01894 __ev);
01895 return make_pair(__rv,__ev);
01896 }
01897 #endif
01898
01904 bool erase_child(const walker& __position,
01905 const children_iterator& __It)
01906 {
01907 _Node* __chld = (_Node*)*__It;
01908
01909 if(__chld->_C_children.size() != 1 || __chld->_C_parents.size() != 1)
01910 { return false; }
01911 else
01912 {
01913 _Node* __c2;
01914 parents_iterator __pit;
01915
01916 __c2 = (_Node*)*__chld->_C_children.begin();
01917 __pit = __c2->get_parententry_iterator((void*)__chld);
01918 *__pit = (void*)__position->_C_w_cur;
01919 *__It = (void*)__c2;
01920 _C_destroy_node(__chld);
01921 return true;
01922 }
01923 }
01924
01930 bool erase_parent(const walker& __position,
01931 const parents_iterator& __It)
01932 {
01933 _Node* __prnt = (_Node*)*__It;
01934
01935 if(__prnt->_C_children.size() != 1 || __prnt->_C_parents.size() != 1)
01936 { return false; }
01937 else
01938 {
01939 _Node* __p2;
01940 children_iterator __cit;
01941
01942 __p2 = (_Node*)*__prnt->_C_parents.begin();
01943 __cit = __p2->get_childentry_iterator((void*)__prnt);
01944 *__cit = (void*)__position->_C_w_cur;
01945 *__It = (void*)__p2;
01946 _C_destroy_node(__prnt);
01947 return true;
01948 }
01949 }
01950
01952 void clear() { _Base::clear(); }
01953
01954 private:
01959 _Node* copy_subgraph(_Node* __x, _Node* __par, std::map<_Node*,_Node*>& __nconn)
01960 { children_iterator cit;
01961 typedef typename std::map<_Node*,_Node*>::iterator map_it;
01962 std::pair<map_it,bool> _rv;
01963 _Node* __h = _C_create_node();
01964 _Node* __cs;
01965 map_it __cdit;
01966
01967 _VGTL_Construct_2(&__h->_C_data, __x->_C_data);
01968 __h->_C_parents.insert(__h->_C_parents.end(), (void*)__par);
01969 __h->_C_visited = 0;
01970 if(__x->_C_parents.size() > 1)
01971 _rv = __nconn.insert(make_pair(__x,__h));
01972 for(cit = __x->_C_children.begin(); cit != __x->_C_children.end(); ++cit)
01973 {
01974 __cs = (_Node*)*cit;
01975 __cdit = __nconn.find(__cs);
01976 if(__cdit == __nconn.end())
01977 __h->_C_children.insert(__h->_C_children.end(),
01978 copy_subgraph(__cs, __h, __nconn));
01979 else
01980 {
01981 (*__cdit).second->_C_parents.insert(
01982 (*__cdit).second->_C_parents.end(), __h);
01983 __h->_C_children.insert(__h->_C_children.end(),
01984 (void*)(*__cdit).second);
01985 }
01986 }
01987 return __h;
01988 }
01989
01990 public:
01992 __DG(const _Self& __x) : _Base(__x.get_allocator())
01993 { children_iterator cit;
01994 std::map<_Node*,_Node*> __nconn;
01995 __nconn.insert(make_pair(__x._C_sky, this->_C_sky));
01996 this->_C_mark = 0;
01997 this->_C_ground->clear_children();
01998 this->_C_sky->clear_parents();
01999 for(cit = __x._C_ground->_C_children.begin();
02000 cit != __x._C_ground->_C_children.end(); ++cit)
02001 {
02002 if((_Node*)*cit != __x._C_sky)
02003 this->_C_ground->_C_children.insert(this->_C_ground->_C_children.end(),
02004 copy_subgraph((_Node*)*cit, this->_C_ground, __nconn));
02005 }
02006 }
02007
02009 ~__DG() {}
02010
02012 _Self& operator=(const _Self& __x);
02013
02015 _Self& operator=(const _RV_DG& __rl)
02016 {
02017 this->_C_ground = __rl.first;
02018 this->_C_sky = __rl.second;
02019 return *this;
02020 }
02021
02023 _Self& operator=(const erased_part& __ep)
02024 {
02025 this->_C_ground = __ep.first.first;
02026 this->_C_sky = __ep.first.second;
02027 return *this;
02028 }
02029
02030 #if 0
02031
02032 friend bool operator== __VGTL_NULL_TMPL_ARGS (
02033 const __DG& __x, const __DG& __y);
02034 #endif
02035 };
02036
02037 #if 0
02038
02039 template <class _Tp, class _Ctr, class _Iterator, class _CIterator,
02040 class _Inserter, class _Alloc>
02041 inline bool operator==(const __DG<_Tp,_Ctr,_Iterator,_CIterator,_Inserter,
02042 _Alloc>& __x,
02043 const __DG<_Tp,_Ctr,_Iterator,_CIterator,_Inserter,
02044 _Alloc>& __y)
02045 {
02046 typedef typename __DG<_Tp,_Ctr,_Iterator,_CIterator,_Inserter,
02047 _Alloc>::const_walker const_walker;
02048 const_walker __w1 = __x.begin(cw_pre);
02049 const_walker __w2 = __y.begin(cw_pre);
02050 const_walker __e1 = __x.end(cw_pre);
02051 const_walker __e2 = __y.end(cw_pre);
02052
02053
02054 for(; __w1 != __e1 && __w2 != __e2 ; ++__w1, ++__w2)
02055 if(__w1.in_preorder() != __w2.in_preorder() ||
02056 (__w1.in_preorder() && *__w1 != *__w2))
02057 return false;
02058 return __w1 == __e1 && __w2 == __e2;
02059 }
02060 #endif
02061
02062 template <class _Tp, class _Ctr, class _Iterator, class _CIterator,
02063 class _Inserter, class _Alloc>
02064 __DG<_Tp, _Ctr, _Iterator, _CIterator, _Inserter, _Alloc>&
02065 __DG<_Tp, _Ctr, _Iterator, _CIterator, _Inserter, _Alloc>::operator=(
02066 const __DG<_Tp, _Ctr, _Iterator, _CIterator, _Inserter, _Alloc>& __x)
02067 {
02068 if (this != &__x)
02069 {
02070 children_iterator cit;
02071 std::map<_Node*,_Node*> __nconn;
02072
02073 clear();
02074 __nconn.insert(make_pair(__x._C_sky, this->_C_sky));
02075 this->_C_mark = 0;
02076 for(cit = __x._C_ground->_C_children.begin();
02077 cit != __x._C_ground->_C_children.end(); ++cit)
02078 {
02079 if((_Node*)*cit != __x._C_sky)
02080 this->_C_ground->_C_children.insert(this->_C_ground->_C_children.end(),
02081 copy_subgraph((_Node*)*cit, this->_C_ground, __nconn));
02082 }
02083 }
02084 return *this;
02085 }
02086
02088
02094 template <class _Tp,
02095 template <class __Ty, class __AllocT> class _SequenceCtr = std::vector,
02096 class _PtrAlloc = __VGTL_DEFAULT_ALLOCATOR(void *),
02097 class _Alloc = __VGTL_DEFAULT_ALLOCATOR(_Tp) >
02098 class dgraph : public __DG<_Tp, _SequenceCtr<void*, _PtrAlloc>,
02099 typename _SequenceCtr<void*, _PtrAlloc>::iterator,
02100 typename _SequenceCtr<void*, _PtrAlloc>::const_iterator,
02101 typename _SequenceCtr<void*, _PtrAlloc>::iterator,
02102 _Alloc>
02103 {
02104 private:
02105 typedef typename _SequenceCtr<void*, _PtrAlloc>::iterator ___cit;
02106 typedef __DG<_Tp,_SequenceCtr<void*, _PtrAlloc>,
02107 typename _SequenceCtr<void*, _PtrAlloc>::iterator,
02108 typename _SequenceCtr<void*, _PtrAlloc>::const_iterator,
02109 typename _SequenceCtr<void*, _PtrAlloc>::iterator,
02110 _Alloc> _Base;
02111 protected:
02112 typedef dgraph<_Tp,_SequenceCtr,_PtrAlloc,_Alloc> _Self;
02113 typedef typename _Base::allocator_type allocator_type;
02114 typedef typename _Base::_RV_DG _RV_DG;
02115 typedef typename _Base::_Node _Node;
02116
02117 typedef typename _Base::container_iterator container_iterator;
02118
02119 typedef typename _Base::erased_part erased_part;
02120
02121 public:
02123 typedef typename _Base::walker walker;
02125 typedef typename _Base::const_walker const_walker;
02127 typedef typename _Base::children_iterator children_iterator;
02129 typedef typename _Base::parents_iterator parents_iterator;
02131 typedef typename _Base::parents_const_iterator parents_const_iterator;
02133 typedef typename _Base::children_const_iterator children_const_iterator;
02134
02135 public:
02137 explicit dgraph(const allocator_type& __a = allocator_type()) : _Base(__a) {}
02138
02140 dgraph(const _Self& __dg) : _Base(__dg) {}
02141
02143 dgraph(const erased_part& __ep, const allocator_type& __a = allocator_type())
02144 : _Base(__a)
02145 {
02146 this->_C_ground = __ep.first.first;
02147 this->_C_sky = __ep.first.second;
02148 }
02149
02150
02151
02153 void clear() { _Base::clear(); }
02154
02160 walker between(const walker& __parent, const children_iterator& __cit,
02161 const walker& __child, const parents_iterator& __pit,
02162 const _Tp& __x)
02163 {
02164 return insert_in_graph(__x, __parent, __child, __cit, __pit);
02165 }
02166
02167
02173 walker split(const walker& __parent, const children_iterator& __ch_it,
02174 const walker& __child, const parents_iterator& __pa_it,
02175 const _Tp& __x)
02176 {
02177 container_iterator __cit;
02178
02179 walker __rv = between(__parent, __ch_it, __child, __pa_it, __x);
02180
02181 __cit = __parent._C_w_cur->get_childentry_iterator((void*)__child._C_w_cur);
02182 if(__cit != __parent._C_w_cur->_C_children.end())
02183 __parent._C_w_cur->_C_children.erase(__cit);
02184 __cit = __child._C_w_cur->get_parententry_iterator((void*)__parent._C_w_cur);
02185 if(__cit != __child._C_w_cur->_C_parents.end())
02186 __child._C_w_cur->_C_parents.erase(__cit);
02187 return __rv;
02188 }
02189
02190
02195 walker between_back(const walker& __parent, const walker& __child,
02196 const _Tp& __x)
02197 {
02198 return insert_in_graph(__x, __parent, __child,
02199 __parent._C_w_cur->_C_children.end(),
02200 __child._C_w_cur->_C_parents.end());
02201 }
02202
02203
02208 walker split_back(const walker& __parent,
02209 const walker& __child, const _Tp& __x)
02210 {
02211 container_iterator __cit;
02212
02213 __cit = __parent._C_w_cur->get_childentry_iterator((void*)__child._C_w_cur);
02214 if(__cit != __parent._C_w_cur->_C_children.end())
02215 __parent._C_w_cur->_C_children.erase(__cit);
02216 __cit = __child._C_w_cur->get_parententry_iterator((void*)__parent._C_w_cur);
02217 if(__cit != __child._C_w_cur->_C_parents.end())
02218 __child._C_w_cur->_C_parents.erase(__cit);
02219 return between_back(__parent, __child, __x);
02220 }
02221
02226 walker between_front(const walker& __parent, const walker& __child,
02227 const _Tp& __x)
02228 {
02229 return insert_in_graph(__x, __parent, __child,
02230 __parent._C_w_cur->_C_children.begin(),
02231 __child._C_w_cur->_C_parents.begin());
02232 }
02233
02234
02239 walker split_front(const walker& __parent,
02240 const walker& __child, const _Tp& __x)
02241 {
02242 container_iterator __cit;
02243
02244 __cit = __parent._C_w_cur->get_childentry_iterator((void*)__child._C_w_cur);
02245 if(__cit != __parent._C_w_cur->_C_children.end())
02246 __parent._C_w_cur->_C_children.erase(__cit);
02247 __cit = __child._C_w_cur->get_parententry_iterator((void*)__parent._C_w_cur);
02248 if(__cit != __child._C_w_cur->_C_parents.end())
02249 __child._C_w_cur->_C_parents.erase(__cit);
02250 return between_front(__parent, __child, __x);
02251 }
02252
02253
02258 #ifdef __VGTL_MEMBER_TEMPLATES
02259 template <template <class __Tp, class __AllocTp> class __SequenceCtr1,
02260 template <class __Tp, class __AllocTp> class __SequenceCtr2,
02261 class _Allocator1, class _Allocator2>
02262 walker between(const __SequenceCtr1<walker,_Allocator1>& __parents,
02263 const __SequenceCtr2<walker,_Allocator2>& __children,
02264 const _Tp& __x)
02265 {
02266 typename __SequenceCtr1<walker,_Allocator1>::iterator __wpit;
02267 typename __SequenceCtr2<walker,_Allocator2>::iterator __wcit;
02268 _Node* __tmp = _C_create_node(__x);
02269 walker __help(__tmp);
02270
02271 if(__parents.empty() || __children.empty())
02272 return;
02273 __wpit = __parents.begin();
02274 __wcit = __children.begin();
02275 insert_node_in_graph(__tmp, *__wpit, *__wcit,
02276 (*__wpit)._C_w_cur->_C_children.end(),
02277 (*__wcit)._C_w_cur->_C_parents.end());
02278 for(++__wpit; __wpit != __parents.end(); ++__wpit)
02279 add_edge(*__wpit, __help, (*__wpit)._C_w_cur->_C_children.end(),
02280 __tmp->_C_parents.end());
02281 for(++__wcit; __wcit != __children.end(); ++__wcit)
02282 add_edge(__help, *__wcit, __tmp->_C_children.end(),
02283 (*__wcit)._C_w_cur->_C_parents.end());
02284 return __help;
02285 }
02286
02291 template <template <class __Tp, class __AllocTp> class __SequenceCtr1,
02292 template <class __Tp, class __AllocTp> class __SequenceCtr2,
02293 class _Allocator1, class _Allocator2>
02294 void split(const __SequenceCtr1<walker,_Allocator1>& __parents,
02295 const __SequenceCtr2<walker,_Allocator2>& __children,
02296 const _Tp& __x)
02297 {
02298 container_iterator __cit;
02299 typename __SequenceCtr1<walker,_Allocator1>::const_iterator __pnt;
02300 typename __SequenceCtr2<walker,_Allocator2>::const_iterator __cld;
02301
02302 for(__cld = __children.begin(); __cld != __children.end(); ++__cld)
02303 for(__pnt = __parents.begin(); __pnt != __parents.end(); ++__pnt)
02304 {
02305 __cit = (*__pnt)._C_w_cur->get_childentry_iterator((void*)(*__cld)._C_w_cur);
02306 if(__cit != (*__pnt)._C_w_cur->_C_children.end())
02307 (*__pnt)._C_w_cur->_C_children.erase(__cit);
02308 __cit = (*__cld)._C_w_cur->get_parententry_iterator((void*)(*__pnt)._C_w_cur);
02309 if(__cit != (*__cld)._C_w_cur->_C_parents.end())
02310 (*__cld)._C_w_cur->_C_parents.erase(__cit);
02311 }
02312 between(__parents, __children, __x);
02313 }
02314 #endif
02315
02320 void insert_subgraph(_Self& __subgraph, const walker& __parent,
02321 const children_iterator& __ch_it, const walker& __child,
02322 const parents_iterator& __pa_it)
02323 {
02324 insert_subgraph(__subgraph, __parent, __child, __ch_it, __pa_it);
02325 }
02326
02331 void insert_back_subgraph(_Self& __subgraph, const walker& __parent,
02332 const walker& __child)
02333 {
02334 insert_subgraph(__subgraph, __parent, __child,
02335 __parent._C_w_cur->_C_children.end(),
02336 __child._C_w_cur->_C_parents.end());
02337 }
02338
02339
02344 void insert_front_subgraph(_Self& __subgraph, const walker& __parent,
02345 const walker& __child)
02346 {
02347 insert_subgraph(__subgraph, __parent, __child,
02348 __parent._C_w_cur->_C_children.begin(),
02349 __child._C_w_cur->_C_parents.begin());
02350 }
02351
02352
02353 #ifdef __VGTL_MEMBER_TEMPLATES
02354
02355 #if 0
02356 template <template <class __Tp, class __AllocTp> class __SequenceCtr1,
02357 template <class __Tp, class __AllocTp> class __SequenceCtr2,
02358 class _Allocator1, class _Allocator2>
02359 void insert_subgraph(_Self& __subgraph,
02360 const __SequenceCtr1<walker,_Allocator1>& __parents,
02361 const __SequenceCtr2<walker,_Allocator2>& __children)
02362 {
02363 insert_subgraph(__subgraph, __parents, __children);
02364 }
02365 #endif // 0
02366 #endif
02367
02372 void add_edge(const walker& __parent, const children_iterator& __ch_it,
02373 const walker& __child, const parents_iterator& __pa_it)
02374 {
02375 _Base::add_edge(__parent, __child, __ch_it, __pa_it);
02376 }
02377
02382 void add_edge_back(const walker& __parent, const walker& __child)
02383 {
02384 add_edge(__parent, __parent._C_w_cur->_C_children.end(), __child,
02385 __child._C_w_cur->_C_parents.end());
02386 }
02387
02392 void add_edge_front(const walker& __parent, const walker& __child)
02393 {
02394 add_edge(__parent, __parent._C_w_cur->_C_children.begin(), __child,
02395 __child._C_w_cur->_C_parents.begin());
02396 }
02397
02398
02399
02400 #ifdef __VGTL_MEMBER_TEMPLATES
02402
02406 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
02407 class _Allocator>
02408 walker between(const walker& __parent, const children_iterator& __cit,
02409 const __SequenceCtr<walker,_Allocator>& __children,
02410 const _Tp& __x)
02411 {
02412 return insert_in_graph(__x, __parent, __cit, __children);
02413 }
02414
02419 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
02420 class _Allocator>
02421 walker split(const walker& __parent, const children_iterator& __ch_it,
02422 const __SequenceCtr<walker,_Allocator>& __children,
02423 const _Tp& __x)
02424 {
02425 container_iterator __cit;
02426 typename __SequenceCtr<walker,_Allocator>::const_iterator __cld;
02427 walker __rv = between(__parent, __ch_it, __children, __x);
02428
02429 for(__cld = __children.begin(); __cld != __children.end(); ++__cld)
02430 {
02431 __cit = __parent._C_w_cur->get_childentry_iterator((void*)(*__cld)._C_w_cur);
02432 if(__cit != __parent._C_w_cur->_C_children.end())
02433 __parent._C_w_cur->_C_children.erase(__cit);
02434 __cit = (*__cld)._C_w_cur->get_parententry_iterator((void*)__parent._C_w_cur);
02435 if(__cit != (*__cld)._C_w_cur->_C_parents.end())
02436 (*__cld)._C_w_cur->_C_parents.erase(__cit);
02437 }
02438 return __rv;
02439 }
02440
02446 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
02447 class _Allocator>
02448 walker split_back(const walker& __parent,
02449 const __SequenceCtr<walker, _Allocator>& __children,
02450 const _Tp& __x)
02451 {
02452 return split(__parent, __parent._C_w_cur->_C_children.end(), __children,
02453 __x);
02454 }
02455
02461 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
02462 class _Allocator>
02463 walker between_back(const walker& __parent,
02464 const __SequenceCtr<walker,_Allocator>& __children,
02465 const _Tp& __x)
02466 {
02467 return between(__parent, __parent._C_w_cur->_C_children.end(),
02468 __children, __x);
02469 }
02470
02476 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
02477 class _Allocator>
02478 walker split_front(const walker& __parent,
02479 const __SequenceCtr<walker,_Allocator>& __children,
02480 const _Tp& __x)
02481 {
02482 return split(__parent, __parent._C_w_cur->_C_children.begin(), __children,
02483 __x);
02484 }
02485
02491 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
02492 class _Allocator>
02493 walker between_front(const walker& __parent,
02494 const __SequenceCtr<walker,_Allocator>& __children,
02495 const _Tp& __x)
02496 {
02497 return between(__parent, __parent._C_w_cur->_C_children.begin(),
02498 __children, __x);
02499 }
02500
02502
02506 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
02507 class _Allocator>
02508 walker between(const __SequenceCtr<walker,_Allocator>& __parents,
02509 const walker& __child, const parents_iterator& __pit,
02510 const _Tp& __x)
02511 {
02512 return insert_in_graph(__x, __parents, __child, __pit);
02513 }
02514
02519 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
02520 class _Allocator>
02521 walker split(const __SequenceCtr<walker,_Allocator>& __parents,
02522 const walker& __child, const parents_iterator& __pr_it,
02523 const _Tp& __x)
02524 {
02525 container_iterator __cit;
02526 typename __SequenceCtr<walker,_Allocator>::iterator __pnt;
02527 walker __rv = between(__parents, __child, __pr_it, __x);
02528
02529 for(__pnt = __parents.begin(); __pnt != __parents.end(); ++__pnt)
02530 {
02531 __cit = __child._C_w_cur->get_parententry_iterator((void*)(*__pnt));
02532 if(__cit != __child._C_w_cur->_C_parents.end())
02533 __child._C_w_cur->_C_parents.erase(__cit);
02534 __cit = (*__pnt)._C_w_cur->get_childentry_iterator((void*)__child);
02535 if(__cit != (*__pnt)._C_w_cur->_C_children.end())
02536 (*__pnt)._C_w_cur->_C_children.erase(__cit);
02537 }
02538 return __rv;
02539 }
02540
02546 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
02547 class _Allocator>
02548 walker split_back(const __SequenceCtr<walker,_Allocator>& __parents, const walker& __child,
02549 const _Tp& __x)
02550 {
02551 return split(__parents, __child, __child._C_w_cur->_C_parents.end(),
02552 __x);
02553 }
02554
02560 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
02561 class _Allocator>
02562 walker between_back(const __SequenceCtr<walker,_Allocator>& __parents,
02563 const walker& __child, const _Tp& __x)
02564 {
02565 return between(__parents, __child,
02566 __child._C_w_cur->_C_children.end(), __x);
02567 }
02568
02574 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
02575 class _Allocator>
02576 walker split_front(const __SequenceCtr<walker,_Allocator>& __parents,
02577 const walker& __child, const _Tp& __x)
02578 {
02579 return split(__parents, __child, __child._C_w_cur->_C_parents.begin(),
02580 __x);
02581 }
02582
02588 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
02589 class _Allocator>
02590 walker between_front(const __SequenceCtr<walker,_Allocator>& __parents,
02591 const walker& __child, const _Tp& __x)
02592 {
02593 return between(__parents, __child,
02594 __child._C_w_cur->_C_children.begin(), __x);
02595 }
02596 #endif
02597
02599 _Self& operator=(const _RV_DG& __rl)
02600 {
02601 this->_C_ground = __rl.first;
02602 this->_C_sky = __rl.second;
02603 return *this;
02604 }
02605
02607 _Self& operator=(const erased_part& __ep)
02608 {
02609 this->_C_ground = __ep.first.first;
02610 this->_C_sky = __ep.first.second;
02611 return *this;
02612 }
02613 };
02614
02616
02617
02618
02619
02620
02621
02622
02624
02630 template <class _Tp,
02631 template <class __Ty, class __AllocT> class _SequenceCtr = std::vector,
02632 class _PtrAlloc = __VGTL_DEFAULT_ALLOCATOR(void *),
02633 class _Alloc = __VGTL_DEFAULT_ALLOCATOR(_Tp) >
02634 class dag : public dgraph<_Tp, _SequenceCtr, _PtrAlloc, _Alloc>
02635 {
02636 protected:
02637 typedef dag<_Tp,_SequenceCtr,_PtrAlloc,_Alloc> _Self;
02638 typedef dgraph<_Tp, _SequenceCtr, _PtrAlloc, _Alloc> _Base;
02639
02640 typedef typename _Base::allocator_type allocator_type;
02641 typedef typename _Base::_RV_DG _RV_DG;
02642 typedef typename _Base::_Node _Node;
02643
02644 typedef typename _Base::container_iterator container_iterator;
02645
02646 public:
02648 typedef typename _Base::walker walker;
02650 typedef typename _Base::const_walker const_walker;
02652 typedef typename _Base::children_iterator children_iterator;
02654 typedef typename _Base::parents_iterator parents_iterator;
02656 typedef typename _Base::children_const_iterator children_const_iterator;
02658 typedef typename _Base::parents_const_iterator parents_const_iterator;
02659
02661 typedef typename _Base::erased_part erased_part;
02662
02663 public:
02665 explicit dag(const allocator_type& __a = allocator_type()) : _Base(__a) {}
02666
02668 dag(const _Self& __dag) : _Base(__dag) {}
02669
02670
02671
02672
02674 dag(const _Base& __dag) : _Base(__dag)
02675 {
02676 if(!check_acyclicity(this->ground(), this->sky()))
02677
02678 this->clear();
02679 }
02680
02682 dag(const erased_part& __ep) : _Base(__ep)
02683 {
02684 if(!check_acyclicity(this->ground(), this->sky()))
02685
02686 this->clear();
02687 }
02688 #if 0
02689 void add_edge(const walker& __parent, const walker& __child)
02690 {
02691 }
02692
02693
02694 #endif
02695
02696 private:
02697
02698 bool check_edge(const walker& __parent, const walker& __child)
02699 {
02700 return true;
02701 }
02702
02703 public:
02705 bool check_acyclicity(const walker& __parent, const walker& __child)
02706 {
02707 return true;
02708 }
02709
02710 #if 0
02711 #ifdef __VGTL_MEMBER_TEMPLATES
02712 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
02713 class _Allocator>
02714 void check_edges(const _SequenceCtr<std::pair<walker,walker>,_Allocator >& __edges)
02715 {
02716 }
02717 #endif
02718 #endif
02719
02721 _Self& operator=(const _RV_DG& __rl)
02722 {
02723 this->_C_ground = __rl.first;
02724 this->_C_sky = __rl.second;
02725 return *this;
02726 }
02727
02729 _Self& operator=(const erased_part& __ep)
02730 {
02731 this->_C_ground = __ep.first.first;
02732 this->_C_sky = __ep.first.second;
02733 return *this;
02734 }
02735 };
02736
02737
02739
02740 #if 0
02741
02742
02743 template <class _Tp,
02744 template <class __Key, class __Ty, class __Compare, class __AllocT> class _AssocCtr = std::multimap,
02745 class _Key = std::string,
02746 class _Compare = less<_Key>,
02747 class _PtrAlloc = __VGTL_DEFAULT_ALLOCATOR(void *),
02748 class _Alloc = __VGTL_DEFAULT_ALLOCATOR(_Tp) >
02749 class ldgraph : public __DG<_Tp, _AssocCtr<_Key, void*, _Compare, _PtrAlloc>,
02750 pair_adaptor<typename _AssocCtr<_Key, void*,
02751 _Compare, _PtrAlloc>::iterator>,
02752 _Key, _Alloc>
02753 {
02754 protected:
02755 typedef ldgraph<_Tp,_AssocCtr,_Key,_Compare,_PtrAlloc,_Alloc> _Self;
02756
02757 public:
02758 _Self& operator=(_Node* __x)
02759 {
02760 this->_C_node = __x;
02761 return *this;
02762 }
02763
02764
02765 };
02766
02767 template <class _Tp,
02768 template <class __Key, class __Ty, class __Compare, class __AllocT> class _AssocCtr = std::multimap,
02769 class _Key = std::string,
02770 class _Compare = less<_Key>,
02771 class _PtrAlloc = __VGTL_DEFAULT_ALLOCATOR(void *),
02772 class _Alloc = __VGTL_DEFAULT_ALLOCATOR(_Tp) >
02773 class ldag : public ldgraph<_Tp, _AssocCtr, _Key, _Compare, _PtrAlloc, _Alloc>
02774 {
02775 protected:
02776 typedef ldag<_Tp,_AssocCtr,_Key,_Compare,_PtrAlloc,_Alloc> _Self;
02777 typedef ldgraph<_Tp,_AssocCtr,_Key,_Compare,_PtrAlloc,_Alloc> _Base;
02778
02779 public:
02780 explicit ldag(const allocator_type& __a = allocator_type()) : _Base(__a) {}
02781
02782 explicit ldag() : _Base(allocator_type()) {}
02783
02784 ldag(const _Self& __dag) : _Base(__dag) {}
02785
02786
02787
02788
02789 #if 0
02790 void add_edge(const walker& __parent, const walker& __child)
02791 {
02792 }
02793
02794
02795
02796 private:
02797 void check_edge(const walker& __parent, const walker& __child)
02798 {
02799 }
02800
02801 #ifdef __VGTL_MEMBER_TEMPLATES
02802 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
02803 class _Allocator>
02804 void check_edges(const _SequenceCtr<std::pair<walker,walker>,_Allocator >& __edges)
02805 {
02806 }
02807 #endif
02808 #endif
02809
02810 _Self& operator=(const _RV_DG& __rl)
02811 {
02812 this->_C_ground = __rl.first;
02813 this->_C_sky = __rl.second;
02814 return *this;
02815 }
02816 };
02817 #endif
02818
02819
02820
02821
02822
02823
02824
02825
02826
02827
02828
02829
02830
02831
02832
02833
02834
02835
02836
02837
02838
02839
02840
02841
02842
02843
02844
02845
02846
02847
02848
02849
02850
02851
02852
02853
02854
02855
02856
02857
02858
02859
02860
02861
02862
02863
02864
02865
02866
02867
02868
02869
02870
02871
02872
02873
02874
02875
02876
02877
02878
02879
02880
02881
02882
02883
02884
02885
02886
02887
02888
02889
02890
02891
02892
02893
02894
02895
02896
02897
02898
02899
02900
02901
02902
02903
02904
02905
02906
02907
02908
02909
02910
02911
02912
02913
02914
02915
02916
02917
02918
02919
02920
02921
02922
02923
02924
02925
02926
02927
02928
02929
02930
02931
02932
02933
02934
02935
02936
02937
02938
02939
02940
02941
02942
02943
02944
02945
02946
02947
02948
02949
02950
02951
02952
02953
02954
02955
02956
02957
02958
02959
02960
02961
02962
02963
02964
02965
02966
02967
02968
02969
02970
02971
02972
02973
02974
02975
02976
02977
02978
02979
02980
02981
02982
02983
02984
02985
02986
02987
02988
02989
02990
02991
02992
02993
02994
02995
02996
02997
02998
02999
03000
03001
03002
03003
03004
03005
03006
03007
03008
03009
03010
03011
03012
03013
03014
03015
03016
03017
03018
03019
03020
03021
03022
03023
03024
03025
03026
03027
03028
03029
03030
03031
03032
03033
03034
03035
03036
03037
03038
03039
03040
03041
03042
03043
03044
03045
03046
03047
03048
03049
03050
03051
03052
03053
03054
03055
03056
03057
03058
03059
03060
03061
03062
03063
03064
03065
03066
03067
03068
03069 __VGTL_END_NAMESPACE
03070
03071 #endif // __VGTL_DAG_H_