lemon/bits/bpugraph_extender.h
changeset 2116 b6a68c15a6a3
equal deleted inserted replaced
0:24100da4e2e3 -1:000000000000
     1 /* -*- C++ -*-
       
     2  *
       
     3  * This file is a part of LEMON, a generic C++ optimization library
       
     4  *
       
     5  * Copyright (C) 2003-2006
       
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
       
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
       
     8  *
       
     9  * Permission to use, modify and distribute this software is granted
       
    10  * provided that this copyright notice appears in all copies. For
       
    11  * precise terms see the accompanying LICENSE file.
       
    12  *
       
    13  * This software is provided "AS IS" with no warranty of any kind,
       
    14  * express or implied, and with no claim as to its suitability for any
       
    15  * purpose.
       
    16  *
       
    17  */
       
    18 
       
    19 #ifndef LEMON_BITS_BPUGRAPH_EXTENDER_H
       
    20 #define LEMON_BITS_BPUGRAPH_EXTENDER_H
       
    21 
       
    22 #include <lemon/bits/invalid.h>
       
    23 #include <lemon/error.h>
       
    24 
       
    25 #include <lemon/bits/map_extender.h>
       
    26 #include <lemon/bits/default_map.h>
       
    27 
       
    28 #include <lemon/concept_check.h>
       
    29 #include <lemon/concept/maps.h>
       
    30 
       
    31 ///\ingroup graphbits
       
    32 ///\file
       
    33 ///\brief Extenders for the graph types
       
    34 namespace lemon {
       
    35 
       
    36   /// \ingroup graphbits
       
    37   ///
       
    38   /// \brief Extender for the BpUGraphs
       
    39   template <typename Base>
       
    40   class BpUGraphExtender : public Base {
       
    41   public:
       
    42     typedef Base Parent;
       
    43     typedef BpUGraphExtender Graph;
       
    44 
       
    45     typedef typename Parent::Node Node;
       
    46     typedef typename Parent::UEdge UEdge;
       
    47 
       
    48 
       
    49     using Parent::first;
       
    50     using Parent::next;
       
    51 
       
    52     using Parent::id;
       
    53 
       
    54     class ANode : public Node {
       
    55       friend class BpUGraphExtender;
       
    56     public:
       
    57       ANode() {}
       
    58       ANode(const Node& node) : Node(node) {
       
    59 	LEMON_ASSERT(Parent::aNode(node) || node == INVALID, 
       
    60 		     typename Parent::NodeSetError());
       
    61       }
       
    62       ANode(Invalid) : Node(INVALID) {}
       
    63     };
       
    64 
       
    65     void first(ANode& node) const {
       
    66       Parent::firstANode(static_cast<Node&>(node));
       
    67     }
       
    68     void next(ANode& node) const {
       
    69       Parent::nextANode(static_cast<Node&>(node));
       
    70     }
       
    71 
       
    72     int id(const ANode& node) const {
       
    73       return Parent::aNodeId(node);
       
    74     }
       
    75 
       
    76     class BNode : public Node {
       
    77       friend class BpUGraphExtender;
       
    78     public:
       
    79       BNode() {}
       
    80       BNode(const Node& node) : Node(node) {
       
    81 	LEMON_ASSERT(Parent::bNode(node) || node == INVALID,
       
    82 		     typename Parent::NodeSetError());
       
    83       }
       
    84       BNode(Invalid) : Node(INVALID) {}
       
    85     };
       
    86 
       
    87     void first(BNode& node) const {
       
    88       Parent::firstBNode(static_cast<Node&>(node));
       
    89     }
       
    90     void next(BNode& node) const {
       
    91       Parent::nextBNode(static_cast<Node&>(node));
       
    92     }
       
    93   
       
    94     int id(const BNode& node) const {
       
    95       return Parent::aNodeId(node);
       
    96     }
       
    97 
       
    98     Node source(const UEdge& edge) const {
       
    99       return aNode(edge);
       
   100     }
       
   101     Node target(const UEdge& edge) const {
       
   102       return bNode(edge);
       
   103     }
       
   104 
       
   105     void firstInc(UEdge& edge, bool& direction, const Node& node) const {
       
   106       if (Parent::aNode(node)) {
       
   107 	Parent::firstFromANode(edge, node);
       
   108 	direction = true;
       
   109       } else {
       
   110 	Parent::firstFromBNode(edge, node);
       
   111 	direction = static_cast<UEdge&>(edge) == INVALID;
       
   112       }
       
   113     }
       
   114     void nextInc(UEdge& edge, bool& direction) const {
       
   115       if (direction) {
       
   116 	Parent::nextFromANode(edge);
       
   117       } else {
       
   118 	Parent::nextFromBNode(edge);
       
   119 	if (edge == INVALID) direction = true;
       
   120       }
       
   121     }
       
   122 
       
   123     class Edge : public UEdge {
       
   124       friend class BpUGraphExtender;
       
   125     protected:
       
   126       bool forward;
       
   127 
       
   128       Edge(const UEdge& edge, bool _forward)
       
   129 	: UEdge(edge), forward(_forward) {}
       
   130 
       
   131     public:
       
   132       Edge() {}
       
   133       Edge (Invalid) : UEdge(INVALID), forward(true) {}
       
   134       bool operator==(const Edge& i) const {
       
   135 	return UEdge::operator==(i) && forward == i.forward;
       
   136       }
       
   137       bool operator!=(const Edge& i) const {
       
   138 	return UEdge::operator!=(i) || forward != i.forward;
       
   139       }
       
   140       bool operator<(const Edge& i) const {
       
   141 	return UEdge::operator<(i) || 
       
   142 	  (!(i.forward<forward) && UEdge(*this)<UEdge(i));
       
   143       }
       
   144     };
       
   145 
       
   146     void first(Edge& edge) const {
       
   147       Parent::first(static_cast<UEdge&>(edge));
       
   148       edge.forward = true;
       
   149     }
       
   150 
       
   151     void next(Edge& edge) const {
       
   152       if (!edge.forward) {
       
   153 	Parent::next(static_cast<UEdge&>(edge));
       
   154       }
       
   155       edge.forward = !edge.forward;
       
   156     }
       
   157 
       
   158     void firstOut(Edge& edge, const Node& node) const {
       
   159       if (Parent::aNode(node)) {
       
   160 	Parent::firstFromANode(edge, node);
       
   161 	edge.forward = true;
       
   162       } else {
       
   163 	Parent::firstFromBNode(edge, node);
       
   164 	edge.forward = static_cast<UEdge&>(edge) == INVALID;
       
   165       }
       
   166     }
       
   167     void nextOut(Edge& edge) const {
       
   168       if (edge.forward) {
       
   169 	Parent::nextFromANode(edge);
       
   170       } else {
       
   171 	Parent::nextFromBNode(edge);
       
   172         edge.forward = static_cast<UEdge&>(edge) == INVALID;
       
   173       }
       
   174     }
       
   175 
       
   176     void firstIn(Edge& edge, const Node& node) const {
       
   177       if (Parent::bNode(node)) {
       
   178 	Parent::firstFromBNode(edge, node);
       
   179 	edge.forward = true;	
       
   180       } else {
       
   181 	Parent::firstFromANode(edge, node);
       
   182 	edge.forward = static_cast<UEdge&>(edge) == INVALID;
       
   183       }
       
   184     }
       
   185     void nextIn(Edge& edge) const {
       
   186       if (edge.forward) {
       
   187 	Parent::nextFromBNode(edge);
       
   188       } else {
       
   189 	Parent::nextFromANode(edge);
       
   190 	edge.forward = static_cast<UEdge&>(edge) == INVALID;
       
   191       }
       
   192     }
       
   193 
       
   194     Node source(const Edge& edge) const {
       
   195       return edge.forward ? Parent::aNode(edge) : Parent::bNode(edge);
       
   196     }
       
   197     Node target(const Edge& edge) const {
       
   198       return edge.forward ? Parent::bNode(edge) : Parent::aNode(edge);
       
   199     }
       
   200 
       
   201     int id(const Edge& edge) const {
       
   202       return (Parent::id(static_cast<const UEdge&>(edge)) << 1) + 
       
   203         (edge.forward ? 0 : 1);
       
   204     }
       
   205     Edge edgeFromId(int id) const {
       
   206       return Edge(Parent::fromUEdgeId(id >> 1), (id & 1) == 0);
       
   207     }
       
   208     int maxEdgeId() const {
       
   209       return (Parent::maxUEdgeId(UEdge()) << 1) + 1;
       
   210     }
       
   211 
       
   212     bool direction(const Edge& edge) const {
       
   213       return edge.forward;
       
   214     }
       
   215 
       
   216     Edge direct(const UEdge& edge, bool direction) const {
       
   217       return Edge(edge, direction);
       
   218     }
       
   219 
       
   220     int edgeNum() const {
       
   221       return 2 * Parent::uEdgeNum();
       
   222     }
       
   223 
       
   224     int uEdgeNum() const {
       
   225       return Parent::uEdgeNum();
       
   226     }
       
   227 
       
   228     Node oppositeNode(const UEdge& edge, const Node& node) const {
       
   229       return source(edge) == node ? 
       
   230 	target(edge) : source(edge);
       
   231     }
       
   232 
       
   233     Edge direct(const UEdge& edge, const Node& node) const {
       
   234       return Edge(edge, node == Parent::source(edge));
       
   235     }
       
   236 
       
   237     Edge oppositeEdge(const Edge& edge) const {
       
   238       return Parent::direct(edge, !Parent::direction(edge));
       
   239     }
       
   240 
       
   241 
       
   242     int maxId(Node) const {
       
   243       return Parent::maxNodeId();
       
   244     }
       
   245     int maxId(BNode) const {
       
   246       return Parent::maxBNodeId();
       
   247     }
       
   248     int maxId(ANode) const {
       
   249       return Parent::maxANodeId();
       
   250     }
       
   251     int maxId(Edge) const {
       
   252       return maxEdgeId();
       
   253     }
       
   254     int maxId(UEdge) const {
       
   255       return Parent::maxUEdgeId();
       
   256     }
       
   257 
       
   258 
       
   259     Node fromId(int id, Node) const {
       
   260       return Parent::nodeFromId(id);
       
   261     }
       
   262     ANode fromId(int id, ANode) const {
       
   263       return Parent::fromANodeId(id);
       
   264     }
       
   265     BNode fromId(int id, BNode) const {
       
   266       return Parent::fromBNodeId(id);
       
   267     }
       
   268     Edge fromId(int id, Edge) const {
       
   269       return Parent::edgeFromId(id);
       
   270     }
       
   271     UEdge fromId(int id, UEdge) const {
       
   272       return Parent::uEdgeFromId(id);
       
   273     }  
       
   274   
       
   275     typedef AlterationNotifier<BpUGraphExtender, ANode> ANodeNotifier;
       
   276     typedef AlterationNotifier<BpUGraphExtender, BNode> BNodeNotifier;
       
   277     typedef AlterationNotifier<BpUGraphExtender, Node> NodeNotifier;
       
   278     typedef AlterationNotifier<BpUGraphExtender, Edge> EdgeNotifier;
       
   279     typedef AlterationNotifier<BpUGraphExtender, UEdge> UEdgeNotifier;
       
   280 
       
   281   protected:
       
   282 
       
   283     mutable ANodeNotifier anode_notifier;
       
   284     mutable BNodeNotifier bnode_notifier;
       
   285     mutable NodeNotifier node_notifier;
       
   286     mutable EdgeNotifier edge_notifier;
       
   287     mutable UEdgeNotifier uedge_notifier;
       
   288 
       
   289   public:
       
   290 
       
   291     NodeNotifier& getNotifier(Node) const {
       
   292       return node_notifier;
       
   293     }
       
   294 
       
   295     ANodeNotifier& getNotifier(ANode) const {
       
   296       return anode_notifier;
       
   297     }
       
   298 
       
   299     BNodeNotifier& getNotifier(BNode) const {
       
   300       return bnode_notifier;
       
   301     }
       
   302 
       
   303     EdgeNotifier& getNotifier(Edge) const {
       
   304       return edge_notifier;
       
   305     }
       
   306 
       
   307     UEdgeNotifier& getNotifier(UEdge) const {
       
   308       return uedge_notifier;
       
   309     }
       
   310 
       
   311     class NodeIt : public Node { 
       
   312       const Graph* graph;
       
   313     public:
       
   314     
       
   315       NodeIt() { }
       
   316     
       
   317       NodeIt(Invalid i) : Node(INVALID) { }
       
   318     
       
   319       explicit NodeIt(const Graph& _graph) : graph(&_graph) {
       
   320 	graph->first(static_cast<Node&>(*this));
       
   321       }
       
   322 
       
   323       NodeIt(const Graph& _graph, const Node& node) 
       
   324 	: Node(node), graph(&_graph) { }
       
   325     
       
   326       NodeIt& operator++() { 
       
   327 	graph->next(*this);
       
   328 	return *this; 
       
   329       }
       
   330 
       
   331     };
       
   332 
       
   333     class ANodeIt : public Node { 
       
   334       friend class BpUGraphExtender;
       
   335       const Graph* graph;
       
   336     public:
       
   337     
       
   338       ANodeIt() { }
       
   339     
       
   340       ANodeIt(Invalid i) : Node(INVALID) { }
       
   341     
       
   342       explicit ANodeIt(const Graph& _graph) : graph(&_graph) {
       
   343 	graph->firstANode(static_cast<Node&>(*this));
       
   344       }
       
   345 
       
   346       ANodeIt(const Graph& _graph, const Node& node) 
       
   347 	: Node(node), graph(&_graph) {}
       
   348     
       
   349       ANodeIt& operator++() { 
       
   350 	graph->nextANode(*this);
       
   351 	return *this; 
       
   352       }
       
   353     };
       
   354 
       
   355     class BNodeIt : public Node { 
       
   356       friend class BpUGraphExtender;
       
   357       const Graph* graph;
       
   358     public:
       
   359     
       
   360       BNodeIt() { }
       
   361     
       
   362       BNodeIt(Invalid i) : Node(INVALID) { }
       
   363     
       
   364       explicit BNodeIt(const Graph& _graph) : graph(&_graph) {
       
   365 	graph->firstBNode(static_cast<Node&>(*this));
       
   366       }
       
   367 
       
   368       BNodeIt(const Graph& _graph, const Node& node) 
       
   369 	: Node(node), graph(&_graph) {}
       
   370     
       
   371       BNodeIt& operator++() { 
       
   372 	graph->nextBNode(*this);
       
   373 	return *this; 
       
   374       }
       
   375     };
       
   376 
       
   377     class EdgeIt : public Edge { 
       
   378       friend class BpUGraphExtender;
       
   379       const Graph* graph;
       
   380     public:
       
   381     
       
   382       EdgeIt() { }
       
   383     
       
   384       EdgeIt(Invalid i) : Edge(INVALID) { }
       
   385     
       
   386       explicit EdgeIt(const Graph& _graph) : graph(&_graph) {
       
   387 	graph->first(static_cast<Edge&>(*this));
       
   388       }
       
   389 
       
   390       EdgeIt(const Graph& _graph, const Edge& edge) 
       
   391 	: Edge(edge), graph(&_graph) { }
       
   392     
       
   393       EdgeIt& operator++() { 
       
   394 	graph->next(*this);
       
   395 	return *this; 
       
   396       }
       
   397 
       
   398     };
       
   399 
       
   400     class UEdgeIt : public UEdge { 
       
   401       friend class BpUGraphExtender;
       
   402       const Graph* graph;
       
   403     public:
       
   404     
       
   405       UEdgeIt() { }
       
   406     
       
   407       UEdgeIt(Invalid i) : UEdge(INVALID) { }
       
   408     
       
   409       explicit UEdgeIt(const Graph& _graph) : graph(&_graph) {
       
   410 	graph->first(static_cast<UEdge&>(*this));
       
   411       }
       
   412 
       
   413       UEdgeIt(const Graph& _graph, const UEdge& edge) 
       
   414 	: UEdge(edge), graph(&_graph) { }
       
   415     
       
   416       UEdgeIt& operator++() { 
       
   417 	graph->next(*this);
       
   418 	return *this; 
       
   419       }
       
   420     };
       
   421 
       
   422     class OutEdgeIt : public Edge { 
       
   423       friend class BpUGraphExtender;
       
   424       const Graph* graph;
       
   425     public:
       
   426     
       
   427       OutEdgeIt() { }
       
   428     
       
   429       OutEdgeIt(Invalid i) : Edge(i) { }
       
   430     
       
   431       OutEdgeIt(const Graph& _graph, const Node& node) 
       
   432 	: graph(&_graph) {
       
   433 	graph->firstOut(*this, node);
       
   434       }
       
   435     
       
   436       OutEdgeIt(const Graph& _graph, const Edge& edge) 
       
   437 	: Edge(edge), graph(&_graph) {}
       
   438     
       
   439       OutEdgeIt& operator++() { 
       
   440 	graph->nextOut(*this);
       
   441 	return *this; 
       
   442       }
       
   443 
       
   444     };
       
   445 
       
   446 
       
   447     class InEdgeIt : public Edge { 
       
   448       friend class BpUGraphExtender;
       
   449       const Graph* graph;
       
   450     public:
       
   451     
       
   452       InEdgeIt() { }
       
   453     
       
   454       InEdgeIt(Invalid i) : Edge(i) { }
       
   455     
       
   456       InEdgeIt(const Graph& _graph, const Node& node) 
       
   457 	: graph(&_graph) {
       
   458 	graph->firstIn(*this, node);
       
   459       }
       
   460     
       
   461       InEdgeIt(const Graph& _graph, const Edge& edge) : 
       
   462 	Edge(edge), graph(&_graph) {}
       
   463     
       
   464       InEdgeIt& operator++() { 
       
   465 	graph->nextIn(*this);
       
   466 	return *this; 
       
   467       }
       
   468 
       
   469     };
       
   470   
       
   471     /// \brief Base node of the iterator
       
   472     ///
       
   473     /// Returns the base node (ie. the source in this case) of the iterator
       
   474     Node baseNode(const OutEdgeIt &e) const {
       
   475       return Parent::source((Edge&)e);
       
   476     }
       
   477     /// \brief Running node of the iterator
       
   478     ///
       
   479     /// Returns the running node (ie. the target in this case) of the
       
   480     /// iterator
       
   481     Node runningNode(const OutEdgeIt &e) const {
       
   482       return Parent::target((Edge&)e);
       
   483     }
       
   484   
       
   485     /// \brief Base node of the iterator
       
   486     ///
       
   487     /// Returns the base node (ie. the target in this case) of the iterator
       
   488     Node baseNode(const InEdgeIt &e) const {
       
   489       return Parent::target((Edge&)e);
       
   490     }
       
   491     /// \brief Running node of the iterator
       
   492     ///
       
   493     /// Returns the running node (ie. the source in this case) of the
       
   494     /// iterator
       
   495     Node runningNode(const InEdgeIt &e) const {
       
   496       return Parent::source((Edge&)e);
       
   497     }
       
   498   
       
   499     class IncEdgeIt : public Parent::UEdge { 
       
   500       friend class BpUGraphExtender;
       
   501       const Graph* graph;
       
   502       bool direction;
       
   503     public:
       
   504     
       
   505       IncEdgeIt() { }
       
   506     
       
   507       IncEdgeIt(Invalid i) : UEdge(i), direction(true) { }
       
   508     
       
   509       IncEdgeIt(const Graph& _graph, const Node &n) : graph(&_graph) {
       
   510 	graph->firstInc(*this, direction, n);
       
   511       }
       
   512 
       
   513       IncEdgeIt(const Graph& _graph, const UEdge &ue, const Node &n)
       
   514 	: graph(&_graph), UEdge(ue) {
       
   515 	direction = (graph->source(ue) == n);
       
   516       }
       
   517 
       
   518       IncEdgeIt& operator++() {
       
   519 	graph->nextInc(*this, direction);
       
   520 	return *this; 
       
   521       }
       
   522     };
       
   523   
       
   524 
       
   525     /// Base node of the iterator
       
   526     ///
       
   527     /// Returns the base node of the iterator
       
   528     Node baseNode(const IncEdgeIt &e) const {
       
   529       return e.direction ? source(e) : target(e);
       
   530     }
       
   531 
       
   532     /// Running node of the iterator
       
   533     ///
       
   534     /// Returns the running node of the iterator
       
   535     Node runningNode(const IncEdgeIt &e) const {
       
   536       return e.direction ? target(e) : source(e);
       
   537     }
       
   538 
       
   539     template <typename _Value>
       
   540     class ANodeMap 
       
   541       : public MapExtender<DefaultMap<Graph, ANode, _Value> > {
       
   542     public:
       
   543       typedef BpUGraphExtender Graph;
       
   544       typedef MapExtender<DefaultMap<Graph, ANode, _Value> > Parent;
       
   545     
       
   546       ANodeMap(const Graph& graph) 
       
   547 	: Parent(graph) {}
       
   548       ANodeMap(const Graph& graph, const _Value& value) 
       
   549 	: Parent(graph, value) {}
       
   550     
       
   551       ANodeMap& operator=(const ANodeMap& cmap) {
       
   552 	return operator=<ANodeMap>(cmap);
       
   553       }
       
   554     
       
   555       template <typename CMap>
       
   556       ANodeMap& operator=(const CMap& cmap) {
       
   557         Parent::operator=(cmap);
       
   558 	return *this;
       
   559       }
       
   560     
       
   561     };
       
   562 
       
   563     template <typename _Value>
       
   564     class BNodeMap 
       
   565       : public MapExtender<DefaultMap<Graph, BNode, _Value> > {
       
   566     public:
       
   567       typedef BpUGraphExtender Graph;
       
   568       typedef MapExtender<DefaultMap<Graph, BNode, _Value> > Parent;
       
   569     
       
   570       BNodeMap(const Graph& graph) 
       
   571 	: Parent(graph) {}
       
   572       BNodeMap(const Graph& graph, const _Value& value) 
       
   573 	: Parent(graph, value) {}
       
   574     
       
   575       BNodeMap& operator=(const BNodeMap& cmap) {
       
   576 	return operator=<BNodeMap>(cmap);
       
   577       }
       
   578     
       
   579       template <typename CMap>
       
   580       BNodeMap& operator=(const CMap& cmap) {
       
   581         Parent::operator=(cmap);
       
   582 	return *this;
       
   583       }
       
   584     
       
   585     };
       
   586 
       
   587   public:
       
   588 
       
   589     template <typename _Value>
       
   590     class NodeMap {
       
   591     public:
       
   592       typedef BpUGraphExtender Graph;
       
   593 
       
   594       typedef Node Key;
       
   595       typedef _Value Value;
       
   596 
       
   597       /// The reference type of the map;
       
   598       typedef typename ANodeMap<_Value>::Reference Reference;
       
   599       /// The const reference type of the map;
       
   600       typedef typename ANodeMap<_Value>::ConstReference ConstReference;
       
   601 
       
   602       typedef True ReferenceMapTag;
       
   603 
       
   604       NodeMap(const Graph& _graph) 
       
   605 	: graph(_graph), aNodeMap(_graph), bNodeMap(_graph) {}
       
   606       NodeMap(const Graph& _graph, const _Value& _value) 
       
   607 	: graph(_graph), aNodeMap(_graph, _value), bNodeMap(_graph, _value) {}
       
   608 
       
   609       NodeMap& operator=(const NodeMap& cmap) {
       
   610 	return operator=<NodeMap>(cmap);
       
   611       }
       
   612     
       
   613       template <typename CMap>
       
   614       NodeMap& operator=(const CMap& cmap) {
       
   615 	checkConcept<concept::ReadMap<Node, _Value>, CMap>();
       
   616 	const typename Parent::Notifier* notifier = Parent::getNotifier();
       
   617 	Edge it;
       
   618 	for (graph.first(it); it != INVALID; graph.next(it)) {
       
   619 	  Parent::set(it, cmap[it]);
       
   620 	}
       
   621 	return *this;
       
   622       }
       
   623 
       
   624       ConstReference operator[](const Key& node) const {
       
   625 	if (Parent::aNode(node)) {
       
   626 	  return aNodeMap[node];
       
   627 	} else {
       
   628 	  return bNodeMap[node];
       
   629 	}
       
   630       } 
       
   631 
       
   632       Reference operator[](const Key& node) {
       
   633 	if (Parent::aNode(node)) {
       
   634 	  return aNodeMap[node];
       
   635 	} else {
       
   636 	  return bNodeMap[node];
       
   637 	}
       
   638       }
       
   639 
       
   640       void set(const Key& node, const Value& value) {
       
   641 	if (Parent::aNode(node)) {
       
   642 	  aNodeMap.set(node, value);
       
   643 	} else {
       
   644 	  bNodeMap.set(node, value);
       
   645 	}
       
   646       }
       
   647 
       
   648       class MapIt : public NodeIt {
       
   649       public:
       
   650 
       
   651         typedef NodeIt Parent;
       
   652         
       
   653         explicit MapIt(NodeMap& _map) 
       
   654           : Parent(_map.graph), map(_map) {}
       
   655         
       
   656         typename MapTraits<NodeMap>::ConstReturnValue operator*() const {
       
   657           return map[*this];
       
   658         }
       
   659         
       
   660         typename MapTraits<NodeMap>::ReturnValue operator*() {
       
   661           return map[*this];
       
   662         }
       
   663         
       
   664         void set(const Value& value) {
       
   665           map.set(*this, value);
       
   666         }
       
   667 
       
   668       private:
       
   669         NodeMap& map;
       
   670       };
       
   671 
       
   672       class ConstMapIt : public NodeIt {
       
   673       public:
       
   674 
       
   675         typedef NodeIt Parent;
       
   676         
       
   677         explicit ConstMapIt(const NodeMap& _map) 
       
   678           : Parent(_map.graph), map(_map) {}
       
   679         
       
   680         typename MapTraits<NodeMap>::ConstReturnValue operator*() const {
       
   681           return map[*this];
       
   682         }
       
   683         
       
   684       private:
       
   685         const NodeMap& map;
       
   686       };
       
   687 
       
   688       class ItemIt : public NodeIt {
       
   689       public:
       
   690 
       
   691         typedef NodeIt Parent;
       
   692 
       
   693         explicit ItemIt(const NodeMap& _map)
       
   694           : Parent(_map.graph) {}
       
   695         
       
   696       };
       
   697       
       
   698     private:
       
   699       const Graph& graph;
       
   700       ANodeMap<_Value> aNodeMap;
       
   701       BNodeMap<_Value> bNodeMap;
       
   702     };
       
   703     
       
   704 
       
   705     template <typename _Value>
       
   706     class EdgeMap 
       
   707       : public MapExtender<DefaultMap<Graph, Edge, _Value> > {
       
   708     public:
       
   709       typedef BpUGraphExtender Graph;
       
   710       typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
       
   711     
       
   712       EdgeMap(const Graph& graph) 
       
   713 	: Parent(graph) {}
       
   714       EdgeMap(const Graph& graph, const _Value& value) 
       
   715 	: Parent(graph, value) {}
       
   716     
       
   717       EdgeMap& operator=(const EdgeMap& cmap) {
       
   718 	return operator=<EdgeMap>(cmap);
       
   719       }
       
   720     
       
   721       template <typename CMap>
       
   722       EdgeMap& operator=(const CMap& cmap) {
       
   723         Parent::operator=(cmap);
       
   724 	return *this;
       
   725       }
       
   726     };
       
   727 
       
   728     template <typename _Value>
       
   729     class UEdgeMap 
       
   730       : public MapExtender<DefaultMap<Graph, UEdge, _Value> > {
       
   731     public:
       
   732       typedef BpUGraphExtender Graph;
       
   733       typedef MapExtender<DefaultMap<Graph, UEdge, _Value> > Parent;
       
   734     
       
   735       UEdgeMap(const Graph& graph) 
       
   736 	: Parent(graph) {}
       
   737       UEdgeMap(const Graph& graph, const _Value& value) 
       
   738 	: Parent(graph, value) {}
       
   739     
       
   740       UEdgeMap& operator=(const UEdgeMap& cmap) {
       
   741 	return operator=<UEdgeMap>(cmap);
       
   742       }
       
   743     
       
   744       template <typename CMap>
       
   745       UEdgeMap& operator=(const CMap& cmap) {
       
   746         Parent::operator=(cmap);
       
   747 	return *this;
       
   748       }
       
   749     };
       
   750 
       
   751   
       
   752     Node addANode() {
       
   753       Node node = Parent::addANode();
       
   754       getNotifier(ANode()).add(node);
       
   755       getNotifier(Node()).add(node);
       
   756       return node;
       
   757     }
       
   758 
       
   759     Node addBNode() {
       
   760       Node node = Parent::addBNode();
       
   761       getNotifier(BNode()).add(node);
       
   762       getNotifier(Node()).add(node);
       
   763       return node;
       
   764     }
       
   765   
       
   766     UEdge addEdge(const Node& source, const Node& target) {
       
   767       UEdge uedge = Parent::addEdge(source, target);
       
   768       getNotifier(UEdge()).add(uedge);
       
   769     
       
   770       std::vector<Edge> edges;
       
   771       edges.push_back(direct(uedge, true));
       
   772       edges.push_back(direct(uedge, false));
       
   773       getNotifier(Edge()).add(edges);
       
   774     
       
   775       return uedge;
       
   776     }
       
   777 
       
   778     void clear() {
       
   779       getNotifier(Edge()).clear();
       
   780       getNotifier(UEdge()).clear();
       
   781       getNotifier(Node()).clear();
       
   782       getNotifier(BNode()).clear();
       
   783       getNotifier(ANode()).clear();
       
   784       Parent::clear();
       
   785     }
       
   786 
       
   787     void erase(const Node& node) {
       
   788       UEdge uedge;
       
   789       if (Parent::aNode(node)) {
       
   790         Parent::firstFromANode(uedge, node);
       
   791         while (uedge != INVALID) {
       
   792           erase(uedge);
       
   793           Parent::firstFromANode(uedge, node);
       
   794         }
       
   795       } else {
       
   796         Parent::firstFromBNode(uedge, node);
       
   797         while (uedge != INVALID) {
       
   798           erase(uedge);
       
   799           Parent::firstFromBNode(uedge, node);
       
   800         }
       
   801       }
       
   802 
       
   803       getNotifier(Node()).erase(node);
       
   804       Parent::erase(node);
       
   805     }
       
   806     
       
   807     void erase(const UEdge& uedge) {
       
   808       std::vector<Edge> edges;
       
   809       edges.push_back(direct(uedge, true));
       
   810       edges.push_back(direct(uedge, false));
       
   811       getNotifier(Edge()).erase(edges);
       
   812       getNotifier(UEdge()).erase(uedge);
       
   813       Parent::erase(uedge);
       
   814     }
       
   815 
       
   816 
       
   817     BpUGraphExtender() {
       
   818       anode_notifier.setContainer(*this); 
       
   819       bnode_notifier.setContainer(*this); 
       
   820       node_notifier.setContainer(*this); 
       
   821       edge_notifier.setContainer(*this); 
       
   822       uedge_notifier.setContainer(*this);
       
   823     } 
       
   824 
       
   825     ~BpUGraphExtender() {
       
   826       uedge_notifier.clear();
       
   827       edge_notifier.clear(); 
       
   828       node_notifier.clear(); 
       
   829       anode_notifier.clear(); 
       
   830       bnode_notifier.clear(); 
       
   831     }
       
   832 
       
   833 
       
   834   };
       
   835 
       
   836 }
       
   837 
       
   838 #endif