51 |
57 |
52 std::vector<NodeT> nodes; |
58 std::vector<NodeT> nodes; |
53 |
59 |
54 std::vector<EdgeT> edges; |
60 std::vector<EdgeT> edges; |
55 |
61 |
56 protected: |
|
57 |
|
58 template <typename Key> class DynMapBase |
|
59 { |
|
60 protected: |
|
61 const SmartGraph* G; |
|
62 public: |
|
63 virtual void add(const Key k) = 0; |
|
64 virtual void erase(const Key k) = 0; |
|
65 DynMapBase(const SmartGraph &_G) : G(&_G) {} |
|
66 virtual ~DynMapBase() {} |
|
67 friend class SmartGraph; |
|
68 }; |
|
69 |
62 |
70 public: |
63 public: |
71 template <typename T> class EdgeMap; |
64 |
72 template <typename T> class NodeMap; |
65 typedef SmartGraph Graph; |
73 |
66 |
74 class Node; |
67 class Node; |
75 class Edge; |
68 class Edge; |
76 |
|
77 // protected: |
|
78 // HELPME: |
|
79 protected: |
|
80 ///\bug It must be public because of SymEdgeMap. |
|
81 /// |
|
82 mutable std::vector<DynMapBase<Node> * > dyn_node_maps; |
|
83 ///\bug It must be public because of SymEdgeMap. |
|
84 /// |
|
85 mutable std::vector<DynMapBase<Edge> * > dyn_edge_maps; |
|
86 |
|
87 public: |
|
88 |
|
89 |
69 |
90 class NodeIt; |
70 class NodeIt; |
91 class EdgeIt; |
71 class EdgeIt; |
92 class OutEdgeIt; |
72 class OutEdgeIt; |
93 class InEdgeIt; |
73 class InEdgeIt; |
94 |
74 |
95 template <typename T> class NodeMap; |
75 CREATE_MAP_REGISTRIES; |
96 template <typename T> class EdgeMap; |
76 CREATE_MAPS(ArrayMapFactory); |
97 |
77 |
98 public: |
78 public: |
99 |
79 |
100 SmartGraph() : nodes(), edges() { } |
80 SmartGraph() : nodes(), edges() { } |
101 SmartGraph(const SmartGraph &_g) : nodes(_g.nodes), edges(_g.edges) { } |
81 SmartGraph(const SmartGraph &_g) : nodes(_g.nodes), edges(_g.edges) { } |
102 |
82 |
103 ~SmartGraph() |
|
104 { |
|
105 for(std::vector<DynMapBase<Node> * >::iterator i=dyn_node_maps.begin(); |
|
106 i!=dyn_node_maps.end(); ++i) (**i).G=NULL; |
|
107 for(std::vector<DynMapBase<Edge> * >::iterator i=dyn_edge_maps.begin(); |
|
108 i!=dyn_edge_maps.end(); ++i) (**i).G=NULL; |
|
109 } |
|
110 |
|
111 int nodeNum() const { return nodes.size(); } //FIXME: What is this? |
83 int nodeNum() const { return nodes.size(); } //FIXME: What is this? |
112 int edgeNum() const { return edges.size(); } //FIXME: What is this? |
84 int edgeNum() const { return edges.size(); } //FIXME: What is this? |
113 |
85 |
114 ///\bug This function does something different than |
86 ///\bug This function does something different than |
115 ///its name would suggests... |
87 ///its name would suggests... |
286 InEdgeIt(const SmartGraph& _G,Node v) |
261 InEdgeIt(const SmartGraph& _G,Node v) |
287 : Edge(_G.nodes[v.n].first_in), G(&_G) { } |
262 : Edge(_G.nodes[v.n].first_in), G(&_G) { } |
288 InEdgeIt &operator++() { n=G->edges[n].next_in; return *this; } |
263 InEdgeIt &operator++() { n=G->edges[n].next_in; return *this; } |
289 // ///Validity check |
264 // ///Validity check |
290 // operator bool() { return Edge::operator bool(); } |
265 // operator bool() { return Edge::operator bool(); } |
291 }; |
|
292 |
|
293 template <typename T> class NodeMap : public DynMapBase<Node> |
|
294 { |
|
295 std::vector<T> container; |
|
296 |
|
297 public: |
|
298 typedef T ValueType; |
|
299 typedef Node KeyType; |
|
300 |
|
301 NodeMap(const SmartGraph &_G) : |
|
302 DynMapBase<Node>(_G), container(_G.maxNodeId()) |
|
303 { |
|
304 G->dyn_node_maps.push_back(this); |
|
305 } |
|
306 NodeMap(const SmartGraph &_G,const T &t) : |
|
307 DynMapBase<Node>(_G), container(_G.maxNodeId(),t) |
|
308 { |
|
309 G->dyn_node_maps.push_back(this); |
|
310 } |
|
311 |
|
312 NodeMap(const NodeMap<T> &m) : |
|
313 DynMapBase<Node>(*m.G), container(m.container) |
|
314 { |
|
315 G->dyn_node_maps.push_back(this); |
|
316 } |
|
317 |
|
318 template<typename TT> friend class NodeMap; |
|
319 |
|
320 ///\todo It can copy between different types. |
|
321 ///\todo We could use 'copy' |
|
322 template<typename TT> NodeMap(const NodeMap<TT> &m) : |
|
323 DynMapBase<Node>(*m.G), container(m.container.size()) |
|
324 { |
|
325 G->dyn_node_maps.push_back(this); |
|
326 typename std::vector<TT>::const_iterator i; |
|
327 for(typename std::vector<TT>::const_iterator i=m.container.begin(); |
|
328 i!=m.container.end(); |
|
329 i++) |
|
330 container.push_back(*i); |
|
331 } |
|
332 ~NodeMap() |
|
333 { |
|
334 if(G) { |
|
335 std::vector<DynMapBase<Node>* >::iterator i; |
|
336 for(i=G->dyn_node_maps.begin(); |
|
337 i!=G->dyn_node_maps.end() && *i!=this; ++i) ; |
|
338 //if(*i==this) G->dyn_node_maps.erase(i); //FIXME: Way too slow... |
|
339 //A better way to do that: (Is this really important?) |
|
340 if(*i==this) { |
|
341 *i=G->dyn_node_maps.back(); |
|
342 G->dyn_node_maps.pop_back(); |
|
343 } |
|
344 } |
|
345 } |
|
346 |
|
347 void add(const Node k) |
|
348 { |
|
349 if(k.n>=int(container.size())) container.resize(k.n+1); |
|
350 } |
|
351 |
|
352 void erase(const Node) { } |
|
353 |
|
354 void set(Node n, T a) { container[n.n]=a; } |
|
355 //'T& operator[](Node n)' would be wrong here |
|
356 typename std::vector<T>::reference |
|
357 operator[](Node n) { return container[n.n]; } |
|
358 //'const T& operator[](Node n)' would be wrong here |
|
359 typename std::vector<T>::const_reference |
|
360 operator[](Node n) const { return container[n.n]; } |
|
361 |
|
362 ///\warning There is no safety check at all! |
|
363 ///Using operator = between maps attached to different graph may |
|
364 ///cause serious problem. |
|
365 ///\todo Is this really so? |
|
366 ///\todo It can copy between different types. |
|
367 const NodeMap<T>& operator=(const NodeMap<T> &m) |
|
368 { |
|
369 container = m.container; |
|
370 return *this; |
|
371 } |
|
372 template<typename TT> |
|
373 const NodeMap<T>& operator=(const NodeMap<TT> &m) |
|
374 { |
|
375 std::copy(m.container.begin(), m.container.end(), container.begin()); |
|
376 return *this; |
|
377 } |
|
378 |
|
379 void update() {} //Useless for Dynamic Maps |
|
380 void update(T a) {} //Useless for Dynamic Maps |
|
381 }; |
|
382 |
|
383 template <typename T> class EdgeMap : public DynMapBase<Edge> |
|
384 { |
|
385 std::vector<T> container; |
|
386 |
|
387 public: |
|
388 typedef T ValueType; |
|
389 typedef Edge KeyType; |
|
390 |
|
391 EdgeMap(const SmartGraph &_G) : |
|
392 DynMapBase<Edge>(_G), container(_G.maxEdgeId()) |
|
393 { |
|
394 //FIXME: What if there are empty Id's? |
|
395 //FIXME: Can I use 'this' in a constructor? |
|
396 G->dyn_edge_maps.push_back(this); |
|
397 } |
|
398 EdgeMap(const SmartGraph &_G,const T &t) : |
|
399 DynMapBase<Edge>(_G), container(_G.maxEdgeId(),t) |
|
400 { |
|
401 G->dyn_edge_maps.push_back(this); |
|
402 } |
|
403 EdgeMap(const EdgeMap<T> &m) : |
|
404 DynMapBase<Edge>(*m.G), container(m.container) |
|
405 { |
|
406 G->dyn_edge_maps.push_back(this); |
|
407 } |
|
408 |
|
409 template<typename TT> friend class EdgeMap; |
|
410 |
|
411 ///\todo It can copy between different types. |
|
412 template<typename TT> EdgeMap(const EdgeMap<TT> &m) |
|
413 : DynMapBase<Edge>(*m.G), container(m.container.size()) |
|
414 { |
|
415 G->dyn_edge_maps.push_back(this); |
|
416 typename std::vector<TT>::const_iterator i; |
|
417 for(typename std::vector<TT>::const_iterator i=m.container.begin(); |
|
418 i!=m.container.end(); |
|
419 i++) |
|
420 container.push_back(*i); |
|
421 } |
|
422 ~EdgeMap() |
|
423 { |
|
424 if(G) { |
|
425 std::vector<DynMapBase<Edge>* >::iterator i; |
|
426 for(i=G->dyn_edge_maps.begin(); |
|
427 i!=G->dyn_edge_maps.end() && *i!=this; ++i) ; |
|
428 //if(*i==this) G->dyn_edge_maps.erase(i); //Way too slow... |
|
429 //A better way to do that: (Is this really important?) |
|
430 if(*i==this) { |
|
431 *i=G->dyn_edge_maps.back(); |
|
432 G->dyn_edge_maps.pop_back(); |
|
433 } |
|
434 } |
|
435 } |
|
436 |
|
437 void add(const Edge k) |
|
438 { |
|
439 if(k.n>=int(container.size())) container.resize(k.n+1); |
|
440 } |
|
441 void erase(const Edge) { } |
|
442 |
|
443 void set(Edge n, T a) { container[n.n]=a; } |
|
444 //T get(Edge n) const { return container[n.n]; } |
|
445 typename std::vector<T>::reference |
|
446 operator[](Edge n) { return container[n.n]; } |
|
447 typename std::vector<T>::const_reference |
|
448 operator[](Edge n) const { return container[n.n]; } |
|
449 |
|
450 ///\warning There is no safety check at all! |
|
451 ///Using operator = between maps attached to different graph may |
|
452 ///cause serious problem. |
|
453 ///\todo Is this really so? |
|
454 ///\todo It can copy between different types. |
|
455 const EdgeMap<T>& operator=(const EdgeMap<T> &m) |
|
456 { |
|
457 container = m.container; |
|
458 return *this; |
|
459 } |
|
460 template<typename TT> |
|
461 const EdgeMap<T>& operator=(const EdgeMap<TT> &m) |
|
462 { |
|
463 std::copy(m.container.begin(), m.container.end(), container.begin()); |
|
464 return *this; |
|
465 } |
|
466 |
|
467 void update() {} //Useless for DynMaps |
|
468 void update(T a) {} //Useless for DynMaps |
|
469 }; |
266 }; |
470 |
267 |
471 }; |
268 }; |
472 |
269 |
473 ///Graph for bidirectional edges. |
270 ///Graph for bidirectional edges. |
515 Edge f; |
318 Edge f; |
516 f.idref() = e.idref() - 2*(e.idref()%2) + 1; |
319 f.idref() = e.idref() - 2*(e.idref()%2) + 1; |
517 return f; |
320 return f; |
518 } |
321 } |
519 |
322 |
520 ///Common data storage for the edge pairs. |
|
521 |
|
522 ///This map makes it possible to store data shared by the oppositely |
|
523 ///directed pairs of edges. |
|
524 template <typename T> class SymEdgeMap : public DynMapBase<Edge> |
|
525 { |
|
526 std::vector<T> container; |
|
527 |
|
528 public: |
|
529 typedef T ValueType; |
|
530 typedef Edge KeyType; |
|
531 |
|
532 SymEdgeMap(const SymSmartGraph &_G) : |
|
533 DynMapBase<Edge>(_G), container(_G.maxEdgeId()/2) |
|
534 { |
|
535 static_cast<const SymSmartGraph*>(G)->dyn_edge_maps.push_back(this); |
|
536 } |
|
537 SymEdgeMap(const SymSmartGraph &_G,const T &t) : |
|
538 DynMapBase<Edge>(_G), container(_G.maxEdgeId()/2,t) |
|
539 { |
|
540 G->dyn_edge_maps.push_back(this); |
|
541 } |
|
542 |
|
543 SymEdgeMap(const SymEdgeMap<T> &m) : |
|
544 DynMapBase<SymEdge>(*m.G), container(m.container) |
|
545 { |
|
546 G->dyn_node_maps.push_back(this); |
|
547 } |
|
548 |
|
549 // template<typename TT> friend class SymEdgeMap; |
|
550 |
|
551 ///\todo It can copy between different types. |
|
552 /// |
|
553 |
|
554 template<typename TT> SymEdgeMap(const SymEdgeMap<TT> &m) |
|
555 : DynMapBase<SymEdge>(*m.G), container(m.container.size()) |
|
556 { |
|
557 G->dyn_node_maps.push_back(this); |
|
558 typename std::vector<TT>::const_iterator i; |
|
559 for(typename std::vector<TT>::const_iterator i=m.container.begin(); |
|
560 i!=m.container.end(); |
|
561 i++) |
|
562 container.push_back(*i); |
|
563 } |
|
564 |
|
565 ~SymEdgeMap() |
|
566 { |
|
567 if(G) { |
|
568 std::vector<DynMapBase<Edge>* >::iterator i; |
|
569 for(i=static_cast<const SymSmartGraph*>(G)->dyn_edge_maps.begin(); |
|
570 i!=static_cast<const SymSmartGraph*>(G)->dyn_edge_maps.end() |
|
571 && *i!=this; ++i) ; |
|
572 //if(*i==this) G->dyn_edge_maps.erase(i); //Way too slow... |
|
573 //A better way to do that: (Is this really important?) |
|
574 if(*i==this) { |
|
575 *i=static_cast<const SymSmartGraph*>(G)->dyn_edge_maps.back(); |
|
576 static_cast<const SymSmartGraph*>(G)->dyn_edge_maps.pop_back(); |
|
577 } |
|
578 } |
|
579 } |
|
580 |
|
581 void add(const Edge k) |
|
582 { |
|
583 if(!k.idref()%2&&k.idref()/2>=int(container.size())) |
|
584 container.resize(k.idref()/2+1); |
|
585 } |
|
586 void erase(const Edge k) { } |
|
587 |
|
588 void set(Edge n, T a) { container[n.idref()/2]=a; } |
|
589 //T get(Edge n) const { return container[n.idref()/2]; } |
|
590 typename std::vector<T>::reference |
|
591 operator[](Edge n) { return container[n.idref()/2]; } |
|
592 typename std::vector<T>::const_reference |
|
593 operator[](Edge n) const { return container[n.idref()/2]; } |
|
594 |
|
595 ///\warning There is no safety check at all! |
|
596 ///Using operator = between maps attached to different graph may |
|
597 ///cause serious problem. |
|
598 ///\todo Is this really so? |
|
599 ///\todo It can copy between different types. |
|
600 const SymEdgeMap<T>& operator=(const SymEdgeMap<T> &m) |
|
601 { |
|
602 container = m.container; |
|
603 return *this; |
|
604 } |
|
605 template<typename TT> |
|
606 const SymEdgeMap<T>& operator=(const SymEdgeMap<TT> &m) |
|
607 { |
|
608 std::copy(m.container.begin(), m.container.end(), container.begin()); |
|
609 return *this; |
|
610 } |
|
611 |
|
612 void update() {} //Useless for DynMaps |
|
613 void update(T a) {} //Useless for DynMaps |
|
614 |
|
615 }; |
|
616 |
323 |
617 }; |
324 }; |
618 |
325 |
619 /// @} |
326 /// @} |
620 |
|
621 } //namespace hugo |
327 } //namespace hugo |
622 |
328 |
623 |
329 |
624 |
330 |
625 |
331 |