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_LDAGBASE_H_
00032 #define __VGTL_LDAGBASE_H_
00033
00034 #include <vgtl_helpers.h>
00035 #include <vgtl_intadapt.h>
00036
00037 __VGTL_BEGIN_NAMESPACE
00038
00040
00044 template <class _Tp, class _Ctr, class _Iterator>
00045 class _LDG_node
00046 {
00047 private:
00048 typedef void* _Void_pointer;
00049 typedef _Iterator _Ctr_iterator;
00050 typedef _LDG_node<_Tp,_Ctr,_Iterator> _Self;
00051
00052 public:
00054 _Tp* _C_data;
00056 _Ctr _C_inedges;
00058 _Ctr _C_outedges;
00060 int _C_visited;
00061
00063 _LDG_node() {
00064 _C_visited=0;
00065 __VGTL_TRY {
00066 _C_data = new _Tp;
00067 std::_Construct(&_C_inedges);
00068 std::_Construct(&_C_outedges);
00069 }
00070 __VGTL_UNWIND( );
00071 }
00072
00074 ~_LDG_node() {
00075 __VGTL_TRY {
00076 std::_Destroy(&_C_inedges);
00077 std::_Destroy(&_C_outedges);
00078 delete _C_data;
00079 }
00080 __VGTL_UNWIND();
00081 }
00082
00084 void clear_in_edges()
00085 { _C_inedges.erase(_C_inedges.begin(), _C_inedges.end()); }
00087 void clear_out_edges()
00088 { _C_outedges.erase(_C_outedges.begin(), _C_outedges.end()); }
00089
00091 _Ctr_iterator get_childentry_iterator(const _Void_pointer __p)
00092 { _Ctr_iterator __tmp;
00093 _Ctr_iterator __end = _C_children.end();
00094 for(__tmp = _C_children.begin(); __tmp != __end; ++__tmp)
00095 if(*__tmp == __p) break;
00096 return __tmp;
00097 }
00098
00100 _Ctr_iterator get_parententry_iterator(const _Void_pointer __p)
00101 { _Ctr_iterator __tmp;
00102 _Ctr_iterator __end = _C_parents.end();
00103 for(__tmp = _C_parents.begin(); __tmp != __end; ++__tmp)
00104 if(*__tmp == __p) break;
00105 return __tmp;
00106 }
00107
00108
00109 #ifdef __VGTL_MEMBER_TEMPLATES
00110
00114 template <class _Output_Iterator>
00115 void add_all_children(_Output_Iterator fi, _Self* _parent);
00116
00117
00122 template <class _Output_Iterator>
00123 void add_all_parents(_Output_Iterator fi, _Self* _child);
00124
00126 template <class Compare>
00127 void sort_in_edges(_Ctr_iterator first, _Ctr_iterator last, Compare comp)
00128 {
00129 sort(first, last, _G_compare_adaptor<Compare, _Self>(comp));
00130 }
00131
00133 template <class Compare>
00134 void sort_out_edges(_Ctr_iterator first, _Ctr_iterator last, Compare comp)
00135 {
00136 sort(first, last, _G_compare_adaptor<Compare, _Self>(comp));
00137 }
00138 #endif
00139 };
00140
00141 #ifdef __VGTL_MEMBER_TEMPLATES
00142 template <class _Tp, class _Ctr, class _Iterator>
00143 template <class _Output_Iterator>
00144 inline void
00145 _LDG_node<_Tp,_Ctr,_Iterator>::
00146 add_all_children(_Output_Iterator fi, _Self* _parent)
00147 { _Ctr_iterator it;
00148 for(it = _C_children.begin();
00149 it != _C_children.end();
00150 ++it)
00151 {
00152 *fi++ = *it;
00153 ((_Self*)*it)->_C_parents.insert(((_Self*)*it)->_C_parents.end(), _parent);
00154 }
00155 };
00156
00157 template <class _Tp, class _Ctr, class _Iterator>
00158 template <class _Output_Iterator>
00159 inline void
00160 _LDG_node<_Tp,_Ctr,_Iterator>::
00161 add_all_parents(_Output_Iterator fi, _Self* _child)
00162 { _Ctr_iterator it;
00163 for(it = _C_parents.begin();
00164 it != _C_parents.end();
00165 ++it)
00166 {
00167 *fi++ = *it;
00168 ((_Self*)*it)->_C_children.insert(((_Self*)*it)->_C_children.end(), _child);
00169 }
00170 };
00171 #endif
00172
00174
00178 template <class _Te, class _TN>
00179 class _LDG_edge
00180 {
00181 private:
00182 typedef void* _Void_pointer;
00183 typedef _Iterator _Ctr_iterator;
00184 typedef _LDG_edge<_Te,_TN> _Self;
00185
00186 public:
00188 _Te* _E_data;
00190 _TN* _E_snode;
00192 _TN* _E_tnode;
00193
00195 _LDG_edge() {
00196 __VGTL_TRY {
00197 _E_data = new _Te;
00198 }
00199 __VGTL_UNWIND( );
00200 _E_snode = NULL;
00201 _E_tnode = NULL;
00202 }
00203
00205 ~_LDG_node() {
00206 __VGTL_TRY {
00207 delete _E_data;
00208 }
00209 __VGTL_UNWIND();
00210 }
00211
00212 #ifdef __VGTL_MEMBER_TEMPLATES
00213 #endif
00214 set_parent(_TN* p) { _E_pnode = p; }
00215
00216 set_child(_TN* c) { _E_cnode = c; }
00217
00218 set_edge(_TN* p, _TN* c) { set_parent(p); set_child(c); }
00219
00220 _TN* source() { return _E_snode; }
00221 _TN* target() { return _E_tnode; }
00222
00223 const _TN* source() const { return _E_snode; }
00224 const _TN* target() const { return _E_tnode; }
00225 };
00226
00227 #ifdef __VGTL_MEMBER_TEMPLATES
00228 #endif
00229
00230 #if __VGTL_USE_STD_ALLOCATORS
00231
00233
00244 template <class _Tp, class _Ctr, class _TI, class _Te, class _NAllocator,
00245 class _EAllocator, bool _IsStatic>
00246 class _LDG_alloc_base {
00247 public:
00248 typedef typename std::_Alloc_traits<_Tp, _NAllocator>::allocator_type
00249 node_allocator_type;
00250 node_allocator_type get_node_allocator() const { return _Node_allocator; }
00251
00252 typedef typename std::_Alloc_traits<_Te, _EAllocator>::allocator_type
00253 edge_allocator_type;
00254 edge_allocator_type get_edge_allocator() const { return _Edge_allocator; }
00255
00256 _LDG_alloc_base(const node_allocator_type& __na, const egde_allocator_type& __ea)
00257 : _Node_allocator(__na), _Edge_allocator(__ea) {}
00258
00259 private:
00260 typedef typename _LDG_node<_Tp,_Ctr,_TI> _Node;
00261
00262 protected:
00264 _LDG_node<_Tp,_Ctr,_TI>* _C_get_node()
00265 { return _Node_allocator.allocate(1); }
00267 void _C_put_node(_LDG_node<_Tp,_Ctr,_TI>* __p)
00268 { _Node_allocator.deallocate(__p, 1); }
00269
00271 _LDG_edge<_Te,_Node>* _C_get_edge()
00272 { return _Node_allocator.allocate(1); }
00274 void _C_put_edge(_LDG_edge<_Te,_Node>* __p)
00275 { _Node_allocator.deallocate(__p, 1); }
00276
00277 protected:
00278 typename std::_Alloc_traits<_LDG_node<_Tp,_Ctr,_TI>, _NAllocator>::allocator_type
00279 _Node_allocator;
00280 typename std::_Alloc_traits<_LDG_node<_Te,_Tp>, _EAllocator>::allocator_type
00281 _Edge_allocator;
00282
00283 protected:
00285 _LDG_node<_Tp,_Ctr,_TI>* _C_ground;
00287 _LDG_node<_Tp,_Ctr,_TI>* _C_sky;
00289 int _C_mark;
00290 };
00291
00293
00304 template <class _Tp, class _Ctr, class _TI, class _Te, class _NAllocator,
00305 class _EAllocator>
00306 class _LDG_alloc_base<_Tp, _Ctr, _TI, _Te, _NAllocator, _EAllocator, true> {
00307 public:
00308 typedef typename std::_Alloc_traits<_Tp, _NAllocator>::allocator_type
00309 node_allocator_type;
00310 node_allocator_type get_node_allocator() const { return node_allocator_type(); }
00311
00312 typedef typename std::_Alloc_traits<_Te, _EAllocator>::allocator_type
00313 edge_allocator_type;
00314 edge_allocator_type get_edge_allocator() const { return edge_allocator_type(); }
00315
00316 _LDG_alloc_base(const node_allocator_type&, const edge_allocator_type&) {}
00317
00318 private:
00319 typedef typename _LDG_node<_Tp,_Ctr,_TI> _Node;
00320
00321 protected:
00322 typedef typename std::_Alloc_traits<_LDG_node<_Tp,_Ctr,_TI>, _Allocator>::_Alloc_type
00323 _NAlloc_type;
00324 typedef typename std::_Alloc_traits<_LDG_edge<_Te,_Tp>, _Allocator>::_Alloc_type
00325 _EAlloc_type;
00326
00328 _LDG_node<_Tp,_Ctr,_TI>* _C_get_node()
00329 { return _NAlloc_type::allocate(1); }
00331 void _C_put_node(_LDG_node<_Tp,_Ctr,_TI>* __p)
00332 { _NAlloc_type::deallocate(__p, 1); }
00333
00335 _LDG_edge<_Te,_Node>* _C_get_edge()
00336 { return _EAlloc_type::allocate(1); }
00338 void _C_put_edge(_LDG_edge<_Te,_Node>* __p)
00339 { _EAlloc_type::deallocate(__p, 1); }
00340
00341 protected:
00343 _LDG_node<_Tp,_Ctr,_TI>* _C_ground;
00345 _LDG_node<_Tp,_Ctr,_TI>* _C_sky;
00347 int _C_mark;
00348 };
00349
00350
00352
00356 template <class _Tp, class _Ctr, class _Iterator, class _CIterator, class _Te,
00357 class _NAlloc, class _EAlloc>
00358 class _LDG_base
00359 : public _LDG_alloc_base<_Tp, _Ctr, _Iterator, _Te, _NAlloc, _EAlloc,
00360 std::_Alloc_traits<_Tp, _NAlloc>::_S_instanceless>
00361 {
00362 public:
00363 typedef _LDG_alloc_base<_Tp, _Ctr, _Iterator, _Te, _NAlloc, _EAlloc,
00364 std::_Alloc_traits<_Tp, _NAlloc>::_S_instanceless>
00365 _Base;
00367 typedef typename _Base::node_allocator_type node_allocator_type;
00369 typedef typename _Base::edge_allocator_type edge_allocator_type;
00370
00372 typedef _Ctr container_type;
00374 typedef _Iterator in_iterator;
00376 typedef _CIterator in_const_iterator;
00378 typedef _Iterator out_iterator;
00380 typedef _CIterator out_const_iterator;
00381
00382
00384 _LDG_base(const node_allocator_type& __a, const edge_allocator_type& __e)
00385 : _Base(__a, __e) {
00386 _Te* e;
00387 this->_C_mark = 0;
00388 __VGTL_TRY {
00389 this->_C_ground = _C_get_node();
00390 this->_C_sky = _C_get_node();
00391 memset(this->_C_ground, 0, sizeof(*this->_C_ground));
00392 memset(this->_C_sky, 0, sizeof(*this->_C_sky));
00393 std::_Construct(&this->_C_ground->_C_children);
00394 std::_Construct(&this->_C_ground->_C_parents);
00395 this->_C_ground->_C_data = new _Tp;
00396 std::_Construct(&this->_C_sky->_C_children);
00397 std::_Construct(&this->_C_sky->_C_parents);
00398 this->_C_sky->_C_data = new _Tp;
00399 e = _C_get_edge();
00400 e->_E_data = new _Te;
00401 }
00402 __VGTL_UNWIND(_C_put_node(this->_C_ground); _C_put_node(this->_C_sky);
00403 _C_put_edge(e); )
00404 this->_C_ground->_C_children.push_back(e);
00405 this->_C_sky->_C_parents.push_back(e);
00406 e->set_edge(&this->_C_ground, &this->_C_sky);
00407 this->_C_ground->_C_visited=0;
00408 this->_C_sky->_C_visited=0;
00409 }
00410
00412 ~_LDG_base() {
00413 clear();
00414
00415
00416 }
00417
00418 protected:
00420 void clear_graph(_LDG_node<_Tp,_Ctr,_Iterator>* _node);
00421
00422 public:
00424 void clear();
00426 void clear_out_edges()
00427 { this->_C_ground->clear_out_edges(); }
00429 void clear_in_edges()
00430 { this->_C_sky->clear_in_edges(); }
00431
00434 template <class _Output_Iterator>
00435 void add_all_out_edges(_Output_Iterator fi,
00436 _LDG_node<_Tp,_Ctr,_Iterator>* _parent);
00439 template <class _Output_Iterator>
00440 void add_all_in_edges(_Output_Iterator fi,
00441 _LDG_node<_Tp,_Ctr,_Iterator>* _child);
00442 };
00443 #else
00444
00445
00447
00453 template <class _Tp, class _Ctr, class _Iterator, class _CIterator, class _Te,
00454 class _NAlloc, class _EAlloc>
00455 class _LDG_base
00456 {
00457 public:
00459 typedef _NAlloc node_allocator_type;
00461 typedef _EAlloc edge_allocator_type;
00463 node_allocator_type get_node_allocator() const { return node_allocator_type(); }
00465 edge_allocator_type get_edge_allocator() const { return edge_allocator_type(); }
00466
00468 typedef _Ctr container_type;
00470 typedef _Iterator out_iterator;
00472 typedef _CIterator out_const_iterator;
00474 typedef _Iterator in_iterator;
00476 typedef _CIterator in_const_iterator;
00477
00479 _LDG_base(const node_allocator_type&, const edge_allocator_type&) {
00480 _Te* e;
00481 this->_C_mark = 0;
00482 __VGTL_TRY {
00483 this->_C_ground = _C_get_node();
00484 this->_C_sky = _C_get_node();
00485 memset(this->_C_ground, 0, sizeof(*this->_C_ground));
00486 memset(this->_C_sky, 0, sizeof(*this->_C_sky));
00487 std::_Construct(&this->_C_ground->_C_children);
00488 std::_Construct(&this->_C_ground->_C_parents);
00489 this->_C_ground->_C_data = new _Tp;
00490 std::_Construct(&this->_C_sky->_C_children);
00491 std::_Construct(&this->_C_sky->_C_parents);
00492 this->_C_sky->_C_data = new _Tp;
00493 e = _C_get_edge();
00494 e->_E_data = new _Te;
00495 }
00496 __VGTL_UNWIND(_C_put_node(this->_C_ground); _C_put_node(this->_C_sky);
00497 _C_put_edge(e); )
00498 this->_C_ground->_C_children.push_back(e);
00499 this->_C_sky->_C_parents.push_back(e);
00500 e->set_edge(&this->_C_ground, &this->_C_sky);
00501 this->_C_ground->_C_visited=0;
00502 this->_C_sky->_C_visited=0;
00503 }
00505 ~_LDG_base() {
00506 clear();
00507
00508
00509 }
00510
00511 protected:
00513 void clear_graph(_LDG_node<_Tp,_Ctr,_Iterator>* _node);
00514
00515 private:
00516 typedef typename _LDG_node<_Tp,_Ctr,_Iterator> _Node;
00517
00518 public:
00520 void clear();
00521
00522 protected:
00523 typedef std::allocator<_LDG_node<_Tp,_Ctr,_Iterator> > _NAlloc_type;
00524 typedef std::allocator<_LDG_edge<_Te,_Node> > _EAlloc_type;
00526 _LDG_node<_Tp,_Ctr,_Iterator>* _C_get_node()
00527 { return _NAlloc_type().allocate(1); }
00529 void _C_put_node(_LDG_node<_Tp,_Ctr,_Iterator>* __p)
00530 { _NAlloc_type().deallocate(__p, 1); }
00531
00533 _LDG_edge<_Te,_Node>* _C_get_edge()
00534 { return _EAlloc_type().allocate(1); }
00536 void _C_put_edge(_LDG_edge<_Te,_Node>* __p)
00537 { _EAlloc_type().deallocate(__p, 1); }
00538
00539 protected:
00541 _LDG_node<_Tp,_Ctr,_Iterator>* _C_ground;
00543 _LDG_node<_Tp,_Ctr,_Iterator>* _C_sky;
00545 int _C_mark;
00546
00548 void clear_out_edges()
00549 { this->_C_ground->clear_out_edges(); }
00551 void clear_in_edges()
00552 { this->_C_sky->clear_in_edges(); }
00553
00556 template <class _Output_Iterator>
00557 void add_all_out_edges(_Output_Iterator fi,
00558 _LDG_node<_Tp,_Ctr,_Iterator>* _parent);
00561 template <class _Output_Iterator>
00562 void add_all_in_edges(_Output_Iterator fi,
00563 _LDG_node<_Tp,_Ctr,_Iterator>* _child);
00564 };
00565
00566 #endif
00567
00568
00569 template <class _Tp, class _Ctr, class _Iterator, class _CIterator, class _Te,
00570 class _NAlloc, class _EAlloc>
00571 void
00572 _LDG_base<_Tp,_Ctr,_Iterator,_CIterator,_Te,_NAlloc,_EAlloc>::clear_graph(
00573 _LDG_node<_Tp,_Ctr,_Iterator>* _node)
00574 {
00575 _Ctr* oed = &_node->_C_out_edges;
00576 _Iterator it;
00577
00578 if(_node->_C_in_edges.size() <= 1)
00579 {
00580
00581 for(it = oed->begin(); it != oed->end(); ++it)
00582 clear_graph((_LDG_node<_Tp,_Ctr,_Iterator>*)(*it));
00583 _node->_C_out_edges.erase(_node->_C_out_edges.begin(),
00584 _node->_C_out_edges.end());
00585
00586 std::_Destroy(&_node->_C_out_edges);
00587 delete _node->_C_data;
00588 }
00589 if(_node->_C_in_edges.size() >= 1)
00590 _node->_C_in_edges.erase(_node->_C_in_edges.begin());
00591 if(_node->_C_in_edges.size() == 0)
00592 {
00593 std::_Destroy(&_node->_C_in_edges);
00594 _C_put_node(_node);
00595 }
00596 }
00597
00598 template <class _Tp, class _Ctr, class _Iterator, class _CIterator, class _Te,
00599 class _NAlloc, class _EAlloc>
00600 template <class _Output_Iterator>
00601 inline void
00602 _LDG_base<_Tp,_Ctr,_Iterator,_CIterator,_Te,_NAlloc,_EAlloc>::
00603 add_all_out_edges(_Output_Iterator fi,
00604 _LDG_node<_Tp,_Ctr,_Iterator>* _parent)
00605 { this->_C_ground->add_all_out_edges(fi, _parent); };
00606
00607 template <class _Tp, class _Ctr, class _Iterator, class _CIterator, class _Te,
00608 class _NAlloc, class _EAlloc>
00609 template <class _Output_Iterator>
00610 inline void
00611 _LDG_base<_Tp,_Ctr,_Iterator,_CIterator,_Te,_NAlloc,_EAlloc>::
00612 add_all_parents(_Output_Iterator fi,
00613 _LDG_node<_Tp,_Ctr,_Iterator>* _child)
00614 { this->_C_sky->add_all_in_edges(fi, _child); };
00615
00616 template <class _Tp, class _Ctr, class _Iterator, class _CIterator, class _Te,
00617 class _NAlloc, class _EAlloc>
00618 void
00619 _LDG_base<_Tp,_Ctr,_Iterator,_CIterator,_Te,_NAlloc,_EAlloc>::clear()
00620 {
00621 clear_graph(this->_C_ground);
00622
00623
00624
00625
00626 }
00627
00628 #if 0
00629
00630
00631
00632 template <class _Tp>
00633 class ldag_node : public _LDG_node<_Tp, vector<void*>, vector<void*>::iterator>
00634 {
00635 }
00636
00637 template <class _Te, class _Tp>
00638 class ldag_edge : public _LDG_edge<_Te, _LDG_node<_Tp> >
00639 {
00640 }
00641
00642
00643
00644 template <class _Tp>
00645 class ldag_node
00646 {
00647 private:
00648 typedef _Ctr_iterator vector<void*>::iterator;
00649
00650 public:
00651 _Tp _C_data;
00652 vector<void *> _C_in_edges;
00653 vector<void *> _C_out_edges;
00654 int _C_visited;
00655
00656 _LDG_node();
00657
00658
00659
00660 void clear_out_edges();
00661 void clear_in_edges();
00662
00663 _Ctr_iterator get_childentry_iterator(const void* __p);
00664 _Ctr_iterator get_parententry_iterator(const void* __p);
00665
00666
00667
00668
00669 template <class _Output_Iterator>
00670 void add_all_out_edges(_Output_Iterator fi, ldag_node<_Tp>* _parent);
00671
00672 template <class _Output_Iterator>
00673 void add_all_in_edges(_Output_Iterator fi, ldag_node<_Tp>* _child);
00674 }
00675
00676
00677 template <class _Te, class _Tp>
00678 class ldag_edge
00679 {
00680 public:
00681 _Te _E_data;
00682 ldag_node<_Tp>* _E_snode;
00683 ldag_node<_Tp>* _E_tnode;
00684
00685 _LDG_edge();
00686
00687
00688
00689 void set_edge(ldag_node<_Tp>* s, _Tp* t);
00690 void set_source(ldag_node<_Tp>* s);
00691 void set_target(ldag_node<_Tp>* t);
00692
00693 ldag_node<_Tp>* source() { return _E_snode; }
00694 ldag_node<_Tp>* target() { return _E_tnode; }
00695
00696 const ldag_node<_Tp>* source() const { return _E_snode; }
00697 const ldag_node<_Tp>* target() const { return _E_tnode; }
00698 }
00699
00700
00701
00702
00703 template <class _Tp>
00704 class ldag_base
00705 {
00706 protected:
00707 ldag_node<_Tp>* _C_ground;
00708 ldag_node<_Tp>* _C_sky;
00709 int _C_mark;
00710
00711 public:
00712 ldag_base();
00713 ~ldag_base();
00714
00715 private:
00716
00717 void clear_graph(ldag_node<_Tp>* _node);
00718
00719 public:
00720 void clear();
00721
00722 ldag_node<_Tp>* _C_get_node();
00723 void _C_put_node(ldag_node<_Tp>* __p);
00724
00725 ldag_edge<_Te,_Tp>* _C_get_edge();
00726 void _C_put_edge(ldag_edge<_Te,_Tp>* __p);
00727
00728 protected:
00729 void clear_out_edges();
00730 void clear_in_edges();
00731
00732
00733 template <class _Output_Iterator>
00734 void add_all_out_edges(_Output_Iterator fi, ldag_node<_Tp>* _parent);
00735 void add_all_in_edges(_Output_Iterator fi, ldag_node<_Tp>* _child);
00736 }
00737
00738 #endif
00739
00740 __VGTL_END_NAMESPACE
00741
00742
00743 #endif // __VGTL_LDAGBASE_H_