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_LDAG_H_
00032 #define __VGTL_LDAG_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_ldagbase.h>
00046
00047 __VGTL_BEGIN_NAMESPACE
00048
00049
00050 template <class _Tp, class _Ref, class _Ptr, class _Ctr, class _Iterator,
00051 class _CIterator, class _Te>
00052 class _LDG_iterator;
00053
00055
00060 template <class _Tp, class _Ref, class _Ptr, class _Ctr, class _Iterator,
00061 class _CIterator, class _Te>
00062 class _LDG_walker
00063 {
00064 public:
00065 typedef _LDG_walker<_Tp,_Tp&,_Tp*,_Ctr,_Iterator,_CIterator,_Te> walker;
00066 typedef _LDG_walker<_Tp,const _Tp&,const _Tp*,_Ctr,_Iterator,_CIterator,_Te>
00067 const_walker;
00068
00069 private:
00070 typedef _LDG_walker<_Tp,_Ref,_Ptr,_Ctr,_Iterator,_CIterator,_Te> _Self;
00071 typedef _LDG_iterator<_Tp,_Ref,_Ptr,_Ctr,_Iterator,_CIterator,_Te> _Itr;
00072
00073 public:
00075
00076 typedef _Tp value_type;
00077 typedef _Ptr pointer;
00078 typedef _Ref reference;
00079 typedef _Te edge_value_type;
00081
00082 private:
00083 typedef _LDG_node<_Tp,_Ctr,_Iterator> _Node;
00084 typedef _LDG_edge<_Te,_Tp> _Edge;
00085 typedef _Iterator _Ctr_iterator;
00086 typedef _CIterator _Ctr_const_iterator;
00087
00088 public:
00090
00091 typedef _Ctr_iterator out_edge_iterator;
00092 typedef _Ctr_iterator in_edge_iterator;
00093 typedef _Ctr_const_iterator out_edge_const_iterator;
00094 typedef _Ctr_const_iterator in_edge_const_iterator;
00095 typedef _Node node_type;
00096 typedef _Edge edge_type;
00097
00098 typedef out_edge_iterator children_iterator;
00099 typedef in_edge_iterator parents_iterator;
00100 typedef out_edge_const_iterator children_const_iterator;
00101 typedef in_edge_const_iterator parents_const_iterator;
00102
00103 typedef size_t size_type;
00104 typedef ptrdiff_t difference_type;
00106
00107 public:
00109 _Node* _C_w_cur;
00110
00111 public:
00113 _LDG_walker() {}
00114
00115 public:
00117 _LDG_walker(_Node* __x) : _C_w_cur(__x) { }
00118
00120 _LDG_walker(const walker& __x) : _C_w_cur(__x._C_w_cur) {}
00121
00123 reference operator*() const { return (*_C_w_cur)._C_data; }
00124
00125 #ifndef __SGI_STL_NO_ARROW_OPERATOR
00126
00127 pointer operator->() const { return &(operator*()); }
00128 #endif
00129
00130 public:
00132 const _Node* node() { return _C_w_cur; }
00133
00135 size_type out_degree() const { return (*_C_w_cur)._C_children.size(); }
00137 size_type in_degree() const { return (*_C_w_cur)._C_parents.size(); }
00138
00140 size_type n_children() const { return out_degree(); }
00142 size_type n_children() const { return in_degree(); }
00143
00145 bool is_source() const
00146 { if(in_degree() != 1)
00147 return false;
00148 else
00149 {
00150 _Node* __help = (_Node*)*((*_C_w_cur)._C_in_edges.begin());
00151 return (*__help)._C_in_edges.empty();
00152 }
00153 }
00155 bool is_root() const { return is_source(); }
00157 bool is_sink() const
00158 { if(out_degree() != 1)
00159 return false;
00160 else
00161 {
00162 _Node* __help = (_Node*)*((*_C_w_cur)._C_in_edges.begin());
00163 return (*__help)._C_in_edges.empty();
00164 }
00165 }
00167 bool is_leaf() const { return is_sink(); }
00168
00170 bool is_ground() const { return (*_C_w_cur)._C_in_edges.empty(); }
00172 bool is_sky() const { return (*_C_w_cur)._C_out_edges.empty(); }
00173
00175
00176 out_iterator out_begin() { return (*_C_w_cur)._C_out_edges.begin(); }
00177 out_const_iterator out_begin() const
00178 { return (*_C_w_cur)._C_out_edges.begin(); }
00179 out_iterator child_begin() { return out_begin(); }
00180 out_const_iterator child_begin() const { return out_begin(); }
00182
00183
00184 out_iterator out_end() { return (*_C_w_cur)._C_out_edges.end(); }
00185 out_const_iterator out_end() const
00186 { return (*_C_w_cur)._C_out_edges.end(); }
00187 out_iterator child_end() { return out_end(); }
00188 out_const_iterator child_end() const { return out_end(); }
00190
00192
00193 in_iterator in_begin() { return (*_C_w_cur)._C_in_edges.begin(); }
00194 in_const_iterator in_begin() const
00195 { return (*_C_w_cur)._C_in_edges.begin(); }
00196 in_iterator parent_begin() { return in_begin(); }
00197 in_const_iterator parent_begin() const { return in_begin(); }
00199
00200
00201 in_iterator in_end() { return (*_C_w_cur)._C_in_edges.end(); }
00202 in_const_iterator in_end() const
00203 { return (*_C_w_cur)._C_in_edges.end(); }
00204 in_iterator in_end() { return in_end(); }
00205 in_const_iterator in_end() const { return in_end(); }
00207
00209 template <class _Function>
00210 _Function for_each_child(_Function __f)
00211 {
00212 return for_each(child_begin(), child_end(), __f);
00213 }
00215 template <class _Function>
00216 _Function for_each_parent(_Function __f)
00217 {
00218 return for_each(parent_begin(), parent_end(), __f);
00219 }
00220
00221 public:
00223
00224 bool operator==(const _Self& __x) const
00225 { return _C_w_cur == __x._C_w_cur; }
00226 bool operator!=(const _Self& __x) const
00227 { return _C_w_cur != __x._C_w_cur; }
00229
00231 _Self operator<<(in_iterator __i) {
00232 _Self __tmp = *this;
00233 _Edge &__te(*__i);
00234 __tmp._C_w_cur = __te.source();
00235 return __tmp;
00236 }
00237
00239 _Self operator>>(out_iterator __i) {
00240 _Self __tmp = *this;
00241 _Edge &__te(*__i);
00242 __tmp._C_w_cur = __te.target();
00243 return __tmp;
00244 }
00245
00247 _Self& operator<<=(in_iterator __i) {
00248 _Edge &__te(*__i);
00249 _C_w_cur = __te.source();
00250 return *this;
00251 }
00252
00254 _Self& operator>>=(out_iterator __i) {
00255 _Edge &__te(*__i);
00256 _C_w_cur = __te.target();
00257 return *this;
00258 }
00259
00261 _Self operator<<(in_const_iterator __i) {
00262 _Self __tmp = *this;
00263 const _Edge &__te(*__i);
00264 __tmp._C_w_cur = __te.source();
00265 return __tmp;
00266 }
00267
00269 _Self operator>>(out_const_iterator __i) {
00270 _Self __tmp = *this;
00271 const _Edge &__te(*__i);
00272 __tmp._C_w_cur = __te.target();
00273 return __tmp;
00274 }
00275
00277 _Self& operator<<=(parents_const_iterator __i) {
00278 const _Edge &__te(*__i);
00279 _C_w_cur = __te.source();
00280 return *this;
00281 }
00282
00284 _Self& operator>>=(children_const_iterator __i) {
00285 const _Edge &__te(*__i);
00286 _C_w_cur = __te.target();
00287 return *this;
00288 }
00289
00291 _Self& operator=(const _Itr& __x) {
00292 _C_w_cur = __x._C_i_cur;
00293 return *this;
00294 }
00295
00297 _Self& operator=(const _Self& __x) {
00298 _C_w_cur = __x._C_w_cur;
00299 return *this;
00300 }
00301
00303 _Self& operator=(const _Node& __n) {
00304 _C_w_cur = &__n;
00305 return *this;
00306 }
00307 };
00308
00310
00316 template <class _Tp, class _Ref, class _Ptr, class _Ctr, class _Iterator,
00317 class _CIterator, class _Te>
00318 class _LDG_iterator
00319 {
00320 public:
00321 typedef _LDG_iterator<_Tp,_Tp&,_Tp*,_Ctr,_Iterator,_CIterator, _Te> iterator;
00322 typedef _LDG_iterator<_Tp,const _Tp&,const _Tp*,_Ctr,_Iterator,_CIterator, _Te>
00323 const_iterator;
00324 typedef _LDG_iterator<_Tp,_Ref,_Ptr,_Ctr,_Iterator,_CIterator, _Te> _Self;
00325 typedef _LDG_walker<_Tp,_Ref,_Ptr,_Ctr,_Iterator,_CIterator, _Te> _Walk;
00326
00328
00329 typedef std::bidirectional_iterator_tag iterator_category;
00330 typedef _Tp value_type;
00331 typedef _Ptr pointer;
00332 typedef _Ref reference;
00333 typedef _LDG_node<_Tp,_Ctr,_Iterator> _Node;
00334 typedef size_t size_type;
00335 typedef ptrdiff_t difference_type;
00337 typedef _Iterator _Ctr_iterator;
00338 typedef _CIterator _Ctr_const_iterator;
00339
00340 protected:
00342 _Node* _C_i_cur;
00344 std::vector<_Ctr_iterator> _C_i_cur_it;
00345
00346 public:
00348 _LDG_iterator() : _C_i_cur_it() {_C_i_cur_it.reserve(32);}
00350 _LDG_iterator(const iterator& __x) : _C_i_cur(__x._C_i_cur),
00351 _C_i_cur_it(__x._C_i_cur_it) {}
00352
00354
00355 bool operator==(const _Self& __x) const
00356 { return (_C_i_cur->_C_in_edges.empty() &&
00357 __x._C_i_cur->_C_in_edges.empty()) ||
00358 (_C_i_cur->_C_out_edges.empty() &&
00359 __x._C_i_cur->_C_out_edges.empty()) ||
00360 ( _C_i_cur == __x._C_i_cur &&
00361 _C_i_cur_it == __x._C_i_cur_it);
00362 }
00363 bool operator!=(const _Self& __x) const
00364 { return (!_C_i_cur->_C_in_edges.empty() ||
00365 !__x._C_i_cur->_C_in_edges.empty()) &&
00366 (!_C_i_cur->_C_out_edges.empty() ||
00367 !__x._C_i_cur->_C_out_edges.empty()) &&
00368 ( _C_i_cur != __x._C_i_cur ||
00369 _C_i_cur_it != __x._C_i_cur_it);
00370 }
00372
00373 reference operator*() const { return (*_C_i_cur)._C_data; }
00374
00375 #ifndef __SGI_STL_NO_ARROW_OPERATOR
00376
00377 pointer operator->() const { return &(operator*()); }
00378 #endif
00379
00380 private:
00382 void find_start_node();
00384 void find_next_node();
00386 void find_prev_node();
00387
00388 public:
00390 _Self& operator=(const _Walk& __x) {
00391 _C_i_cur = __x._C_w_cur;
00392 _C_i_cur_it.erase(_C_i_cur_it.begin(), _C_i_cur_it.end());
00393
00394
00395 find_start_node();
00396 return *this;
00397 }
00398
00400
00401 _Self& operator++() {
00402 find_next_node();
00403 return *this;
00404 }
00405 _Self operator++(int) {
00406 _Self __tmp = *this;
00407 ++*this;
00408 return __tmp;
00409 }
00410
00411 _Self& operator--() {
00412 find_prev_node();
00413 return *this;
00414 }
00415 _Self operator--(int) {
00416 _Self __tmp = *this;
00417 --*this;
00418 return __tmp;
00419 }
00421 };
00422
00423 #ifndef __VGTL_CLASS_PARTIAL_SPECIALIZATION // Specifies the iterator to be bi-directional.
00424 template <class _Tp, class _Ref, class _Ptr, class _Ctr, class _Iterator,
00425 class _CIterator, class _Te>
00426 inline bidirectional_iterator_tag
00427 iterator_category(const _LDG_iterator<_Tp,_Ref,_Ptr,_Ctr,_Iterator,_CIterator,_Te>&)
00428 {
00429 return bidirectional_iterator_tag();
00430 }
00431
00432 template <class _Tp, class _Ref, class _Ptr, class _Ct, class _Iterator,
00433 class _CIterator, class _Te>
00434 inline _Tp*
00435 value_type(const _LDG_iterator<_Tp,_Ref,_Ptr,_Ctr,_Iterator,_CIterator,_Te>&)
00436 {
00437 return 0;
00438 }
00439
00440
00441
00442
00443
00444 template <class _Tp, class _Ref, class _Ptr, class _Ctr, class _Iterator,
00445 class _CIterator, class _Te>
00446 inline ptrdiff_t*
00447 distance_type(const _LDG_iterator<_Tp,_Ref,_Ptr,_Ctr,_Iterator,_CIterator,_Te>&)
00448 {
00449 return 0;
00450 }
00451
00452 #endif
00453
00454
00455
00456
00457
00458 template <class _Tp, class _Ref, class _Ptr, class _Ctr, class _Iterator,
00459 class _CIterator, class _Te>
00460 void
00461 _LDG_iterator<_Tp,_Ref,_Ptr,_Ctr,_Iterator,_CIterator,_Te>::find_start_node()
00462 {
00463 _Node* __s = _C_i_cur;
00464 _Ctr_iterator __help;
00465
00466 while(!__s->_C_parents.empty())
00467 {
00468 __help = ((_Node*)*__s->_C_parents.begin());
00469 _C_i_cur_it.insert(_C_i_cur_it.begin(),
00470 __help->get_entry_iterator((void*)__s));
00471 __s = __help;
00472 }
00473 while(!_C_i_cur->_C_children.empty())
00474 {
00475
00476 for(__help = _C_i_cur->_C_children.begin();
00477 __help != _C_i_cur->_C_children.end(); ++__help)
00478 {
00479 __s = (_Node*)*__help;
00480 if(*(__s->_C_parents.begin()) == (void*)_C_i_cur)
00481 break;
00482 }
00483 if(__help == _C_i_cur->_C_children.end())
00484 break;
00485 _C_i_cur = __s;
00486 _C_i_cur_it.push_back(__help);
00487 }
00488 if(_C_i_cur->_C_children.empty())
00489 {
00490 __help = _C_i_cur_it.back();
00491 _C_i_cur_it.pop_back();
00492 _C_i_cur = (_Node*)*__help;
00493 }
00494 }
00495
00496
00497
00498
00499
00500 template <class _Tp, class _Ref, class _Ptr, class _Ctr, class _Iterator,
00501 class _CIterator, class _Te>
00502 void
00503 _LDG_iterator<_Tp,_Ref,_Ptr,_Ctr,_Iterator,_CIterator,_Te>::find_next_node()
00504 {
00505 if(!_C_i_cur->_C_parents.empty())
00506 {
00507 _Ctr_iterator __help(_C_i_cur_it.back());
00508 _Node* __par;
00509
00510 _C_i_cur_it.pop_back();
00511 __par = (_Node*)*(_C_i_cur->_C_parents.begin());
00512
00513 for(++__help; __help != __par->_C_children.end(); ++__help)
00514 {
00515 _Node* __s = (_Node*)*__help;
00516 if(*(__s->_C_parents.begin()) == (void*)_C_i_cur)
00517 {
00518 _C_i_cur_it.push_back(__help);
00519 _C_i_cur = __s;
00520 while(!_C_i_cur->_C_children.empty());
00521 {
00522 for(__help = _C_i_cur->_C_children.begin();
00523 __help != _C_i_cur->_C_children.end(); ++__help)
00524 {
00525 __s = (_Node*)*__help;
00526 if(*(__s->_C_parents.begin()) == (void*)_C_i_cur)
00527 break;
00528 }
00529 if(__help == _C_i_cur->_C_children.end())
00530 break;
00531 _C_i_cur = __s;
00532 _C_i_cur_it.push_back(__help);
00533 }
00534 break;
00535 }
00536 }
00537 if(__help == __par->_C_children.end())
00538 {
00539 _C_i_cur = __par;
00540 }
00541 else if(_C_i_cur->_C_children.empty())
00542 {
00543 __help = _C_i_cur_it.back();
00544 _C_i_cur_it.pop_back();
00545 _C_i_cur = (_Node*)*__help;
00546 }
00547 }
00548 }
00549
00550
00551
00552
00553 template <class _Tp, class _Ref, class _Ptr, class _Ctr, class _Iterator,
00554 class _CIterator, class _Te>
00555 void
00556 _LDG_iterator<_Tp,_Ref,_Ptr,_Ctr,_Iterator,_CIterator,_Te>::find_prev_node()
00557 {
00558 #if 0
00560 _Ctr_iterator help;
00561
00562 if(_C_i_cur->_C_children.empty())
00563 {
00564 while(1)
00565 {
00566 if(_C_i_cur->_C_parent == NULL)
00567 break;
00568 help = _C_i_cur_it.back();
00569 _C_i_cur_it.pop_back();
00570 _C_i_cur = (_Node*)_C_i_cur->_C_parent;
00571 if(help != _C_i_cur->_C_children.begin())
00572 {
00573 --help;
00574 _C_i_cur_it.push_back(help);
00575 _C_i_cur = (_Node*)*help;
00576 break;
00577 }
00578 }
00579 }
00580 else
00581 {
00582 help = _C_i_cur->_C_children.end();
00583 --help;
00584 _C_i_cur_it.push_back(help);
00585 _C_i_cur = (_Node*)*help;
00586 }
00587 #endif
00588 }
00589
00591
00596 template <class _Tp, class _Te, class _Ctr, class _Iterator, class _CIterator,
00597 class _Inserter, class _NAlloc, class _EAlloc>
00598 class __LDG : public _LDG_base<_Tp, _Ctr, _Iterator, _CIterator, _Te, _NAlloc, _EAlloc>
00599 {
00600 public:
00601 typedef _Ctr container_type;
00602 typedef _Iterator out_iterator;
00603 typedef _Iterator in_iterator;
00604 typedef _CIterator out_const_iterator;
00605 typedef _CIterator in_const_iterator;
00606 typedef _Iterator children_iterator;
00607 typedef _Iterator parents_iterator;
00608 typedef _CIterator children_const_iterator;
00609 typedef _CIterator parents_const_iterator;
00610 typedef _Inserter container_insert_arg;
00611
00612 protected:
00613 typedef void* _Void_pointer;
00614 typedef _LDG_base<_Tp, container_type, out_iterator, out_const_iterator, _Te,
00615 _NAlloc, _EAlloc> _Base;
00616 typedef _LDG_node<_Tp, container_type, children_iterator> _Node;
00617 typedef _LDG_edge<_Tp, _Node> _Edge;
00618 typedef __LDG<_Tp,_Te,_Ctr,_Iterator,_CIterator,_Inserter,_NAlloc,_EAlloc> _Self;
00619 typedef std::pair<_Node*,_Node*> _RV_LDG;
00620 typedef _Iterator container_iterator;
00621 typedef _CIterator container_const_iterator;
00622
00623 public:
00625
00626 typedef _Tp value_type;
00627 typedef _Node node_type;
00628 typedef _Edge edge_type;
00629 typedef value_type* pointer;
00630 typedef const value_type* const_pointer;
00631 typedef value_type& reference;
00632 typedef const value_type& const_reference;
00633 typedef size_t size_type;
00634 typedef ptrdiff_t difference_type;
00636
00637 typedef typename _Base::node_allocator_type node_allocator_type;
00639 node_allocator_type get_node_allocator() const { return _Base::get_node_allocator(); }
00640
00641 typedef typename _Base::edge_allocator_type edge_allocator_type;
00643 edge_allocator_type get_edge_allocator() const { return _Base::get_edge_allocator(); }
00644
00645 public:
00647 typedef _LDG_iterator<_Tp,_Tp&,_Tp*,container_type,children_iterator,
00648 children_const_iterator,_Te> iterator;
00650 typedef _LDG_iterator<_Tp,const _Tp&,const _Tp*,container_type,
00651 children_iterator,children_const_iterator,_Te> const_iterator;
00652
00653 #ifdef __VGTL_CLASS_PARTIAL_SPECIALIZATION
00654
00655 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00657 typedef std::reverse_iterator<iterator> reverse_iterator;
00658 #else
00659
00660 typedef std::reverse_bidirectional_iterator<const_iterator,value_type,
00661 const_reference,difference_type>
00662 const_reverse_iterator;
00664 typedef std::reverse_bidirectional_iterator<iterator,value_type,reference,
00665 difference_type>
00666 reverse_iterator;
00667 #endif
00668
00670 typedef _LDG_walker<_Tp,_Tp&,_Tp*,container_type,children_iterator,
00671 children_const_iterator,_Te> walker;
00673 typedef _LDG_walker<_Tp,const _Tp&,const _Tp*,container_type,children_iterator,
00674 children_const_iterator,_Te> const_walker;
00675
00677
00679
00680
00681 protected:
00683 typedef std::pair<_RV_LDG, std::vector<enhanced_edge> > erased_part;
00684
00685 protected:
00686 #ifdef __VGTL_HAS_NAMESPACES
00687 using _Base::_C_ground;
00688 using _Base::_C_sky;
00689 using _Base::_C_mark;
00690 using _Base::_C_put_node;
00691 using _Base::_C_get_node;
00692 using _Base::_C_put_edge;
00693 using _Base::_C_get_edge;
00694 #endif
00695
00696 protected:
00698 _Node* _C_create_node(const _Tp& __x)
00699 {
00700 _Node* __p = _C_get_node();
00701 __p->_C_visited = 0;
00702 __VGTL_TRY {
00703 __p->_C_data = new _Tp(__x);
00704 std::_Construct(&__p->_C_out_edges);
00705 std::_Construct(&__p->_C_in_edges);
00706 }
00707 __VGTL_UNWIND(_C_put_node(__p));
00708 return __p;
00709 }
00710
00712 _Node* _C_create_node()
00713 {
00714 _Node* __p = _C_get_node();
00715 __p->_C_visited = 0;
00716 __VGTL_TRY {
00717 __p->_C_data = new _Tp;
00718 std::_Construct(&__p->_C_out_edges);
00719 std::_Construct(&__p->_C_in_edges);
00720 }
00721 __VGTL_UNWIND(_C_put_node(__p));
00722 return __p;
00723 }
00724
00726 _Edge* _C_create_edge(const _Te& __x)
00727 {
00728 _Edge* __p = _C_get_edge();
00729 __VGTL_TRY {
00730 __p->_E_data = new _Te(__x);
00731 }
00732 __VGTL_UNWIND(_C_put_edge(__p));
00733 __p->_E_snode = __p->_E_tnode = NULL;
00734 return __p;
00735 }
00736
00738 _Edge* _C_create_edge()
00739 {
00740 _Edge* __p = _C_get_edge();
00741 __VGTL_TRY {
00742 __p->_E_data = new _Te;
00743 }
00744 __VGTL_UNWIND(_C_put_edge(__p));
00745 __p->_E_snode = __p->_E_tnode = NULL;
00746 return __p;
00747 }
00748
00751 _Edge* _C_create_edge(const _Te& __x, _Node* __s, _Node* __t)
00752 {
00753 _Edge* __p = _C_get_edge();
00754 __p->_C_visited = 0;
00755 __VGTL_TRY {
00756 __p->_C_data = new _Te(__x);
00757 }
00758 __VGTL_UNWIND(_C_put_edge(__p));
00759 __p->_E_snode = __s;
00760 __p->_E_tnode = __t;
00761 return __p;
00762 }
00763
00766 _Edge* _C_create_edge(_Node* __s, _Node* __t)
00767 {
00768 _Edge* __p = _C_get_edge();
00769 __p->_C_visited = 0;
00770 __VGTL_TRY {
00771 __p->_C_data = new _Te;
00772 }
00773 __VGTL_UNWIND(_C_put_edge(__p));
00774 __p->_E_snode = __s;
00775 __p->_E_tnode = __t;
00776 return __p;
00777 }
00778
00779 public:
00781 explicit __LDG(const allocator_type& __a = allocator_type()) : _Base(__a) {}
00782
00784 walker ground()
00785 { walker __help(this->_C_ground);
00786 return __help; }
00787
00789 walker sky()
00790 { walker __help(this->_C_sky);
00791 return __help; }
00792
00794 const_walker ground() const
00795 { const_walker __help(this->_C_ground);
00796 return __help; }
00797
00799 const_walker sky() const
00800 { const_walker __help(this->_C_sky);
00801 return __help; }
00802
00804
00805 out_iterator source_begin()
00806 { return this->_C_ground->_C_out_edges.begin(); }
00807 out_iterator root_begin() { return source_begin(); }
00809
00810
00811 out_iterator source_end()
00812 { return this->_C_ground->_C_out_edges.end(); }
00813 out_iterator root_end() { return source_end(); }
00815
00817
00818 out_const_iterator source_begin() const
00819 { return this->_C_ground->_C_out_edges.begin(); }
00820 out_iterator root_begin() { return source_begin(); }
00822
00823
00824 out_const_iterator source_end() const
00825 { return this->_C_ground->_C_out_edges.end(); }
00826 out_iterator root_end() { return source_end(); }
00828
00830
00831 in_iterator sink_begin()
00832 { return this->_C_sky->_C_in_edges.begin(); }
00833 in_iterator leaf_begin() { return sink_begin(); }
00835
00836
00837 in_iterator sink_end()
00838 { return this->_C_sky->_C_in_edges.end(); }
00839 in_iterator leaf_end() { return sink_end(); }
00841
00843
00844 in_const_iterator sink_begin() const
00845 { return this->_C_sky->_C_in_edges.begin(); }
00846 in_iterator leaf_begin() { return sink_begin(); }
00848
00849
00850 in_const_iterator sink_end() const
00851 { return this->_C_sky->_C_in_edges.end(); }
00852 in_iterator leaf_end() { return sink_end(); }
00854
00855 iterator begin()
00856 {
00857 iterator __help(this->_C_ground);
00858 return __help;
00859 }
00860 const_iterator begin() const
00861 {
00862 const_iterator __help(this->_C_ground);
00863 return __help;
00864 }
00865
00866 iterator end()
00867 {
00868 iterator __help(this->_C_sky);
00869 return --__help;
00870 }
00871 const_iterator end() const
00872 {
00873 const_iterator __help(this->_C_sky);
00874 return --__help;
00875 }
00876
00877 reverse_iterator rbegin()
00878 { return reverse_iterator(end()); }
00879 reverse_iterator rend()
00880 { return reverse_iterator(begin()); }
00881
00882 const_reverse_iterator rbegin() const
00883 { return const_reverse_iterator(end()); }
00884 const_reverse_iterator rend() const
00885 { return const_reverse_iterator(begin()); }
00886
00888 bool empty() const
00889 { return (*((*this->_C_ground)._C_out_edges.begin())).target() == this->_C_sky; }
00890
00892 size_type size() const {
00893 size_type __result = 0;
00894 distance(begin(), end(), __result);
00895 return __result;
00896 }
00897
00899 size_type max_size() const { return size_type(-1); }
00900
00902 void swap(_Self& __x)
00903 { __STD::swap(this->_C_ground, __x._C_ground);
00904 __STD::swap(this->_C_sky, __x._C_sky);
00905 __STD::swap(_C_mark, __x._C_mark); }
00906
00912 walker insert_node_in_graph(_Node* __n, const walker& __parent,
00913 const walker& __child,
00914 const container_insert_arg& __Itc,
00915 const container_insert_arg& __Itp)
00916 { __parent._C_w_cur->_C_children.insert(__Itc, (void*)__n);
00917 __child._C_w_cur->_C_parents.insert(__Itp, (void*)__n);
00918 __n->_C_children.push_back((void*)__child._C_w_cur);
00919 __n->_C_parents.push_back((void*)__parent._C_w_cur);
00920 return walker(__n);
00921 }
00922
00928 walker insert_in_graph(const _Tp& __x, const walker& __parent,
00929 const walker& __child,
00930 const container_insert_arg& __Itc,
00931 const container_insert_arg& __Itp)
00932 {
00933 _Node* __tmp = _C_create_node(__x);
00934 return insert_node_in_graph(__tmp, __parent, __child, __Itc, __Itp);
00935 }
00936
00942 walker insert_in_graph(const walker& __parent,
00943 const walker& __child,
00944 const container_insert_arg& __Itc,
00945 const container_insert_arg& __Itp)
00946 { return insert_in_graph(_Tp(), __parent, __child, __Itc, __Itp); }
00947
00953 void insert_subgraph(_Self& __subgraph,
00954 const walker& __parent,
00955 const walker& __child,
00956 const container_insert_arg& __Itc,
00957 const container_insert_arg& __Itp)
00958 {
00959 __subgraph.add_all_children(inserter(__parent._C_w_cur->_C_children,
00960 __Itc), __parent._C_w_cur);
00961 __subgraph.add_all_parents(inserter(__child._C_w_cur->_C_parents,
00962 __Itp), __child._C_w_cur);
00963 __subgraph.clear_children();
00964 __subgraph.clear_parents();
00965 }
00966
00967 #ifdef __VGTL_MEMBER_TEMPLATES
00968
00972 template <template <class __Tp, class __AllocTp> class __SequenceCtr1,
00973 template <class __Tp, class __AllocTp> class __SequenceCtr2,
00974 class _Allocator1, class _Allocator2>
00975 walker insert_node_in_graph(_Node* __node,
00976 const __SequenceCtr1<walker,_Allocator1>& __parents,
00977 const __SequenceCtr2<walker,_Allocator2>& __children)
00978 {
00979 typedef typename __SequenceCtr1<walker,_Allocator1>::const_iterator
00980 _Sequ_itp;
00981 typedef typename __SequenceCtr2<walker,_Allocator2>::const_iterator
00982 _Sequ_itc;
00983
00984 for(_Sequ_itp __b = __parents.begin(); __b != __parents.end(); ++__b)
00985 {
00986 __node->_C_parents.insert(__node->_C_parents.end(), (void*)(*__b).node());
00987 (*__b)._C_w_cur->_C_children.insert((*__b)._C_w_cur->_C_children.end(),
00988 (void*)__node);
00989 }
00990 for(_Sequ_itc __b = __children.begin(); __b != __children.end(); ++__b)
00991 {
00992 __node->_C_children.insert(__node->_C_children.end(), (void*)(*__b).node());
00993 (*__b)._C_w_cur->_C_parents.insert((*__b)._C_w_cur->_C_parents.end(),
00994 (void*)__node);
00995 }
00996 return walker(__node);
00997 }
00998
01003 template <template <class __Tp, class __AllocTp> class __SequenceCtr1,
01004 template <class __Tp, class __AllocTp> class __SequenceCtr2,
01005 class _Allocator1, class _Allocator2>
01006 walker insert_in_graph(const _Tp& __x,
01007 const __SequenceCtr1<walker,_Allocator1>& __parents,
01008 const __SequenceCtr2<walker,_Allocator2>& __children)
01009 {
01010 _Node* __tmp = _C_create_node(__x);
01011 return insert_node_in_graph(__tmp, __parents, __children);
01012 }
01013
01018 template <template <class __Tp, class __AllocTp> class __SequenceCtr1,
01019 template <class __Tp, class __AllocTp> class __SequenceCtr2,
01020 class _Allocator1, class _Allocator2>
01021 walker insert_in_graph(const __SequenceCtr1<walker,_Allocator1>& __parents,
01022 const __SequenceCtr2<walker,_Allocator2>& __children)
01023 {
01024 _Node* __tmp = _C_create_node();
01025 return insert_node_in_graph(__tmp, __parents, __children);
01026 }
01027
01032 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
01033 class _Allocator>
01034 walker insert_node_in_graph(_Node* __node, const walker& __parent,
01035 const container_insert_arg& __pref,
01036 const __SequenceCtr<walker,_Allocator>& __children)
01037 {
01038 typedef typename __SequenceCtr<walker,_Allocator>::const_iterator _Sequ_it;
01039 _Sequ_it __b;
01040
01041 __node->_C_parents.insert(__node->_C_parents.end(), (void*)__parent._C_w_cur);
01042 __parent._C_w_cur->_C_children.insert(__pref, (void*)__node);
01043 for(__b = __children.begin(); __b != __children.end(); ++__b)
01044 {
01045 __node->_C_children.insert(__node->_C_children.end(),
01046 (void*)(*__b)._C_w_cur);
01047 (*__b)._C_w_cur->_C_parents.insert((*__b)._C_w_cur->_C_parents.end(),
01048 (void*)__node);
01049 }
01050 return walker(__node);
01051 }
01052
01057 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
01058 class _Allocator>
01059 walker insert_in_graph(const _Tp& __x, const walker& __parent,
01060 const container_insert_arg& __pref,
01061 const __SequenceCtr<walker,_Allocator>& __children)
01062 {
01063 _Node* __tmp = _C_create_node(__x);
01064 return insert_node_in_graph(__tmp, __parent, __pref, __children);
01065 }
01066
01071 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
01072 class _Allocator>
01073 walker insert_in_graph(const walker& __parent,
01074 const container_insert_arg& __pref,
01075 const __SequenceCtr<walker,_Allocator>& __children)
01076 {
01077 _Node* __tmp = _C_create_node();
01078 return insert_node_in_graph(__tmp, __parent, __pref, __children);
01079 }
01080
01085 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
01086 class _Allocator>
01087 walker insert_node_in_graph(_Node* __node,
01088 const __SequenceCtr<walker,_Allocator>& __parents,
01089 const walker& __child,
01090 const container_insert_arg& __cref)
01091 {
01092 typedef typename __SequenceCtr<walker,_Allocator>::const_iterator _Sequ_it;
01093 _Sequ_it __b;
01094
01095 __node->_C_children.insert(__node->_C_children.end(), (void*)__child.node());
01096 __child._C_w_cur->_C_parents.insert(__cref, (void*)__node);
01097 for(__b = __parents.begin(); __b != __parents.end(); ++__b)
01098 {
01099 __node->_C_parents.insert(__node->_C_parents.end(), (void*)(*__b).node());
01100 (*__b)._C_w_cur->_C_children.insert((*__b)._C_w_cur->_C_children.end(),
01101 (void*)__node);
01102 }
01103 return walker(__node);
01104 }
01105
01110 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
01111 class _Allocator>
01112 walker insert_in_graph(const _Tp& __x,
01113 const __SequenceCtr<walker,_Allocator>& __parents,
01114 const walker& __child,
01115 const container_insert_arg& __cref)
01116 {
01117 _Node* __tmp = _C_create_node(__x);
01118 return insert_node_in_graph(__tmp, __parents, __child, __cref);
01119 }
01120
01125 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
01126 class _Allocator>
01127 walker insert_in_graph(const __SequenceCtr<walker,_Allocator>& __parents,
01128 const walker& __child,
01129 const container_insert_arg& __cref)
01130 {
01131 _Node* __tmp = _C_create_node();
01132 return insert_node_in_graph(__tmp, __parents, __child, __cref);
01133 }
01134
01138 template <template <class __Tp, class __AllocTp> class __SequenceCtr1,
01139 template <class __Tp, class __AllocTp> class __SequenceCtr2,
01140 class _Allocator1, class _Allocator2>
01141 void insert_subgraph(_Self& __subgraph,
01142 const __SequenceCtr1<walker,_Allocator1>& __parents,
01143 const __SequenceCtr2<walker,_Allocator2>& __children)
01144 {
01145 typedef typename __SequenceCtr1<walker,_Allocator1>::const_iterator
01146 _Sequ_itp;
01147 typedef typename __SequenceCtr2<walker,_Allocator2>::const_iterator
01148 _Sequ_itc;
01149 _Sequ_itp __sitp;
01150 _Sequ_itc __sitc;
01151 children_iterator __b;
01152 walker __wb;
01153 _Node* __n;
01154
01155 __sitp = __parents.begin();
01156 for(__b = __subgraph._C_ground->_C_children.begin();
01157 __b != __subgraph._C_ground->_C_children.end();
01158 ++__b)
01159 {
01160 if(__sitp == __parents.end())
01161 __wb = (*this)._C_ground;
01162 else
01163 __wb = *__sitp++;
01164 __n = __wb.node();
01165 __n->_C_children.insert(__n->_C_children.end(), *__b);
01166 ((_Node*)*__b)->_C_parents.insert(((_Node*)*__b)->_C_parents.end(),
01167 (void*)__n);
01168 }
01169 __sitc = __children.begin();
01170 for(__b = __subgraph._C_sky->_C_parents.begin();
01171 __b != __subgraph._C_sky->_C_parents.end();
01172 ++__b)
01173 {
01174 if(__sitc == __children.end())
01175 __wb = (*this)._C_sky;
01176 else
01177 __wb = *__sitc++;
01178 __n = __wb.node();
01179 __n->_C_parents.insert(__n->_C_parents.end(), *__b);
01180 ((_Node*)*__b)->_C_children.insert(((_Node*)*__b)->_C_children.end(),
01181 (void*)__n);
01182 }
01183 __subgraph.clear_children();
01184 __subgraph.clear_parents();
01185 }
01186 #endif
01187
01191 void add_edge(const edge& __edge,
01192 const container_insert_arg& __Itc,
01193 const container_insert_arg& __Itp)
01194 { add_edge(__edge.first, __edge.second, __Itc, __Itp); }
01195
01200 void add_edge(const walker& __parent, const walker& __child,
01201 const container_insert_arg& __Itc,
01202 const container_insert_arg& __Itp)
01203 {
01204 int do_remove(0);
01205 if(__parent._C_w_cur->_C_children.size() == 1)
01206 {
01207 container_iterator __it;
01208 __it = __parent._C_w_cur->_C_children.begin();
01209 if(*__it == (void*)this->_C_sky)
01210 do_remove += 1;
01211 }
01212 if(__child._C_w_cur->_C_parents.size() == 1)
01213 {
01214 container_iterator __it;
01215 __it = __child._C_w_cur->_C_parents.begin();
01216 if(*__it == (void*)this->_C_ground)
01217 do_remove += 2;
01218 }
01219 __parent._C_w_cur->_C_children.insert(__Itc, (void*)__child._C_w_cur);
01220 __child._C_w_cur->_C_parents.insert(__Itp, (void*)__parent._C_w_cur);
01221 if(do_remove & 1)
01222 {
01223 container_iterator __it;
01224 __it = __parent._C_w_cur->get_childentry_iterator((void*)this->_C_sky);
01225 __parent._C_w_cur->_C_children.erase(__it);
01226 __it = this->_C_sky->get_parententry_iterator((void*)__parent._C_w_cur);
01227 this->_C_sky->_C_parents.erase(__it);
01228 }
01229 if(do_remove & 2)
01230 {
01231 container_iterator __it;
01232 __it = __child._C_w_cur->get_parententry_iterator((void*)this->_C_ground);
01233 __child._C_w_cur->_C_parents.erase(__it);
01234 __it = this->_C_ground->get_childentry_iterator((void*)__child._C_w_cur);
01235 this->_C_ground->_C_children.erase(__it);
01236 }
01237 }
01238
01243 void replace_edge_to_child(const walker& __parent,
01244 const walker& __child_old,
01245 const walker& __child_new)
01246 { container_iterator __it;
01247 __it = __parent._C_w_cur->get_childentry_iterator((void*) __child_old._C_w_cur);
01248 if(__it == __parent._C_w_cur->_C_children.end())
01249 return;
01250 (*__it) = (void*) __child_new._C_w_cur;
01251 __it = __child_old._C_w_cur->get_parententry_iterator((void*) __parent._C_w_cur);
01252 if(__it == __child_old._C_w_cur->_C_parents.end())
01253 return;
01254 __child_old._C_w_cur->_C_parents.erase(__it);
01255 if(__child_old._C_w_cur->_C_parents.empty())
01256 {
01257 __child_old._C_w_cur->_C_parents.insert(
01258 __child_old._C_w_cur->_C_parents.end(), (void*)this->_C_ground);
01259 this->_C_ground->_C_children.insert(this->_C_ground->_C_children.end(),
01260 (void*)__child_old._C_w_cur);
01261 }
01262 if(__child_new._C_w_cur->_C_parents.size() == 1)
01263 {
01264 if(*__child_new._C_w_cur->_C_parents.begin() == (void*)this->_C_ground)
01265 {
01266 __it = this->_C_ground->get_childentry_iterator((void*) __child_new._C_w_cur);
01267 if(__it != this->_C_ground->_C_children.end())
01268 this->_C_ground->_C_children.erase(__it);
01269 __child_new._C_w_cur->_C_parents.erase(__child_new._C_w_cur->
01270 _C_parents.begin());
01271 }
01272 }
01273 __child_new._C_w_cur->_C_parents.insert(
01274 __child_new._C_w_cur->_C_parents.end(), (void*)__parent._C_w_cur);
01275 }
01276
01281 void replace_edge_to_parent(const walker& __parent_old,
01282 const walker& __parent_new, const walker& __child)
01283 { container_iterator __it;
01284 __it = __child._C_w_cur->get_parententry_iterator((void*) __parent_old._C_w_cur);
01285 if(__it == __child._C_w_cur->_C_parents.end())
01286 return;
01287 (*__it) = (void*) __parent_new._C_w_cur;
01288 __it = __parent_old._C_w_cur->get_childentry_iterator((void*) __child._C_w_cur);
01289 if(__it == __parent_old._C_w_cur->_C_children.end())
01290 return;
01291 __parent_old._C_w_cur->_C_children.erase(__it);
01292 if(__parent_old._C_w_cur->_C_children.empty())
01293 {
01294 __parent_old._C_w_cur->_C_children.insert(
01295 __parent_old._C_w_cur->_C_children.end(), (void*)this->_C_sky);
01296 this->_C_sky->_C_parents.insert(this->_C_sky->_C_parents.end(),
01297 (void*)__parent_old._C_w_cur);
01298 }
01299 if(__parent_new._C_w_cur->_C_children.size() == 1)
01300 {
01301 if(*__parent_new._C_w_cur->_C_children.begin() == (void*)this->_C_sky)
01302 {
01303 __it = this->_C_sky->get_parententry_iterator((void*) __parent_new._C_w_cur);
01304 if(__it != this->_C_sky->_C_parents.end())
01305 this->_C_sky->_C_parents.erase(__it);
01306 __parent_new._C_w_cur->_C_children.erase(__parent_new._C_w_cur->
01307 _C_children.begin());
01308 }
01309 }
01310 __parent_new._C_w_cur->_C_children.insert(
01311 __parent_new._C_w_cur->_C_children.end(), (void*)__child._C_w_cur);
01312 }
01313
01315 void remove_edge(const edge& __edge)
01316 { remove_edge(__edge.first, __edge.second); }
01317
01319 void remove_edge_and_deattach(const walker& __parent, const walker& __child)
01320 { container_iterator __it;
01321 __it = __parent._C_w_cur->get_childentry_iterator((void*) __child._C_w_cur);
01322 if(__it == __parent._C_w_cur->_C_children.end())
01323 return;
01324 __parent._C_w_cur->_C_children.erase(__it);
01325 __it = __child._C_w_cur->get_parententry_iterator((void*) __parent._C_w_cur);
01326 if(__it == __child._C_w_cur->_C_parents.end())
01327 return;
01328 __child._C_w_cur->_C_parents.erase(__it);
01329 }
01330
01332 void remove_edge(const walker& __parent, const walker& __child)
01333 {
01334 remove_edge_and_deattach(__parent, __child);
01335
01336
01337
01338 if(__parent._C_w_cur->_C_children.empty())
01339 {
01340 __parent._C_w_cur->_C_children.insert(
01341 __parent._C_w_cur->_C_children.end(), (void*)this->_C_sky);
01342 this->_C_sky->_C_parents.insert(this->_C_sky->_C_parents.end(),
01343 (void*)__parent._C_w_cur);
01344 }
01345 if(__child._C_w_cur->_C_parents.empty())
01346 {
01347 __child._C_w_cur->_C_parents.insert(
01348 __child._C_w_cur->_C_parents.end(), (void*)this->_C_ground);
01349 this->_C_ground->_C_children.insert(this->_C_ground->_C_children.end(),
01350 (void*)__child._C_w_cur);
01351 }
01352 }
01353
01355 template <class Compare>
01356 void sort_child_edges(walker __position, children_iterator first,
01357 children_iterator last, Compare comp)
01358 { (*__position._C_w_cur).sort_child_edges(first, last, comp); }
01359
01361 template <class Compare>
01362 void sort_parent_edges(walker __position, parents_iterator first,
01363 parents_iterator last, Compare comp)
01364 { (*__position._C_w_cur).sort_parent_edges(first, last, comp); }
01365
01367 template <class Compare>
01368 void sort_child_edges(walker __position, Compare comp)
01369 { (*__position._C_w_cur).sort_child_edges(__position.child_begin(),
01370 __position.child_end(), comp); }
01371
01373 template <class Compare>
01374 void sort_parent_edges(walker __position, Compare comp)
01375 { (*__position._C_w_cur).sort_parent_edges(__position.parent_begin(),
01376 __position.parent_end(), comp); }
01377
01379 walker insert_node(_Node* _node, const walker& __position,
01380 const container_insert_arg& __It)
01381 { if(__position.sky())
01382 return;
01383 __position._C_w_cur->add_all_children(
01384 inserter(_node->_C_children, __It), _node);
01385 __position._C_w_cur->clear_children();
01386 __position._C_w_cur->_C_children.insert(
01387 __position._C_w_cur->_C_children.end(), _node);
01388 _node->_C_parents.insert(_node->_C_parents.end(),__position._C_w_cur);
01389 return walker(_node);
01390 }
01391
01393 walker insert_node(const _Tp& __x, const walker& __position,
01394 const container_insert_arg& __It)
01395 { return insert_node(_C_create_node(__x), __position, __It); }
01396
01397
01399 walker insert_node(const walker& __position,
01400 const container_insert_arg& __It)
01401 { return insert_node(_Tp(), __position, __It); }
01402
01404 walker insert_node_before(_Node* _node, const walker& __position,
01405 const container_insert_arg& __It)
01406 { if(__position.ground())
01407 return;
01408 __position._C_w_cur->add_all_parents(
01409 back_inserter(_node->_C_parents), _node);
01410 __position._C_w_cur->clear_parents();
01411 __position._C_w_cur->_C_parents.insert(
01412 __position._C_w_cur->_C_parents.end(), _node);
01413 _node->_C_children.push_back(__position.C_w_cur);
01414 return walker(_node);
01415 }
01416
01418 void insert_node_before(const _Tp& __x, const walker& __position,
01419 const container_insert_arg& __It)
01420 { return insert_node_before(_C_create_node(__x), __position, __It); }
01421
01423 void insert_node_before(const walker& __position,
01424 const container_insert_arg& __It)
01425 { return insert_node_before(_Tp(), __position, __It); }
01426
01427
01429 void merge(const walker& __position, const walker& __second,
01430 bool merge_parent_edges = true, bool merge_child_edges = true)
01431 { _Node* __tp = __position._C_w_cur;
01432 _Node* __ts = __second._C_w_cur;
01433 _Node* __p;
01434
01435 if(__position.is_sky() || __position.is_ground() ||
01436 __second.is_sky() || __second.is_ground() ||
01437 __position == __second)
01438
01439 return;
01440
01441 container_iterator __i, __j;
01442 bool mrg_it;
01443 bool __is_root = __position.is_root();
01444 bool __is_leaf = __position.is_leaf();
01445
01446 for(__i = __ts->_C_children.begin();
01447 __i != __ts->_C_children.end(); ++__i)
01448 {
01449 mrg_it = 0;
01450 __p = (_Node*)*__i;
01451 if(merge_child_edges)
01452 {
01453 for(__j = __tp->_C_children.begin();
01454 __j != __tp->_C_children.end(); ++__j)
01455 {
01456 if(*__i == *__j)
01457 {
01458 mrg_it = 1;
01459 break;
01460 }
01461 }
01462 }
01463 __j = __p->get_parententry_iterator(__ts);
01464 if(__p == this->_C_sky || mrg_it)
01465 __p->_C_parents.erase(__j);
01466 else
01467 *__j = (void *)__tp;
01468 if(!mrg_it && __p != this->_C_sky)
01469 __tp->_C_children.insert(__tp->_C_children.end(), (void*)__p);
01470 }
01471 if(__is_leaf && __tp->_C_children.size() > 1)
01472 {
01473 __j = this->_C_sky->get_parententry_iterator(__tp);
01474 this->_C_sky->_C_parents.erase(__j);
01475 __j = __tp->get_childentry_iterator(this->_C_sky);
01476 __tp->_C_children.erase(__j);
01477 }
01478 for(__i = __ts->_C_parents.begin();
01479 __i != __ts->_C_parents.end(); ++__i)
01480 {
01481 mrg_it = 0;
01482 __p = (_Node*)*__i;
01483 if(merge_parent_edges)
01484 {
01485 for(__j = __tp->_C_parents.begin();
01486 __j != __tp->_C_parents.end(); ++__j)
01487 {
01488 if(*__i == *__j)
01489 {
01490 mrg_it = 1;
01491 break;
01492 }
01493 }
01494 }
01495 __j = __p->get_childentry_iterator(__ts);
01496 if(__p == this->_C_ground || mrg_it)
01497 __p->_C_children.erase(__j);
01498 else
01499 *__j = (void *)__tp;
01500 if(!mrg_it && __p != this->_C_ground)
01501 __tp->_C_parents.insert(__tp->_C_parents.end(), (void*)__p);
01502 }
01503 if(__is_root && __tp->_C_parents.size() > 1)
01504 {
01505 __j = this->_C_ground->get_childentry_iterator(__tp);
01506 this->_C_ground->_C_children.erase(__j);
01507 __j = __tp->get_parententry_iterator(this->_C_ground);
01508 __tp->_C_parents.erase(__j);
01509 }
01510
01511 (__tp->_C_data).merge(__ts->_C_data);
01512 __ts->clear_children();
01513 __ts->clear_parents();
01514 _C_put_node(__ts);
01515 }
01516
01518 void erase(const walker& __position)
01519 { _Node* __tmp = __position._C_w_cur;
01520
01521 if(!__tmp->_C_children.empty() && !__tmp->_C_parents.empty())
01522 {
01523 container_iterator __ip, __ic;
01524 _Node* __p;
01525 bool do_it;
01526
01527 do_it = !__position.is_leaf();
01528 for(__ip = __tmp->_C_parents.begin();
01529 __ip != __tmp->_C_parents.end(); ++__ip)
01530 {
01531 __p = (_Node*)*__ip;
01532 __ic = __p->get_childentry_iterator(__tmp);
01533 ++__ic;
01534 if(__position.is_root())
01535 {
01536 for(container_iterator __icc = __tmp->_C_children.begin();
01537 __icc != __tmp->_C_children.end(); ++__icc)
01538 {
01539 _Node* __c = (_Node*)*__icc;
01540 if(__c->_C_parents.size() == 1)
01541 {
01542 __c->_C_parents.insert(__c->_C_parents.end(), (void*)__p);
01543 __p->_C_children.insert(__ic, (void*)__c);
01544 ++__ic;
01545 }
01546 }
01547 }
01548 else if(do_it || __p->_C_children.size() == 1)
01549 __tmp->add_all_children(inserter(__p->_C_children, __ic), __p);
01550
01551
01552
01553
01554 __ic = __p->get_childentry_iterator(__tmp);
01555 __p->_C_children.erase(__ic);
01556 if(__p->_C_children.empty())
01557 __p->_C_children.insert(__p->_C_children.end(),
01558 (void*) this->_C_sky);
01559 }
01560 for(__ic = __tmp->_C_children.begin();
01561 __ic != __tmp->_C_children.end(); ++__ic)
01562 {
01563 __p = (_Node*)*__ic;
01564 __ip = __p->get_parententry_iterator(__tmp);
01565 __p->_C_parents.erase(__ip);
01566 if(__p->_C_parents.empty())
01567 __p->_C_parents.insert(__p->_C_parents.end(),
01568 (void*) this->_C_ground);
01569 }
01570 __tmp->clear_parents();
01571 __tmp->clear_children();
01572 _C_put_node(__tmp);
01573 }
01574 }
01575
01578 void partial_erase_to_parent(const walker& __position, const walker& __parent, unsigned int idx)
01579 { _Node* __tmp = __position._C_w_cur;
01580 _Node* __p = __parent._C_w_cur;
01581
01582 if(!__tmp->_C_children.empty() && !__tmp->_C_parents.empty())
01583 {
01584 container_iterator __ic;
01585 bool do_it;
01586
01587 do_it = !__position.is_leaf();
01588 __ic = __p->_C_children.begin()+idx;
01589 if(*__ic != (void*)__tmp)
01590 return;
01591 ++__ic;
01592 if(__position.is_root())
01593 {
01594 for(container_iterator __icc = __tmp->_C_children.begin();
01595 __icc != __tmp->_C_children.end(); ++__icc)
01596 {
01597 _Node* __c = (_Node*)*__icc;
01598 if(__c->_C_parents.size() == 1)
01599 {
01600 __c->_C_parents.insert(__c->_C_parents.end(), (void*)__p);
01601 __p->_C_children.insert(__ic, (void*)__c);
01602 ++__ic;
01603 }
01604 }
01605 }
01606 else if(do_it || __p->_C_children.size() == 1)
01607 __tmp->add_all_children(inserter(__p->_C_children, __ic), __p);
01608
01609
01610
01611
01612 __ic = __p->_C_children.begin()+idx;
01613 __p->_C_children.erase(__ic);
01614 if(__p->_C_children.empty())
01615 __p->_C_children.insert(__p->_C_children.end(),
01616 (void*) this->_C_sky);
01617
01618 parents_iterator __ip;
01619 __ip = __tmp->get_parententry_iterator((void*)__parent._C_w_cur);
01620 __tmp->_C_parents.erase(__ip);
01621
01622 if(__tmp->_C_parents.empty())
01623 {
01624 for(__ic = __tmp->_C_children.begin();
01625 __ic != __tmp->_C_children.end(); ++__ic)
01626 {
01627 __p = (_Node*)*__ic;
01628 __ip = __p->get_parententry_iterator(__tmp);
01629 __p->_C_parents.erase(__ip);
01630 if(__p->_C_parents.empty())
01631 __p->_C_parents.insert(__p->_C_parents.end(),
01632 (void*) this->_C_ground);
01633 }
01634 __tmp->clear_children();
01635 _C_put_node(__tmp);
01636 }
01637 }
01638 }
01639
01640
01641 private:
01643 void cut_excess_edges(const walker& __position, _Node* __ngrd, _Node* __nsky,
01644 bool maximal, bool upwards, std::vector<enhanced_edge>& __ev)
01645 {
01646 std::vector<walker> __v(1);
01647 __v[0] = __position;
01648 cut_excess_edges(__v, __ngrd, __nsky, maximal, upwards, __ev);
01649 }
01650
01652 bool parents_are_marked(int __mark, const walker& __pson)
01653 {
01654 parents_iterator _pit;
01655 const_walker __pr;
01656 walker __position(__pson);
01657
01658 for(_pit = __position.parent_begin(); _pit != __position.parent_end();
01659 ++_pit)
01660 {
01661 __pr = __position << _pit;
01662 if(__pr.node()->_C_visited < __mark && !__pr.is_ground())
01663 return false;
01664 }
01665 return true;
01666 }
01667
01669 bool children_are_marked(int __mark, const walker& __pson)
01670 {
01671 children_iterator _cit;
01672 const_walker __ch;
01673 walker __position(__pson);
01674
01675 for(_cit = __position.child_begin(); _cit != __position.child_end();
01676 ++_cit)
01677 {
01678 __ch = __position >> _cit;
01679 if(__ch.node()->_C_visited < __mark && !__ch.is_sky())
01680 return false;
01681 }
01682 return true;
01683 }
01684
01686 void dnrecursive_mark_node(int __mark, const walker& __pson,
01687 bool maximal)
01688 {
01689 children_iterator _cit;
01690 walker __position(__pson);
01691
01692 if(__position._C_w_cur->_C_visited == __mark ||
01693 __position.is_ground() || __position.is_sky())
01694 return;
01695 if(!maximal && !parents_are_marked(__mark, __position))
01696
01697
01698 return;
01699 __position._C_w_cur->_C_visited = __mark;
01700 for(_cit = __position.child_begin();
01701 _cit != __position.child_end(); ++_cit)
01702 dnrecursive_mark_node(__mark, __position>>_cit, maximal);
01703 }
01704
01706 void uprecursive_mark_node(int __mark, const walker& __pson,
01707 bool maximal)
01708 {
01709 walker __position(__pson);
01710 parents_iterator _pit;
01711
01712 if(__position._C_w_cur->_C_visited == __mark ||
01713 __position.is_ground() || __position.is_sky())
01714 return;
01715 if(!maximal && !children_are_marked(__mark, __position))
01716
01717
01718 return;
01719 __position._C_w_cur->_C_visited = __mark;
01720 for(_pit = __position.parent_begin();
01721 _pit != __position.parent_end(); ++_pit)
01722 dnrecursive_mark_node(__mark, __position<<_pit, maximal);
01723 }
01724
01726 void recursive_cut_edges(int __mark, const walker& __pson,
01727 _Node* __ngrd, _Node* __nsky, std::vector<enhanced_edge>& __ev)
01728
01729
01730 {
01731 children_iterator _cit;
01732 _Node* _h;
01733 walker _w;
01734 walker __position(__pson);
01735 edge _e;
01736 bool _rcf(false);
01737 std::list<children_iterator> _er_cit;
01738
01739 for(_cit = __position.child_begin(); _cit != __position.child_end(); ++_cit)
01740 {
01741 _h = (_Node*)(*_cit);
01742 _w = __position >> _cit;
01743 if((__position._C_w_cur->_C_visited == __mark && _h->_C_visited < __mark)
01744 ||(__position._C_w_cur->_C_visited < __mark && _h->_C_visited == __mark))
01745
01746
01747 {
01748 container_iterator __it;
01749
01750
01751 _e = make_pair(__position, _w);
01752
01753 _er_cit.push_back(_cit);
01754
01755 __it = _h->get_parententry_iterator((void*)__position._C_w_cur);
01756 if(__it != _h->_C_parents.end())
01757 _h->_C_parents.erase(__it);
01758 if(__position._C_w_cur->_C_visited == __mark)
01759
01760 {
01761
01762
01763
01764 if(_h->_C_parents.empty())
01765 {
01766 _h->_C_parents.insert(_h->_C_parents.end(), (void*)this->_C_ground);
01767 this->_C_ground->_C_children.insert(this->_C_ground->_C_children.end(),
01768 (void*)_h);
01769 _rcf = true;
01770 }
01771 else
01772 _rcf = false;
01773 }
01774 else
01775
01776 {
01777 if(_h->_C_parents.empty())
01778 {
01779 _h->_C_parents.insert(_h->_C_parents.end(), (void*)__ngrd);
01780 __ngrd->_C_children.insert(__ngrd->_C_children.end(), (void*)_h);
01781 }
01782 }
01783 __ev.push_back(make_pair(_e, _rcf));
01784 }
01785 recursive_cut_edges(__mark, _w, __ngrd, __nsky, __ev);
01786 }
01787 if(!_er_cit.empty())
01788 {
01789
01790
01791
01792
01793
01794 children_iterator _hit, _eit;
01795 typename std::list<children_iterator>::iterator _erc;
01796
01797 _erc = _er_cit.begin();;
01798 _eit = __position._C_w_cur->_C_children.end();
01799 for(_hit = _cit = __position._C_w_cur->_C_children.begin();
01800 _cit != _eit; ++_cit)
01801 {
01802 if(_cit == *_erc)
01803 ++_erc;
01804 else
01805 {
01806 if(_cit != _hit)
01807 *_hit = *_cit;
01808 ++_hit;
01809 }
01810 }
01811 __position._C_w_cur->_C_children.erase(_hit, _eit);
01812
01813 if(__position._C_w_cur->_C_visited == __mark)
01814 {
01815
01816 if(__position._C_w_cur->_C_children.empty())
01817 {
01818 __position._C_w_cur->_C_children.insert(
01819 __position._C_w_cur->_C_children.end(), (void*)__nsky);
01820 __nsky->_C_parents.insert(__nsky->_C_parents.end(),
01821 (void*)__position._C_w_cur);
01822 }
01823 }
01824 else
01825 {
01826
01827
01828
01829 if(__position._C_w_cur->_C_children.empty())
01830 {
01831 __position._C_w_cur->_C_children.insert(
01832 __position._C_w_cur->_C_children.end(), (void*)this->_C_sky);
01833 this->_C_sky->_C_parents.insert(this->_C_sky->_C_parents.end(),
01834 (void*)__position._C_w_cur);
01835 }
01836 }
01837 }
01838 }
01839
01840 #ifdef __VGTL_MEMBER_TEMPLATES
01842 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
01843 class _Allocator>
01844 void cut_excess_edges(const __SequenceCtr<walker,_Allocator>& __positions,
01845 _Node* __ngrd, _Node* __nsky, bool maximal,
01846 bool upwards, std::vector<enhanced_edge>& __ev)
01847 {
01848 int _actmark = ++_C_mark;
01849 typename __SequenceCtr<walker,_Allocator>::const_iterator _pit;
01850 walker _w;
01851
01852 for(_pit = __positions.begin(); _pit != __positions.end(); ++_pit)
01853 {
01854 _w = *_pit;
01855 _w._C_w_cur->_C_visited = _actmark;
01856 if(upwards)
01857 uprecursive_mark_node(_actmark, _w, maximal);
01858 else
01859 dnrecursive_mark_node(_actmark, _w, maximal);
01860 }
01861 recursive_cut_edges(_actmark, ground(), __ngrd, __nsky, __ev);
01862 }
01863 #endif
01864
01865
01866 public:
01868 void clear_erased_part(erased_part& _ep)
01869 {
01870 clear_graph(_ep.first.first);
01871 }
01872
01879 erased_part erase_maximal_subgraph(const walker& __position)
01880 { _RV_LDG __rv(_C_create_node(),_C_create_node());
01881 std::vector<enhanced_edge> __ev;
01882
01883 cut_excess_edges(__position, __rv.first, __rv.second, true, false,
01884 __ev);
01885 return make_pair(__rv,__ev);
01886 }
01887
01895 erased_part erase_minimal_subgraph(const walker& __position)
01896 { _RV_LDG __rv(_C_create_node(),_C_create_node());
01897 std::vector<enhanced_edge> __ev;
01898
01899 cut_excess_edges(__position, __rv.first, __rv.second, false, false,
01900 __ev);
01901 return make_pair(__rv,__ev);
01902 }
01903
01904 #ifdef __VGTL_MEMBER_TEMPLATES
01905
01911 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
01912 class _Allocator>
01913 erased_part erase_maximal_subgraph(
01914 const __SequenceCtr<walker,_Allocator>& __positions)
01915 { _RV_LDG __rv(_C_create_node(),_C_create_node());
01916 std::vector<enhanced_edge> __ev;
01917
01918 cut_excess_edges(__positions, __rv.first, __rv.second, true, false,
01919 __ev);
01920 return make_pair(__rv,__ev);
01921 }
01922
01931 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
01932 class _Allocator>
01933 erased_part erase_minimal_subgraph(
01934 const __SequenceCtr<walker,_Allocator>& __positions)
01935 { _RV_LDG __rv(_C_create_node(),_C_create_node());
01936 std::vector<enhanced_edge> __ev;
01937
01938 cut_excess_edges(__positions, __rv.first, __rv.second, false, false,
01939 __ev);
01940 return make_pair(__rv,__ev);
01941 }
01942 #endif
01943
01950 erased_part erase_maximal_pregraph(const walker& __position)
01951 { _RV_LDG __rv(_C_create_node(),_C_create_node());
01952 std::vector<enhanced_edge> __ev;
01953
01954 cut_excess_edges(__position, __rv.first, __rv.second, true, true,
01955 __ev);
01956 return make_pair(__rv,__ev);
01957 }
01958
01966 erased_part erase_minimal_pregraph(const walker& __position)
01967 { _RV_LDG __rv(_C_create_node(),_C_create_node());
01968 std::vector<enhanced_edge> __ev;
01969
01970 cut_excess_edges(__position, __rv.first, __rv.second, false, true,
01971 __ev);
01972 return make_pair(__rv,__ev);
01973 }
01974
01975 #ifdef __VGTL_MEMBER_TEMPLATES
01976
01982 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
01983 class _Allocator>
01984 erased_part erase_maximal_pregraph(
01985 const __SequenceCtr<walker,_Allocator>& __positions)
01986 { _RV_LDG __rv(_C_create_node(),_C_create_node());
01987 std::vector<enhanced_edge> __ev;
01988
01989 cut_excess_edges(__positions, __rv.first, __rv.second, true, true,
01990 __ev);
01991 return make_pair(__rv,__ev);
01992 }
01993
02002 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
02003 class _Allocator>
02004 erased_part erase_minimal_pregraph(
02005 const __SequenceCtr<walker,_Allocator>& __positions)
02006 { _RV_LDG __rv(_C_create_node(),_C_create_node());
02007 std::vector<enhanced_edge> __ev;
02008
02009 cut_excess_edges(__positions, __rv.first, __rv.second, false, true,
02010 __ev);
02011 return make_pair(__rv,__ev);
02012 }
02013 #endif
02014
02020 bool erase_child(const walker& __position,
02021 const children_iterator& __It)
02022 {
02023 _Node* __chld = (_Node*)*__It;
02024
02025 if(__chld->_C_children.size() != 1 || __chld->_C_parents.size() != 1)
02026 { return false; }
02027 else
02028 {
02029 _Node* __c2;
02030 parents_iterator __pit;
02031
02032 __c2 = (_Node*)*__chld->_C_children.begin();
02033 __pit = __c2->get_parententry_iterator((void*)__chld);
02034 *__pit = (void*)__position->_C_w_cur;
02035 *__It = (void*)__c2;
02036 _C_put_node(__chld);
02037 return true;
02038 }
02039 }
02040
02046 bool erase_parent(const walker& __position,
02047 const parents_iterator& __It)
02048 {
02049 _Node* __prnt = (_Node*)*__It;
02050
02051 if(__prnt->_C_children.size() != 1 || __prnt->_C_parents.size() != 1)
02052 { return false; }
02053 else
02054 {
02055 _Node* __p2;
02056 children_iterator __cit;
02057
02058 __p2 = (_Node*)*__prnt->_C_parents.begin();
02059 __cit = __p2->get_childentry_iterator((void*)__prnt);
02060 *__cit = (void*)__position->_C_w_cur;
02061 *__It = (void*)__p2;
02062 _C_put_node(__prnt);
02063 return true;
02064 }
02065 }
02066
02068 void clear() { _Base::clear(); }
02069
02070 private:
02075 _Node* copy_subgraph(_Node* __x, _Node* __par, std::map<_Node*,_Node*>& __nconn)
02076 { children_iterator cit;
02077 typedef typename std::map<_Node*,_Node*>::iterator map_it;
02078 std::pair<map_it,bool> _rv;
02079 _Node* __h = _C_create_node();
02080 _Node* __cs;
02081 map_it __cdit;
02082
02083 std::_Construct(&__h->_C_data, __x->_C_data);
02084 __h->_C_parents.insert(__h->_C_parents.end(), (void*)__par);
02085 __h->_C_visited = 0;
02086 if(__x->_C_parents.size() > 1)
02087 _rv = __nconn.insert(make_pair(__x,__h));
02088 for(cit = __x->_C_children.begin(); cit != __x->_C_children.end(); ++cit)
02089 {
02090 __cs = (_Node*)*cit;
02091 __cdit = __nconn.find(__cs);
02092 if(__cdit == __nconn.end())
02093 __h->_C_children.insert(__h->_C_children.end(),
02094 copy_subgraph(__cs, __h, __nconn));
02095 else
02096 {
02097 (*__cdit).second->_C_parents.insert(
02098 (*__cdit).second->_C_parents.end(), __h);
02099 __h->_C_children.insert(__h->_C_children.end(),
02100 (void*)(*__cdit).second);
02101 }
02102 }
02103 return __h;
02104 }
02105
02106 public:
02108 __LDG(const _Self& __x) : _Base(__x.get_allocator())
02109 { children_iterator cit;
02110 std::map<_Node*,_Node*> __nconn;
02111 __nconn.insert(make_pair(__x._C_sky, this->_C_sky));
02112 this->_C_mark = 0;
02113 this->_C_ground->clear_children();
02114 this->_C_sky->clear_parents();
02115 for(cit = __x._C_ground->_C_children.begin();
02116 cit != __x._C_ground->_C_children.end(); ++cit)
02117 {
02118 if((_Node*)*cit != __x._C_sky)
02119 this->_C_ground->_C_children.insert(this->_C_ground->_C_children.end(),
02120 copy_subgraph((_Node*)*cit, this->_C_ground, __nconn));
02121 }
02122 }
02123
02125 ~__LDG() {}
02126
02128 _Self& operator=(const _Self& __x);
02129
02131 _Self& operator=(const _RV_LDG& __rl)
02132 {
02133 this->_C_ground = __rl.first;
02134 this->_C_sky = __rl.second;
02135 return *this;
02136 }
02137
02139 _Self& operator=(const erased_part& __ep)
02140 {
02141 this->_C_ground = __ep.first.first;
02142 this->_C_sky = __ep.first.second;
02143 return *this;
02144 }
02145
02146 #if 0
02147
02148 friend bool operator== __VGTL_NULL_TMPL_ARGS (
02149 const __LDG& __x, const __LDG& __y);
02150 #endif
02151 };
02152
02153 #if 0
02154
02155 template <class _Tp, class _Ctr, class _Iterator, class _CIterator,
02156 class _Inserter, class _Alloc>
02157 inline bool operator==(const __LDG<_Tp,_Ctr,_Iterator,_CIterator,_Inserter,
02158 _Alloc>& __x,
02159 const __LDG<_Tp,_Ctr,_Iterator,_CIterator,_Inserter,
02160 _Alloc>& __y)
02161 {
02162 typedef typename __LDG<_Tp,_Ctr,_Iterator,_CIterator,_Inserter,
02163 _Alloc>::const_walker const_walker;
02164 const_walker __w1 = __x.begin(cw_pre);
02165 const_walker __w2 = __y.begin(cw_pre);
02166 const_walker __e1 = __x.end(cw_pre);
02167 const_walker __e2 = __y.end(cw_pre);
02168
02169
02170 for(; __w1 != __e1 && __w2 != __e2 ; ++__w1, ++__w2)
02171 if(__w1.in_preorder() != __w2.in_preorder() ||
02172 (__w1.in_preorder() && *__w1 != *__w2))
02173 return false;
02174 return __w1 == __e1 && __w2 == __e2;
02175 }
02176 #endif
02177
02178 template <class _Tp, class _Ctr, class _Iterator, class _CIterator,
02179 class _Inserter, class _Alloc>
02180 __LDG<_Tp, _Ctr, _Iterator, _CIterator, _Inserter, _Alloc>&
02181 __LDG<_Tp, _Ctr, _Iterator, _CIterator, _Inserter, _Alloc>::operator=(
02182 const __LDG<_Tp, _Ctr, _Iterator, _CIterator, _Inserter, _Alloc>& __x)
02183 {
02184 if (this != &__x)
02185 {
02186 children_iterator cit;
02187 std::map<_Node*,_Node*> __nconn;
02188
02189 clear();
02190 __nconn.insert(make_pair(__x._C_sky, this->_C_sky));
02191 this->_C_mark = 0;
02192 for(cit = __x._C_ground->_C_children.begin();
02193 cit != __x._C_ground->_C_children.end(); ++cit)
02194 {
02195 if((_Node*)*cit != __x._C_sky)
02196 this->_C_ground->_C_children.insert(this->_C_ground->_C_children.end(),
02197 copy_subgraph((_Node*)*cit, this->_C_ground, __nconn));
02198 }
02199 }
02200 return *this;
02201 }
02202
02204
02210 template <class _Tp,
02211 template <class __Ty, class __AllocT> class _SequenceCtr = std::vector,
02212 class _PtrAlloc = __VGTL_DEFAULT_ALLOCATOR(void *),
02213 class _Alloc = __VGTL_DEFAULT_ALLOCATOR(_Tp) >
02214 class ldgraph : public __LDG<_Tp, _SequenceCtr<void*, _PtrAlloc>,
02215 typename _SequenceCtr<void*, _PtrAlloc>::iterator,
02216 typename _SequenceCtr<void*, _PtrAlloc>::const_iterator,
02217 typename _SequenceCtr<void*, _PtrAlloc>::iterator,
02218 _Alloc>
02219 {
02220 private:
02221 typedef typename _SequenceCtr<void*, _PtrAlloc>::iterator ___cit;
02222 typedef __LDG<_Tp,_SequenceCtr<void*, _PtrAlloc>,
02223 typename _SequenceCtr<void*, _PtrAlloc>::iterator,
02224 typename _SequenceCtr<void*, _PtrAlloc>::const_iterator,
02225 typename _SequenceCtr<void*, _PtrAlloc>::iterator,
02226 _Alloc> _Base;
02227 protected:
02228 typedef ldgraph<_Tp,_SequenceCtr,_PtrAlloc,_Alloc> _Self;
02229 typedef typename _Base::allocator_type allocator_type;
02230 typedef typename _Base::_RV_LDG _RV_LDG;
02231 typedef typename _Base::_Node _Node;
02232
02233 typedef typename _Base::container_iterator container_iterator;
02234
02235 typedef typename _Base::erased_part erased_part;
02236
02237 public:
02239 typedef typename _Base::walker walker;
02241 typedef typename _Base::const_walker const_walker;
02243 typedef typename _Base::children_iterator children_iterator;
02245 typedef typename _Base::parents_iterator parents_iterator;
02247 typedef typename _Base::parents_const_iterator parents_const_iterator;
02249 typedef typename _Base::children_const_iterator children_const_iterator;
02250
02251 public:
02253 explicit ldgraph(const allocator_type& __a = allocator_type()) : _Base(__a) {}
02254
02256 ldgraph(const _Self& __dg) : _Base(__dg) {}
02257
02259 ldgraph(const erased_part& __ep, const allocator_type& __a = allocator_type())
02260 : _Base(__a)
02261 {
02262 this->_C_ground = __ep.first.first;
02263 this->_C_sky = __ep.first.second;
02264 }
02265
02266
02267
02269 void clear() { _Base::clear(); }
02270
02276 walker between(const walker& __parent, const children_iterator& __cit,
02277 const walker& __child, const parents_iterator& __pit,
02278 const _Tp& __x)
02279 {
02280 return insert_in_graph(__x, __parent, __child, __cit, __pit);
02281 }
02282
02283
02289 walker split(const walker& __parent, const children_iterator& __ch_it,
02290 const walker& __child, const parents_iterator& __pa_it,
02291 const _Tp& __x)
02292 {
02293 container_iterator __cit;
02294
02295 walker __rv = between(__parent, __ch_it, __child, __pa_it, __x);
02296
02297 __cit = __parent._C_w_cur->get_childentry_iterator((void*)__child._C_w_cur);
02298 if(__cit != __parent._C_w_cur->_C_children.end())
02299 __parent._C_w_cur->_C_children.erase(__cit);
02300 __cit = __child._C_w_cur->get_parententry_iterator((void*)__parent._C_w_cur);
02301 if(__cit != __child._C_w_cur->_C_parents.end())
02302 __child._C_w_cur->_C_parents.erase(__cit);
02303 return __rv;
02304 }
02305
02306
02311 walker between_back(const walker& __parent, const walker& __child,
02312 const _Tp& __x)
02313 {
02314 return insert_in_graph(__x, __parent, __child,
02315 __parent._C_w_cur->_C_children.end(),
02316 __child._C_w_cur->_C_parents.end());
02317 }
02318
02319
02324 walker split_back(const walker& __parent,
02325 const walker& __child, const _Tp& __x)
02326 {
02327 container_iterator __cit;
02328
02329 __cit = __parent._C_w_cur->get_childentry_iterator((void*)__child._C_w_cur);
02330 if(__cit != __parent._C_w_cur->_C_children.end())
02331 __parent._C_w_cur->_C_children.erase(__cit);
02332 __cit = __child._C_w_cur->get_parententry_iterator((void*)__parent._C_w_cur);
02333 if(__cit != __child._C_w_cur->_C_parents.end())
02334 __child._C_w_cur->_C_parents.erase(__cit);
02335 return between_back(__parent, __child, __x);
02336 }
02337
02342 walker between_front(const walker& __parent, const walker& __child,
02343 const _Tp& __x)
02344 {
02345 return insert_in_graph(__x, __parent, __child,
02346 __parent._C_w_cur->_C_children.begin(),
02347 __child._C_w_cur->_C_parents.begin());
02348 }
02349
02350
02355 walker split_front(const walker& __parent,
02356 const walker& __child, const _Tp& __x)
02357 {
02358 container_iterator __cit;
02359
02360 __cit = __parent._C_w_cur->get_childentry_iterator((void*)__child._C_w_cur);
02361 if(__cit != __parent._C_w_cur->_C_children.end())
02362 __parent._C_w_cur->_C_children.erase(__cit);
02363 __cit = __child._C_w_cur->get_parententry_iterator((void*)__parent._C_w_cur);
02364 if(__cit != __child._C_w_cur->_C_parents.end())
02365 __child._C_w_cur->_C_parents.erase(__cit);
02366 return between_front(__parent, __child, __x);
02367 }
02368
02369
02374 #ifdef __VGTL_MEMBER_TEMPLATES
02375 template <template <class __Tp, class __AllocTp> class __SequenceCtr1,
02376 template <class __Tp, class __AllocTp> class __SequenceCtr2,
02377 class _Allocator1, class _Allocator2>
02378 walker between(const __SequenceCtr1<walker,_Allocator1>& __parents,
02379 const __SequenceCtr2<walker,_Allocator2>& __children,
02380 const _Tp& __x)
02381 {
02382 typename __SequenceCtr1<walker,_Allocator1>::iterator __wpit;
02383 typename __SequenceCtr2<walker,_Allocator2>::iterator __wcit;
02384 _Node* __tmp = _C_create_node(__x);
02385 walker __help(__tmp);
02386
02387 if(__parents.empty() || __children.empty())
02388 return;
02389 __wpit = __parents.begin();
02390 __wcit = __children.begin();
02391 insert_node_in_graph(__tmp, *__wpit, *__wcit,
02392 (*__wpit)._C_w_cur->_C_children.end(),
02393 (*__wcit)._C_w_cur->_C_parents.end());
02394 for(++__wpit; __wpit != __parents.end(); ++__wpit)
02395 add_edge(*__wpit, __help, (*__wpit)._C_w_cur->_C_children.end(),
02396 __tmp->_C_parents.end());
02397 for(++__wcit; __wcit != __children.end(); ++__wcit)
02398 add_edge(__help, *__wcit, __tmp->_C_children.end(),
02399 (*__wcit)._C_w_cur->_C_parents.end());
02400 return __help;
02401 }
02402
02407 template <template <class __Tp, class __AllocTp> class __SequenceCtr1,
02408 template <class __Tp, class __AllocTp> class __SequenceCtr2,
02409 class _Allocator1, class _Allocator2>
02410 void split(const __SequenceCtr1<walker,_Allocator1>& __parents,
02411 const __SequenceCtr2<walker,_Allocator2>& __children,
02412 const _Tp& __x)
02413 {
02414 container_iterator __cit;
02415 typename __SequenceCtr1<walker,_Allocator1>::const_iterator __pnt;
02416 typename __SequenceCtr2<walker,_Allocator2>::const_iterator __cld;
02417
02418 for(__cld = __children.begin(); __cld != __children.end(); ++__cld)
02419 for(__pnt = __parents.begin(); __pnt != __parents.end(); ++__pnt)
02420 {
02421 __cit = (*__pnt)._C_w_cur->get_childentry_iterator((void*)(*__cld)._C_w_cur);
02422 if(__cit != (*__pnt)._C_w_cur->_C_children.end())
02423 (*__pnt)._C_w_cur->_C_children.erase(__cit);
02424 __cit = (*__cld)._C_w_cur->get_parententry_iterator((void*)(*__pnt)._C_w_cur);
02425 if(__cit != (*__cld)._C_w_cur->_C_parents.end())
02426 (*__cld)._C_w_cur->_C_parents.erase(__cit);
02427 }
02428 between(__parents, __children, __x);
02429 }
02430 #endif
02431
02436 void insert_subgraph(_Self& __subgraph, const walker& __parent,
02437 const children_iterator& __ch_it, const walker& __child,
02438 const parents_iterator& __pa_it)
02439 {
02440 insert_subgraph(__subgraph, __parent, __child, __ch_it, __pa_it);
02441 }
02442
02447 void insert_back_subgraph(_Self& __subgraph, const walker& __parent,
02448 const walker& __child)
02449 {
02450 insert_subgraph(__subgraph, __parent, __child,
02451 __parent._C_w_cur->_C_children.end(),
02452 __child._C_w_cur->_C_parents.end());
02453 }
02454
02455
02460 void insert_front_subgraph(_Self& __subgraph, const walker& __parent,
02461 const walker& __child)
02462 {
02463 insert_subgraph(__subgraph, __parent, __child,
02464 __parent._C_w_cur->_C_children.begin(),
02465 __child._C_w_cur->_C_parents.begin());
02466 }
02467
02468
02469 #ifdef __VGTL_MEMBER_TEMPLATES
02470
02471 #if 0
02472 template <template <class __Tp, class __AllocTp> class __SequenceCtr1,
02473 template <class __Tp, class __AllocTp> class __SequenceCtr2,
02474 class _Allocator1, class _Allocator2>
02475 void insert_subgraph(_Self& __subgraph,
02476 const __SequenceCtr1<walker,_Allocator1>& __parents,
02477 const __SequenceCtr2<walker,_Allocator2>& __children)
02478 {
02479 insert_subgraph(__subgraph, __parents, __children);
02480 }
02481 #endif // 0
02482 #endif
02483
02488 void add_edge(const walker& __parent, const children_iterator& __ch_it,
02489 const walker& __child, const parents_iterator& __pa_it)
02490 {
02491 _Base::add_edge(__parent, __child, __ch_it, __pa_it);
02492 }
02493
02498 void add_edge_back(const walker& __parent, const walker& __child)
02499 {
02500 add_edge(__parent, __parent._C_w_cur->_C_children.end(), __child,
02501 __child._C_w_cur->_C_parents.end());
02502 }
02503
02508 void add_edge_front(const walker& __parent, const walker& __child)
02509 {
02510 add_edge(__parent, __parent._C_w_cur->_C_children.begin(), __child,
02511 __child._C_w_cur->_C_parents.begin());
02512 }
02513
02514
02515
02516 #ifdef __VGTL_MEMBER_TEMPLATES
02518
02522 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
02523 class _Allocator>
02524 walker between(const walker& __parent, const children_iterator& __cit,
02525 const __SequenceCtr<walker,_Allocator>& __children,
02526 const _Tp& __x)
02527 {
02528 return insert_in_graph(__x, __parent, __cit, __children);
02529 }
02530
02535 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
02536 class _Allocator>
02537 walker split(const walker& __parent, const children_iterator& __ch_it,
02538 const __SequenceCtr<walker,_Allocator>& __children,
02539 const _Tp& __x)
02540 {
02541 container_iterator __cit;
02542 typename __SequenceCtr<walker,_Allocator>::const_iterator __cld;
02543 walker __rv = between(__parent, __ch_it, __children, __x);
02544
02545 for(__cld = __children.begin(); __cld != __children.end(); ++__cld)
02546 {
02547 __cit = __parent._C_w_cur->get_childentry_iterator((void*)(*__cld)._C_w_cur);
02548 if(__cit != __parent._C_w_cur->_C_children.end())
02549 __parent._C_w_cur->_C_children.erase(__cit);
02550 __cit = (*__cld)._C_w_cur->get_parententry_iterator((void*)__parent._C_w_cur);
02551 if(__cit != (*__cld)._C_w_cur->_C_parents.end())
02552 (*__cld)._C_w_cur->_C_parents.erase(__cit);
02553 }
02554 return __rv;
02555 }
02556
02562 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
02563 class _Allocator>
02564 walker split_back(const walker& __parent,
02565 const __SequenceCtr<walker, _Allocator>& __children,
02566 const _Tp& __x)
02567 {
02568 return split(__parent, __parent._C_w_cur->_C_children.end(), __children,
02569 __x);
02570 }
02571
02577 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
02578 class _Allocator>
02579 walker between_back(const walker& __parent,
02580 const __SequenceCtr<walker,_Allocator>& __children,
02581 const _Tp& __x)
02582 {
02583 return between(__parent, __parent._C_w_cur->_C_children.end(),
02584 __children, __x);
02585 }
02586
02592 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
02593 class _Allocator>
02594 walker split_front(const walker& __parent,
02595 const __SequenceCtr<walker,_Allocator>& __children,
02596 const _Tp& __x)
02597 {
02598 return split(__parent, __parent._C_w_cur->_C_children.begin(), __children,
02599 __x);
02600 }
02601
02607 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
02608 class _Allocator>
02609 walker between_front(const walker& __parent,
02610 const __SequenceCtr<walker,_Allocator>& __children,
02611 const _Tp& __x)
02612 {
02613 return between(__parent, __parent._C_w_cur->_C_children.begin(),
02614 __children, __x);
02615 }
02616
02618
02622 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
02623 class _Allocator>
02624 walker between(const __SequenceCtr<walker,_Allocator>& __parents,
02625 const walker& __child, const parents_iterator& __pit,
02626 const _Tp& __x)
02627 {
02628 return insert_in_graph(__x, __parents, __child, __pit);
02629 }
02630
02635 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
02636 class _Allocator>
02637 walker split(const __SequenceCtr<walker,_Allocator>& __parents,
02638 const walker& __child, const parents_iterator& __pr_it,
02639 const _Tp& __x)
02640 {
02641 container_iterator __cit;
02642 typename __SequenceCtr<walker,_Allocator>::iterator __pnt;
02643 walker __rv = between(__parents, __child, __pr_it, __x);
02644
02645 for(__pnt = __parents.begin(); __pnt != __parents.end(); ++__pnt)
02646 {
02647 __cit = __child._C_w_cur->get_parententry_iterator((void*)(*__pnt));
02648 if(__cit != __child._C_w_cur->_C_parents.end())
02649 __child._C_w_cur->_C_parents.erase(__cit);
02650 __cit = (*__pnt)._C_w_cur->get_childentry_iterator((void*)__child);
02651 if(__cit != (*__pnt)._C_w_cur->_C_children.end())
02652 (*__pnt)._C_w_cur->_C_children.erase(__cit);
02653 }
02654 return __rv;
02655 }
02656
02662 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
02663 class _Allocator>
02664 walker split_back(const __SequenceCtr<walker,_Allocator>& __parents, const walker& __child,
02665 const _Tp& __x)
02666 {
02667 return split(__parents, __child, __child._C_w_cur->_C_parents.end(),
02668 __x);
02669 }
02670
02676 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
02677 class _Allocator>
02678 walker between_back(const __SequenceCtr<walker,_Allocator>& __parents,
02679 const walker& __child, const _Tp& __x)
02680 {
02681 return between(__parents, __child,
02682 __child._C_w_cur->_C_children.end(), __x);
02683 }
02684
02690 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
02691 class _Allocator>
02692 walker split_front(const __SequenceCtr<walker,_Allocator>& __parents,
02693 const walker& __child, const _Tp& __x)
02694 {
02695 return split(__parents, __child, __child._C_w_cur->_C_parents.begin(),
02696 __x);
02697 }
02698
02704 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
02705 class _Allocator>
02706 walker between_front(const __SequenceCtr<walker,_Allocator>& __parents,
02707 const walker& __child, const _Tp& __x)
02708 {
02709 return between(__parents, __child,
02710 __child._C_w_cur->_C_children.begin(), __x);
02711 }
02712 #endif
02713
02715 _Self& operator=(const _RV_LDG& __rl)
02716 {
02717 this->_C_ground = __rl.first;
02718 this->_C_sky = __rl.second;
02719 return *this;
02720 }
02721
02723 _Self& operator=(const erased_part& __ep)
02724 {
02725 this->_C_ground = __ep.first.first;
02726 this->_C_sky = __ep.first.second;
02727 return *this;
02728 }
02729 };
02730
02732
02733
02734
02735
02736
02737
02738
02740
02746 template <class _Tp,
02747 template <class __Ty, class __AllocT> class _SequenceCtr = std::vector,
02748 class _PtrAlloc = __VGTL_DEFAULT_ALLOCATOR(void *),
02749 class _Alloc = __VGTL_DEFAULT_ALLOCATOR(_Tp) >
02750 class ldag : public ldgraph<_Tp, _SequenceCtr, _PtrAlloc, _Alloc>
02751 {
02752 protected:
02753 typedef ldag<_Tp,_SequenceCtr,_PtrAlloc,_Alloc> _Self;
02754 typedef ldgraph<_Tp, _SequenceCtr, _PtrAlloc, _Alloc> _Base;
02755
02756 typedef typename _Base::allocator_type allocator_type;
02757 typedef typename _Base::_RV_LDG _RV_LDG;
02758 typedef typename _Base::_Node _Node;
02759
02760 typedef typename _Base::container_iterator container_iterator;
02761
02762 public:
02764 typedef typename _Base::walker walker;
02766 typedef typename _Base::const_walker const_walker;
02768 typedef typename _Base::children_iterator children_iterator;
02770 typedef typename _Base::parents_iterator parents_iterator;
02772 typedef typename _Base::children_const_iterator children_const_iterator;
02774 typedef typename _Base::parents_const_iterator parents_const_iterator;
02775
02777 typedef typename _Base::erased_part erased_part;
02778
02779 public:
02781 explicit ldag(const allocator_type& __a = allocator_type()) : _Base(__a) {}
02782
02784 ldag(const _Self& __ldag) : _Base(__ldag) {}
02785
02786
02787
02788
02790 ldag(const _Base& __ldag) : _Base(__ldag)
02791 {
02792 if(!check_acyclicity(this->ground(), this->sky()))
02793
02794 this->clear();
02795 }
02796
02798 ldag(const erased_part& __ep) : _Base(__ep)
02799 {
02800 if(!check_acyclicity(this->ground(), this->sky()))
02801
02802 this->clear();
02803 }
02804 #if 0
02805 void add_edge(const walker& __parent, const walker& __child)
02806 {
02807 }
02808
02809
02810 #endif
02811
02812 private:
02813
02814 bool check_edge(const walker& __parent, const walker& __child)
02815 {
02816
02817 return true;
02818 }
02819
02820 public:
02822 bool check_acyclicity(const walker& __parent, const walker& __child)
02823 {
02824 return true;
02825 }
02826
02827 #if 0
02828 #ifdef __VGTL_MEMBER_TEMPLATES
02829 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
02830 class _Allocator>
02831 void check_edges(const _SequenceCtr<std::pair<walker,walker>,_Allocator >& __edges)
02832 {
02833 }
02834 #endif
02835 #endif
02836
02838 _Self& operator=(const _RV_LDG& __rl)
02839 {
02840 this->_C_ground = __rl.first;
02841 this->_C_sky = __rl.second;
02842 return *this;
02843 }
02844
02846 _Self& operator=(const erased_part& __ep)
02847 {
02848 this->_C_ground = __ep.first.first;
02849 this->_C_sky = __ep.first.second;
02850 return *this;
02851 }
02852 };
02853
02854
02856
02857 #if 0
02858
02859
02860 template <class _Tp,
02861 template <class __Key, class __Ty, class __Compare, class __AllocT> class _AssocCtr = std::multimap,
02862 class _Key = std::string,
02863 class _Compare = less<_Key>,
02864 class _PtrAlloc = __VGTL_DEFAULT_ALLOCATOR(void *),
02865 class _Alloc = __VGTL_DEFAULT_ALLOCATOR(_Tp) >
02866 class ldgraph : public __LDG<_Tp, _AssocCtr<_Key, void*, _Compare, _PtrAlloc>,
02867 pair_adaptor<typename _AssocCtr<_Key, void*,
02868 _Compare, _PtrAlloc>::iterator>,
02869 _Key, _Alloc>
02870 {
02871 protected:
02872 typedef ldgraph<_Tp,_AssocCtr,_Key,_Compare,_PtrAlloc,_Alloc> _Self;
02873
02874 public:
02875 _Self& operator=(_Node* __x)
02876 {
02877 this->_C_node = __x;
02878 return *this;
02879 }
02880
02881
02882 };
02883
02884 template <class _Tp,
02885 template <class __Key, class __Ty, class __Compare, class __AllocT> class _AssocCtr = std::multimap,
02886 class _Key = std::string,
02887 class _Compare = less<_Key>,
02888 class _PtrAlloc = __VGTL_DEFAULT_ALLOCATOR(void *),
02889 class _Alloc = __VGTL_DEFAULT_ALLOCATOR(_Tp) >
02890 class ldag : public ldgraph<_Tp, _AssocCtr, _Key, _Compare, _PtrAlloc, _Alloc>
02891 {
02892 protected:
02893 typedef ldag<_Tp,_AssocCtr,_Key,_Compare,_PtrAlloc,_Alloc> _Self;
02894 typedef ldgraph<_Tp,_AssocCtr,_Key,_Compare,_PtrAlloc,_Alloc> _Base;
02895
02896 public:
02897 explicit ldag(const allocator_type& __a = allocator_type()) : _Base(__a) {}
02898
02899 explicit ldag() : _Base(allocator_type()) {}
02900
02901 ldag(const _Self& __ldag) : _Base(__ldag) {}
02902
02903
02904
02905
02906 #if 0
02907 void add_edge(const walker& __parent, const walker& __child)
02908 {
02909 }
02910
02911
02912
02913 private:
02914 void check_edge(const walker& __parent, const walker& __child)
02915 {
02916 }
02917
02918 #ifdef __VGTL_MEMBER_TEMPLATES
02919 template <template <class __Tp, class __AllocTp> class __SequenceCtr,
02920 class _Allocator>
02921 void check_edges(const _SequenceCtr<std::pair<walker,walker>,_Allocator >& __edges)
02922 {
02923 }
02924 #endif
02925 #endif
02926
02927 _Self& operator=(const _RV_LDG& __rl)
02928 {
02929 this->_C_ground = __rl.first;
02930 this->_C_sky = __rl.second;
02931 return *this;
02932 }
02933 };
02934 #endif
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
03070
03071
03072
03073
03074
03075
03076
03077
03078
03079
03080
03081
03082
03083
03084
03085
03086
03087
03088
03089
03090
03091
03092
03093
03094
03095
03096
03097
03098
03099
03100
03101
03102
03103
03104
03105
03106
03107
03108
03109
03110
03111
03112
03113
03114
03115
03116
03117
03118
03119
03120
03121
03122
03123
03124
03125
03126
03127
03128
03129
03130
03131
03132
03133
03134
03135
03136
03137
03138
03139
03140
03141
03142
03143
03144
03145
03146
03147
03148
03149
03150
03151
03152
03153
03154
03155
03156
03157
03158
03159
03160
03161
03162
03163
03164
03165
03166
03167
03168
03169
03170
03171
03172
03173
03174
03175
03176
03177
03178
03179
03180
03181
03182
03183
03184
03185
03186 __VGTL_END_NAMESPACE
03187
03188 #endif // __VGTL_LDAG_H_