//==================================================================================================
// G r a p h                                                                              Interface
// S t r u c t u r e
//                                                                                By Bruno Bachelet
//==================================================================================================
// Copyright (c) 1999-2016
// Bruno Bachelet - bruno@nawouak.net - http://www.nawouak.net
//
// This file is part of the B++ Library. This library is free software; you can redistribute it
// and/or modify it under the terms of the GNU Library General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
// the GNU Library General Public License for more details (http://www.gnu.org).

/*DESCRIPTION*/
/* This module defines the structure of a graph. */

// File Name //-------------------------------------------------------------------------------------
#line __LINE__ "graph/structure.hpp"

// Guardian //--------------------------------------------------------------------------------------
#ifndef guGraphStructure
#define guGraphStructure

// Headers //---------------------------------------------------------------------------------------
#include <bpp/data_structure.hpp> /*INCLUDE*/

namespace bpp {

// Importation/Exportation //-----------------------------------------------------------------------
#ifdef GRAPH_DLL
 #define dll_export DLL_EXPORT
#else
 #define dll_export DLL_IMPORT
#endif

// Namespaces //------------------------------------------------------------------------------------
#define public_area  graphStructure
#define private_area graphStructure_private

namespace public_area  { /*NAMESPACE*/ using namespace dataStructureDataTemplate; }
namespace private_area { using namespace public_area; }

extern_module_name;

// Initialization //--------------------------------------------------------------------------------
#define iniGraphStructure
has_initializer;

// Macrocommands //---------------------------------------------------------------------------------
/*ALIAS*/
#define tdGraph class prArcData,class prNodeData //

/*ALIAS*/
#define tuGraph prArcData,prNodeData //

// Types & Classes //-------------------------------------------------------------------------------
namespace public_area  {
 //------------------------------------------------------------------------------------------Classes
 template <tdGraph> class clArc;
 template <tdGraph> class clGraph;
 template <tdGraph> class clNode;
 //-----------------------------------------------------------------------------------Variable Types
 /*TYPE*/ /* Key to identify a node in a graph. */
 typedef tyCardinal tyNodeKey;

 /*TYPE*/ /* Key to identify an arc in a graph. */
 typedef tyCardinal tyArcKey;

 /*TYPE*/ /* Arc of a generic graph. */
 typedef clArc<clGenericData,clGenericData> clGenericArc;

 /*TYPE*/ /* Generic graph. */
 typedef clGraph<clGenericData,clGenericData> clGenericGraph;

 /*TYPE*/ /* Node of a generic graph. */
 typedef clNode<clGenericData,clGenericData> clGenericNode;

 /*TYPE*/ /* Pair of real numbers. */
 typedef std_pair(tyReal,tyReal) tyPairReal;
 //-----------------------------------------------------------------------------------Constant Types
 typedef const tyArcKey  tcArcKey;
 typedef const tyNodeKey tcNodeKey;

 typedef const clGenericArc   ctGenericArc;
 typedef const clGenericGraph ctGenericGraph;
 typedef const clGenericNode  ctGenericNode;

 typedef const tyPairReal tcPairReal;
}

namespace private_area {}

// Functions Interface //---------------------------------------------------------------------------
namespace public_area  {
 template <tdGraph> clOutStream & operator << (clOutStream &,const clArc<tuGraph> &);
 template <tdGraph> clOutStream & operator << (clOutStream &,const clGraph<tuGraph> &);
 template <tdGraph> clOutStream & operator << (clOutStream &,const clNode<tuGraph> &);
 template <tdGraph> clOutStream & operator << (clOutStream &,const std_vector(clArc<tuGraph> *) &);
 template <tdGraph> clOutStream & operator << (clOutStream &,const std_vector(clNode<tuGraph> *) &);
 template <tdGraph> clInStream & operator >> (clInStream &,clGraph<tuGraph> &);

 inline tyArcKey  arcKey(ctString &);
 inline tyNodeKey nodeKey(ctString &);

 template <tdGraph,class prData> void deleteNodeWorkspace(clGraph<tuGraph> &,const prData &);
 template <tdGraph,class prData> void deleteArcWorkspace(clGraph<tuGraph> &,const prData &);
}

namespace private_area { testing_mode ( function void test(void); ) }

// Errors //----------------------------------------------------------------------------------------
namespace public_area {
 /*ERROR*/ extern_error erArcExtremityNotFixed; /* An arc extremity is not fixed. */
 /*ERROR*/ extern_error erArcKeyAlreadyExists; /* An arc already has this key in the graph. */
 /*ERROR*/ extern_error erInvalidArcKey; /* No arc has this key in the graph. */
 /*ERROR*/ extern_error erInvalidNodeKey; /* No node has this key in the graph. */
 /*ERROR*/ extern_error erNodeKeyAlreadyExists; /* A node already has this key in the graph. */
}

// Constants & Variables //-------------------------------------------------------------------------
/*CONSTANT*/ /* Arc key that is never used and represents no arc. */
extern_static_constant(public,tyArcKey,goNilArc,nilArc);

/*CONSTANT*/ /* Node key that is never used and represents no node. */
extern_static_constant(public,tyNodeKey,goNilNode,nilNode);

extern_static_constant(private,tcString,goArcFlag,?);
extern_static_constant(private,tcString,goArcsEndFlag,?);
extern_static_constant(private,tcString,goArcsStartFlag,?);
extern_static_constant(private,tcString,goGraphEndFlag,?);
extern_static_constant(private,tcString,goGraphStartFlag,?);
extern_static_constant(private,tcString,goNbArcsFlag,?);
extern_static_constant(private,tcString,goNbNodesFlag,?);
extern_static_constant(private,tcString,goNodeFlag,?);
extern_static_constant(private,tcString,goNodesEndFlag,?);
extern_static_constant(private,tcString,goNodesStartFlag,?);
extern_static_constant(private,tcString,goNoArcFlag,?);
extern_static_constant(private,tcString,goNoNodeFlag,?);
extern_static_constant(private,tcString,goSolvedFlag,?);

// A r c  Interface //------------------------------------------------------------------------------
namespace public_area {
 /*CLASS clArc */
 /* Represents an arc of a graph. The first parameter of the template is the type of data the arcs
    carry and the second one is the type of data the nodes carry. */
 template <tdGraph> class clArc {
  //-------------------------------------------------------------------------------------------Types
  /*TYPE clArc */ /* This class. */
  public_property typedef clArc<tuGraph> cpArc;

  /*TYPE clArc */ /* Type of the nodes the arc links. */
  public_property typedef clNode<tuGraph> cpNode;

  /*TYPE clArc */ /* Type of graph the arc belongs to. */
  public_property typedef clGraph<tuGraph> cpGraph;

  /*TYPE clArc */ /* List of arcs with their key. */
  public_property typedef std_map(tyArcKey,cpArc *) cpArcX;

  /*TYPE clArc */ /* List of nodes with their key. */
  public_property typedef std_map(tyNodeKey,cpNode *) cpNodeX;

  private_property typedef cpNode * cpNodeP;
  //-----------------------------------------------------------------------------------------Private
  private_property cpGraph & atGraph;

  private_property constructor clArc(const cpArc &);
  //------------------------------------------------------------------------------------------Public
  /*ATTRIBUTE clArc */ /* Key of the arc. */
  read_only_attribute(tyArcKey,atKey,key);

  /*ATTRIBUTE clArc */ /* Mark used by some algorithms. */
  read_write_attribute(tyMark,atMark,mark);

  /*ATTRIBUTE clArc */ /* Data carried by the arc. */
  read_write_attribute(prArcData,atData,data);

  /*ATTRIBUTE clArc */ /* Pointer to a workspace. Used and managed by some algorithms. */
  read_write_attribute(tyPointer,atWork,work);

  /*ATTRIBUTE clArc */ /* Pointer to the node pointed by the source extremity of the arc. */
  read_only_attribute(cpNodeP,atSourceNode,sourceNode);

  /*ATTRIBUTE clArc */ /* Pointer to the node pointed by the target extremity of the arc. */
  read_only_attribute(cpNodeP,atTargetNode,targetNode);

  public_property cpGraph & graph(void);
  public_property const cpGraph & graph(void) const;

  public_property constructor clArc(cpGraph &,const cpArc &);
  public_property constructor clArc(cpGraph &,tyArcKey,const prArcData &,tyNodeKey=nilNode(),
                                    tyNodeKey=nilNode());
  public_property constructor clArc(cpGraph &,tyArcKey,clInStream &,tyNodeKey=nilNode(),
                                    tyNodeKey=nilNode());
  public_property destructor  clArc(void);

  public_property cpArc & operator = (const cpArc &);

  public_property void setSourceNode(cpNode *);
  public_property void setTargetNode(cpNode *);

  public_property void changeKey(tyArcKey);
  public_property void reverse(void);
 };
}

// G r a p h  Interface //--------------------------------------------------------------------------
namespace public_area {
 /*CLASS clGraph */
 /* Represents a graph. The first parameter of the template is the type of data the arcs carry and
    the second one is the type of data the nodes carry. */
 template <tdGraph> class clGraph {
  //-------------------------------------------------------------------------------------------Types
  /*TYPE clGraph */ /* Type of the arcs the graph contains. */
  public_property typedef clArc<tuGraph> cpArc;

  /*TYPE clGraph */ /* Type of the nodes the graph contains. */
  public_property typedef clNode<tuGraph> cpNode;

  /*TYPE clGraph */ /* This class. */
  public_property typedef clGraph<tuGraph> cpGraph;

  /*TYPE clGraph */ /* List of arcs with their key. */
  public_property typedef std_map(tyArcKey,cpArc *) cpArcX;

  /*TYPE clGraph */ /* List of nodes with their key. */
  public_property typedef std_map(tyNodeKey,cpNode *) cpNodeX;
  //-----------------------------------------------------------------------------------------Friends
  friend class clArc<tuGraph>;
  friend class clNode<tuGraph>;
  //-----------------------------------------------------------------------------------------Private
  private_property void copy(const cpGraph &);
  //------------------------------------------------------------------------------------------Public
  /*ATTRIBUTE clGraph */ /* Indicates if the graph is solved according to a problem. */
  read_write_attribute(tyBoolean,atSolved,solved);

  /*ATTRIBUTE clGraph */ /* Mark used by some algorithms. */
  read_write_attribute(tyMark,atMark,mark);

  /*ATTRIBUTE clGraph */ /* Arcs of the graph. */
  read_only_attribute(cpArcX,atArcX,arcs);

  /*ATTRIBUTE clGraph */ /* Nodes of the graph. */
  read_only_attribute(cpNodeX,atNodeX,nodes);

  public_property constructor clGraph(void);
  public_property constructor clGraph(const cpGraph &);
  public_property destructor  clGraph(void);

  public_property cpGraph & operator = (const cpGraph &);

  public_property cpArc &        arc(tyArcKey);
  public_property const cpArc &  arc(tyArcKey) const;
  public_property void           clear(void);
  public_property tyArcKey       getNewArcKey(void) const;
  public_property tyNodeKey      getNewNodeKey(void) const;
  public_property cpNode &       mergeNodes(cpNode &,cpNode &);
  public_property cpNode &       mergeNodes(tyNodeKey,tyNodeKey);
  public_property cpNode &       node(tyNodeKey);
  public_property const cpNode & node(tyNodeKey) const;
  public_property void           numberKeys(void);
  public_property void           removeArcs(void);
  public_property void           removeNodes(void);
 };
}

// N o d e  Interface //----------------------------------------------------------------------------
namespace public_area {
 /*CLASS clNode */
 /* Represents a node of a graph. The first parameter of the template is the type of data the arcs
    carry and the second one is the type of data the nodes carry. */
 template <tdGraph> class clNode {
  //-------------------------------------------------------------------------------------------Types
  /*TYPE clNode */ /* Type of the arcs the node is associated with. */
  public_property typedef clArc<tuGraph> cpArc;

  /*TYPE clNode */ /* This class. */
  public_property typedef clNode<tuGraph> cpNode;

  /*TYPE clNode */ /* Type of graph the node belongs to. */
  public_property typedef clGraph<tuGraph> cpGraph;

  /*TYPE clNode */ /* List of arcs with their key. */
  public_property typedef std_map(tyArcKey,cpArc *) cpArcX;

  /*TYPE clNode */ /* List of nodes with their key. */
  public_property typedef std_map(tyNodeKey,cpNode *) cpNodeX;
  //-----------------------------------------------------------------------------------------Friends
  friend class clArc<tuGraph>;
  //-----------------------------------------------------------------------------------------Private
  private_property cpGraph & atGraph;

  private_property constructor clNode(const cpNode &);
  //------------------------------------------------------------------------------------------Public
  /*ATTRIBUTE clNode */ /* Key of the node. */
  read_only_attribute(tyNodeKey,atKey,key);

  /*ATTRIBUTE clNode */ /* Mark used by some algorithms. */
  read_write_attribute(tyMark,atMark,mark);

  /*ATTRIBUTE clNode */ /* Data carried by the node. */
  read_write_attribute(prNodeData,atData,data);

  /*ATTRIBUTE clNode */ /* Pointer to a workspace. Used and managed by some algorithms. */
  read_write_attribute(tyPointer,atWork,work);

  /*ATTRIBUTE clNode */ /* Arcs incoming to the node. */
  read_only_attribute(cpArcX,atIncomingArcX,incomingArcs);

  /*ATTRIBUTE clNode */ /* Arcs outgoing from the node. */
  read_only_attribute(cpArcX,atOutgoingArcX,outgoingArcs);

  public_property cpGraph & graph(void);
  public_property const cpGraph & graph(void) const;

  public_property constructor clNode(cpGraph &,const cpNode &);
  public_property constructor clNode(cpGraph &,tyNodeKey,const prNodeData &);
  public_property constructor clNode(cpGraph &,tyNodeKey,clInStream &);
  public_property destructor  clNode(void);

  public_property cpNode & operator = (const cpNode &);

  public_property cpArc &       incomingArc(tyArcKey);
  public_property const cpArc & incomingArc(tyArcKey) const;
  public_property cpArc &       outgoingArc(tyArcKey);
  public_property const cpArc & outgoingArc(tyArcKey) const;

  public_property void changeKey(tyNodeKey);
 };
}

// Functions Inline //------------------------------------------------------------------------------
namespace public_area  {
 //---------------------------------------------------------------------------------String To ArcKey
 /*FUNCTION*/ /* Converts a string into an arc key. */
 inline tyArcKey arcKey(ctString & agString) {
  if (agString==private_area::goNoArcFlag) return (nilArc());
  return (cardinal(agString.data()));
 }
 //--------------------------------------------------------------------------------String To NodeKey
 /*FUNCTION*/ /* Converts a string into a node key. */
 inline tyNodeKey nodeKey(ctString & agString) {
  if (agString==private_area::goNoNodeFlag) return (nilNode());
  return (cardinal(agString.data()));
 }
}

namespace private_area {}

// A r c  Inline //---------------------------------------------------------------------------------
namespace public_area {
 //--------------------------------------------------------------------------------------------Graph
 /*METHOD clArc */ /* Returns the graph that contains the arc. */
 template <tdGraph> inline clGraph<tuGraph> & clArc<tuGraph>::graph(void) { return (atGraph); }
 //--------------------------------------------------------------------------------------------Graph
 /*METHOD clArc */ /* Returns the graph that contains the arc. */
 template <tdGraph> inline const clGraph<tuGraph> & clArc<tuGraph>::graph(void) const
 { return (atGraph); }
 //---------------------------------------------------------------------------------------Destructor
 /*METHOD clArc */ /* Destructs the arc. The graph that contained it is updated. */
 template <tdGraph> inline clArc<tuGraph>::~clArc(void) {
  atGraph.atArcX.erase(atKey);
  setSourceNode(nil);
  setTargetNode(nil);
 }
 //------------------------------------------------------------------------------------SetSourceNode
 /*METHOD clArc */ /* Sets the source node of the arc. The graph that contains it is updated. */
 template <tdGraph> inline void clArc<tuGraph>::setSourceNode(cpNode * agNode) {
  if (atSourceNode!=nil) atSourceNode->atOutgoingArcX.erase(atKey);
  atSourceNode=agNode;
  if (agNode!=nil) agNode->atOutgoingArcX.insert(std_make_pair(atKey,this));
 }
 //------------------------------------------------------------------------------------SetTargetNode
 /*METHOD clArc */ /* Sets the target node of the arc. The graph that contains it is updated. */
 template <tdGraph> inline void clArc<tuGraph>::setTargetNode(cpNode * agNode) {
  if (atTargetNode!=nil) atTargetNode->atIncomingArcX.erase(atKey);
  atTargetNode=agNode;
  if (agNode!=nil) agNode->atIncomingArcX.insert(std_make_pair(atKey,this));
 }
 //------------------------------------------------------------------------------------------Reverse
 /*METHOD clArc */
 /* Reverses the target and the source nodes of the arc. The graph that contains it is updated. */
 template <tdGraph> inline void clArc<tuGraph>::reverse(void) {
  clNode<tuGraph> * lcTempo = atSourceNode;

  setSourceNode(atTargetNode);
  setTargetNode(lcTempo);
 }
}

// G r a p h  Inline //-----------------------------------------------------------------------------
namespace public_area {
 //--------------------------------------------------------------------------------------Constructor
 /*METHOD clGraph */ /* Builds an empty graph. */
 template <tdGraph> inline clGraph<tuGraph>::clGraph(void)
 : atSolved(false),atMark(firstMark()),atArcX(),atNodeX() {}
 //--------------------------------------------------------------------------------------Constructor
 /*METHOD clGraph */ /* Builds and copies a graph. */
 template <tdGraph> inline clGraph<tuGraph>::clGraph(const cpGraph & agGraph)
 : atSolved(),atMark(firstMark()),atArcX(),atNodeX()
 { copy(agGraph); }
 //---------------------------------------------------------------------------------------Destructor
 /*METHOD clGraph */ /* Destructs a graph. */
 template <tdGraph> inline clGraph<tuGraph>::~clGraph(void) { clear(); }
 //----------------------------------------------------------------------------------------------Arc
 /*METHOD clGraph */ /* Returns the arc in the graph identified by a given key. */
 template <tdGraph>
 inline typename clGraph<tuGraph>::cpArc & clGraph<tuGraph>::arc(tyArcKey agKey) {
  typename cpArcX::const_iterator lcIterator = atArcX.find(agKey);

  if (lcIterator==atArcX.end()) send_inline_error(erInvalidArcKey,"graph::arc");
  return (*(lcIterator->second));
 }
 //----------------------------------------------------------------------------------------------Arc
 /*METHOD clGraph */ /* Returns the arc in the graph identified by a given key. */
 template <tdGraph>
 inline const typename clGraph<tuGraph>::cpArc & clGraph<tuGraph>::arc(tyArcKey agKey) const {
  typename cpArcX::const_iterator lcIterator = atArcX.find(agKey);

  if (lcIterator==atArcX.end()) send_inline_error(erInvalidArcKey,"graph::arc");
  return (*(lcIterator->second));
 }
 //--------------------------------------------------------------------------------------------Clear
 /*METHOD clGraph */ /* Removes all the nodes and arcs from the graph. */
 template <tdGraph> inline void clGraph<tuGraph>::clear(void) {
  removeNodes();
  removeArcs();
 }
 //---------------------------------------------------------------------------------------MergeNodes
 /*METHOD clGraph */ /* Merges two nodes. */
 template <tdGraph>
 inline typename clGraph<tuGraph>::cpNode & clGraph<tuGraph>::mergeNodes(tyNodeKey agNode1,
                                                                         tyNodeKey agNode2)
 { return (mergeNodes(*(atNodeX[agNode1]),*(atNodeX[agNode2]))); }
 //---------------------------------------------------------------------------------------------Node
 /*METHOD clGraph */ /* Returns the node in the graph identified by a given key. */
 template <tdGraph>
 inline typename clGraph<tuGraph>::cpNode & clGraph<tuGraph>::node(tyNodeKey agKey) {
  typename cpNodeX::const_iterator lcIterator = atNodeX.find(agKey);

  if (lcIterator==atNodeX.end()) send_inline_error(erInvalidNodeKey,"graph::node");
  return (*(lcIterator->second));
 }
 //---------------------------------------------------------------------------------------------Node
 /*METHOD clGraph */ /* Returns the node in the graph identified by a given key. */
 template <tdGraph>
 inline const typename clGraph<tuGraph>::cpNode & clGraph<tuGraph>::node(tyNodeKey agKey) const {
  typename cpNodeX::const_iterator lcIterator = atNodeX.find(agKey);

  if (lcIterator==atNodeX.end()) send_inline_error(erInvalidNodeKey,"graph::node");
  return (*(lcIterator->second));
 }
}

// N o d e  Inline //-------------------------------------------------------------------------------
namespace public_area {
 //--------------------------------------------------------------------------------------------Graph
 /*METHOD clNode */ /* Returns the graph that contains the node. */
 template <tdGraph> inline clGraph<tuGraph> & clNode<tuGraph>::graph(void) { return (atGraph); }
 //--------------------------------------------------------------------------------------------Graph
 /*METHOD clNode */ /* Returns the graph that contains the node. */
 template <tdGraph> inline const clGraph<tuGraph> & clNode<tuGraph>::graph(void) const
 { return (atGraph); }
 //--------------------------------------------------------------------------------------IncomingArc
 /*METHOD clNode */ /* Returns the incoming arc of the node identified by a given key. */
 template <tdGraph>
 inline typename clNode<tuGraph>::cpArc & clNode<tuGraph>::incomingArc(tyArcKey agKey) {
  typename cpArcX::const_iterator lcIterator = atIncomingArcX.find(agKey);

  if (lcIterator==atIncomingArcX.end()) send_inline_error(erInvalidArcKey,"node::incomingArc");
  return (*(lcIterator->second));
 }
 //--------------------------------------------------------------------------------------IncomingArc
 /*METHOD clNode */ /* Returns the incoming arc of the node identified by a given key. */
 template <tdGraph> inline
 const typename clNode<tuGraph>::cpArc & clNode<tuGraph>::incomingArc(tyArcKey agKey) const {
  typename cpArcX::const_iterator lcIterator = atIncomingArcX.find(agKey);

  if (lcIterator==atIncomingArcX.end()) send_inline_error(erInvalidArcKey,"node::IncomingArc");
  return (*(lcIterator->second));
 }
 //--------------------------------------------------------------------------------------OutgoingArc
 /*METHOD clNode */ /* Returns the outgoing arc of the node identified by a given key. */
 template <tdGraph>
 inline typename clNode<tuGraph>::cpArc & clNode<tuGraph>::outgoingArc(tyArcKey agKey) {
  typename cpArcX::const_iterator lcIterator = atOutgoingArcX.find(agKey);

  if (lcIterator==atOutgoingArcX.end()) send_inline_error(erInvalidArcKey,"node::outgoingArc");
  return (*(lcIterator->second));
 }
 //--------------------------------------------------------------------------------------OutgoingArc
 /*METHOD clNode */ /* Returns the outgoing arc of the node identified by a given key. */
 template <tdGraph> inline
 const typename clNode<tuGraph>::cpArc & clNode<tuGraph>::outgoingArc(tyArcKey agKey) const {
  typename cpArcX::const_iterator lcIterator = atOutgoingArcX.find(agKey);

  if (lcIterator==atOutgoingArcX.end()) send_inline_error(erInvalidArcKey,"node::outgoingArc");
  return (*(lcIterator->second));
 }
}

// Functions Implementation //----------------------------------------------------------------------
namespace public_area {
 //----------------------------------------------------------------------------------Arc Operator <<
 /*FUNCTION*/ /* Writes an arc into a stream. */
 template <tdGraph>
 clOutStream & operator << (clOutStream & agStream,const clArc<tuGraph> & agArc) {
  method_name("arc::operator <<");

  agStream << private_area::goArcFlag << " " << agArc.key() << " = ";

  if (agArc.sourceNode()==nil) agStream << private_area::goNoNodeFlag;
  else agStream << agArc.sourceNode()->key();

  agStream << " , ";

  if (agArc.targetNode()==nil) agStream << private_area::goNoNodeFlag;
  else agStream << agArc.targetNode()->key();

  agStream << " ; ";

  agArc.data().out(agStream,agArc.graph().solved());
  agStream << end_line;

  if (agStream.fail()) send_error(erStreamWriting);
  return (agStream);
 }
 //--------------------------------------------------------------------------------Graph Operator <<
 /*FUNCTION*/ /* Writes a graph into a stream. */
 template <tdGraph>
 clOutStream & operator << (clOutStream & agStream,const clGraph<tuGraph> & agGraph) {
  method_name("graph::operator <<");

  typedef typename clGraph<tuGraph>::cpArcX::const_iterator  cpArcIterator;
  typedef typename clGraph<tuGraph>::cpNodeX::const_iterator cpNodeIterator;

  cpArcIterator  lcCurrentArc  = agGraph.arcs().begin();
  cpNodeIterator lcCurrentNode = agGraph.nodes().begin();
  cpArcIterator  lcLastArc     = agGraph.arcs().end();
  cpNodeIterator lcLastNode    = agGraph.nodes().end();

  agStream << private_area::goGraphStartFlag << end_line << end_line;
  agStream << private_area::goNbNodesFlag << " = " << agGraph.nodes().size() << end_line;
  agStream << private_area::goNbArcsFlag << " = " << agGraph.arcs().size() << end_line;
  agStream << private_area::goSolvedFlag << " = " << standard::string(agGraph.solved());
  agStream << end_line << end_line;
  agStream << private_area::goNodesStartFlag << end_line;
  while (lcCurrentNode!=lcLastNode) agStream << *((*(lcCurrentNode++)).second);
  agStream << private_area::goNodesEndFlag << end_line << end_line;
  agStream << private_area::goArcsStartFlag << end_line;
  while (lcCurrentArc!=lcLastArc) agStream << *((*(lcCurrentArc++)).second);
  agStream << private_area::goArcsEndFlag << end_line << end_line;
  agStream << private_area::goGraphEndFlag << end_line;

  if (agStream.fail()) send_error(erStreamWriting);
  return (agStream);
 }
 //---------------------------------------------------------------------------------Node Operator <<
 /*FUNCTION*/ /* Writes a node into a stream. */
 template <tdGraph>
 clOutStream & operator << (clOutStream & agStream,const clNode<tuGraph> & agNode) {
  method_name("node::operator <<");

  agStream << private_area::goNodeFlag << " ";
  agStream << agNode.key() << " = ";
  agNode.data().out(agStream,agNode.graph().solved());
  agStream << end_line;

  if (agStream.fail()) send_error(erStreamWriting);
  return (agStream);
 }
 //--------------------------------------------------------------------------Vector<Arc> Operator <<
 /*FUNCTION*/ /* Writes a vector of arcs (only their key) into a stream. */
 template <tdGraph>
 clOutStream & operator << (clOutStream & agStream,const std_vector(clArc<tuGraph> *) & agArcS) {
  method_name("std_vector(arc *)::operator <<");

  typedef clArc<tuGraph>                               cpArc;
  typedef typename std_vector(cpArc *)::const_iterator cpArcIterator;

  cpArcIterator lcCurrentArc = agArcS.begin();
  cpArcIterator lcLastArc    = agArcS.end();

  if (lcCurrentArc==lcLastArc) agStream << "None";

  while (lcCurrentArc!=lcLastArc) {
   agStream << (*lcCurrentArc)->key();
   lcCurrentArc++;
   if (lcCurrentArc!=lcLastArc) agStream << " ";
  }

  agStream << end_line;
  if (agStream.fail()) send_error(erStreamWriting);
  return (agStream);
 }
 //-------------------------------------------------------------------------Vector<Node> Operator <<
 /*FUNCTION*/ /* Writes a vector of nodes (only their key) into a stream. */
 template <tdGraph>
 clOutStream & operator << (clOutStream & agStream,const std_vector(clNode<tuGraph> *) & agNodeS) {
  method_name("std_vector(node *)::operator <<");

  typedef clNode<tuGraph>                               cpNode;
  typedef typename std_vector(cpNode *)::const_iterator cpNodeIterator;

  cpNodeIterator lcCurrentNode = agNodeS.begin();
  cpNodeIterator lcLastNode    = agNodeS.end();

  if (lcCurrentNode==lcLastNode) agStream << "None";

  while (lcCurrentNode!=lcLastNode) {
   agStream << (*lcCurrentNode)->key();
   lcCurrentNode++;
   if (lcCurrentNode!=lcLastNode) agStream << " ";
  }

  agStream << end_line;
  if (agStream.fail()) send_error(erStreamWriting);
  return (agStream);
 }
 //--------------------------------------------------------------------------------Graph Operator >>
 /*FUNCTION*/ /* Reads a graph from a stream. */
 template <tdGraph> clInStream & operator >> (clInStream & agStream,clGraph<tuGraph> & agGraph) {
  method_name("graph::operator >>");

  typedef clArc<tuGraph>  cpArc;
  typedef clNode<tuGraph> cpNode;

  tyArcKey  lcArcKey;
  tyNodeKey lcNodeKey;
  clString  lcString;
  tyNodeKey lcSourceKey;
  tyNodeKey lcTargetKey;

  agGraph.clear();

  agStream >> lcString;
  if (lcString!=private_area::goGraphStartFlag) send_error(erStreamReading);
  agStream >> lcString;
  if (lcString!=private_area::goNbNodesFlag) send_error(erStreamReading);
  agStream >> lcString >> lcString >> lcString;
  if (lcString!=private_area::goNbArcsFlag) send_error(erStreamReading);
  agStream >> lcString >> lcString >> lcString;
  if (lcString!=private_area::goSolvedFlag) send_error(erStreamReading);
  agStream >> lcString >> lcString;
  agGraph.solved()=boolean(lcString.data());
  agStream >> lcString;
  if (lcString!=private_area::goNodesStartFlag) send_error(erStreamReading);
  agStream >> lcString;

  while (lcString==private_area::goNodeFlag) {
   agStream >> lcNodeKey >> lcString;
   new_object(cpNode(agGraph,lcNodeKey,agStream));
   agStream >> lcString;
  }

  if (lcString!=private_area::goNodesEndFlag) send_error(erStreamReading);
  agStream >> lcString;
  if (lcString!=private_area::goArcsStartFlag) send_error(erStreamReading);
  agStream >> lcString;

  while (lcString==private_area::goArcFlag) {
   agStream >> lcArcKey >> lcString;
   agStream >> lcString;
   lcSourceKey=nodeKey(lcString);
   agStream >> lcString >> lcString;
   lcTargetKey=arcKey(lcString);
   agStream >> lcString;
   new_object(cpArc(agGraph,lcArcKey,agStream,lcSourceKey,lcTargetKey));
   agStream >> lcString;
  }

  if (lcString!=private_area::goArcsEndFlag) send_error(erStreamReading);
  agStream >> lcString;
  if (lcString!=private_area::goGraphEndFlag) send_error(erStreamReading);

  if (agStream.fail()) send_error(erStreamReading);
  return (agStream);
 }
 //------------------------------------------------------------------------------DeleteNodeWorkspace
 /*FUNCTION*/ /* Deletes the workspace of the nodes of a graph. */
 template <tdGraph,class prData>
 void deleteNodeWorkspace(clGraph<tuGraph> & agGraph,const prData &) {
  typedef typename clGraph<tuGraph>::cpNodeX::const_iterator cpIterator;

  cpIterator lcCurrentNode = agGraph.nodes().begin();
  cpIterator lcLastNode    = agGraph.nodes().end();

  while (lcCurrentNode!=lcLastNode) {
   if ((*lcCurrentNode).second->work()!=nil) {
    delete_object(static_cast<prData *>((*lcCurrentNode).second->work()));
    (*lcCurrentNode).second->work()=nil;
   }

   ++lcCurrentNode;
  }
 }
 //-------------------------------------------------------------------------------DeleteArcWorkspace
 /*FUNCTION*/ /* Deletes the workspace of the arcs of a graph. */
 template <tdGraph,class prData>
 void deleteArcWorkspace(clGraph<tuGraph> & agGraph,const prData &) {
  typedef typename clGraph<tuGraph>::cpArcX::const_iterator cpIterator;

  cpIterator lcCurrentArc = agGraph.arcs().begin();
  cpIterator lcLastArc    = agGraph.arcs().end();

  while (lcCurrentArc!=lcLastArc) {
   if ((*lcCurrentArc).second->work()!=nil) {
    delete_object(static_cast<prData *>((*lcCurrentArc).second->work()));
    (*lcCurrentArc).second->work()=nil;
   }

   ++lcCurrentArc;
  }
 }
}

namespace private_area {}

// A r c  Implementation //-------------------------------------------------------------------------
namespace public_area {
 //--------------------------------------------------------------------------------------Constructor
 /*METHOD clArc */
 /* Builds an arc in a graph by copying another arc. The graph that contains it is updated. */
 template <tdGraph> clArc<tuGraph>::clArc(cpGraph & agGraph,const cpArc & agArc)
 : atGraph(agGraph),atKey(agArc.atKey),atMark(atGraph.atMark),atData(agArc.atData),atWork(nil),
   atSourceNode(nil),atTargetNode(nil) {
  method_name("arc::constructor");

  typename cpGraph::cpNodeX::const_iterator lcIterator;
  tyNodeKey                                 lcKey;

  if (atGraph.atArcX.count(atKey)==1) send_error(erArcKeyAlreadyExists);
  atGraph.atArcX.insert(std_make_pair(atKey,this));

  if (agArc.atSourceNode!=nil) {
   lcKey=agArc.atSourceNode->key();
   lcIterator=atGraph.atNodeX.find(lcKey);
   if (lcIterator==atGraph.atNodeX.end()) send_error(erInvalidNodeKey);
   setSourceNode(lcIterator->second);
  }

  if (agArc.atTargetNode!=nil) {
   lcKey=agArc.atTargetNode->key();
   lcIterator=atGraph.atNodeX.find(lcKey);
   if (lcIterator==atGraph.atNodeX.end()) send_error(erInvalidNodeKey);
   setTargetNode(lcIterator->second);
  }
 }
 //--------------------------------------------------------------------------------------Constructor
 /*METHOD clArc */
 /* Builds an arc between two nodes in a graph from given data. The graph that contains it is
    updated. */
 template <tdGraph> clArc<tuGraph>::clArc(cpGraph & agGraph,tyArcKey agKey,
                                          const prArcData & agData,tyNodeKey agSourceKey,
                                          tyNodeKey agTargetKey)
 : atGraph(agGraph),atKey(agKey),atMark(atGraph.atMark),atData(agData),atWork(nil),
   atSourceNode(nil),atTargetNode(nil) {
  method_name("arc::constructor");

  typename cpGraph::cpNodeX::const_iterator lcIterator;

  if (atGraph.atArcX.count(atKey)==1) send_error(erArcKeyAlreadyExists);
  if (atKey==nilArc()) send_error(erInvalidArcKey);
  atGraph.atArcX.insert(std_make_pair(atKey,this));

  if (agSourceKey==nilNode()) setSourceNode(nil);
  else {
   lcIterator=atGraph.atNodeX.find(agSourceKey);

   if (lcIterator==atGraph.atNodeX.end()) send_error(erInvalidNodeKey);
   else setSourceNode(lcIterator->second);
  }

  if (agTargetKey==nilNode()) setTargetNode(nil);
  else {
   lcIterator=atGraph.atNodeX.find(agTargetKey);

   if (lcIterator==atGraph.atNodeX.end()) send_error(erInvalidNodeKey);
   else setTargetNode(lcIterator->second);
  }
 }
 //--------------------------------------------------------------------------------------Constructor
 /*METHOD clArc */
 /* Builds an arc between two nodes in a graph from a stream. The graph that contains it is
    updated. */
 template <tdGraph> clArc<tuGraph>::clArc(cpGraph & agGraph,tyArcKey agKey,clInStream & agStream,
                                          tyNodeKey agSourceKey,tyNodeKey agTargetKey)
 : atGraph(agGraph),atKey(agKey),atMark(agGraph.atMark),atData(agStream,agGraph.atSolved),
   atWork(nil),atSourceNode(nil),atTargetNode(nil) {
  method_name("arc::constructor");

  typename cpGraph::cpNodeX::const_iterator lcIterator;

  if (atGraph.atArcX.count(atKey)==1) send_error(erArcKeyAlreadyExists);
  if (atKey==nilArc()) send_error(erInvalidArcKey);
  atGraph.atArcX.insert(std_make_pair(atKey,this));

  if (agSourceKey==nilNode()) setSourceNode(nil);
  else {
   lcIterator=atGraph.atNodeX.find(agSourceKey);

   if (lcIterator==atGraph.atNodeX.end()) send_error(erInvalidNodeKey);
   else setSourceNode(lcIterator->second);
  }

  if (agTargetKey==nilNode()) setTargetNode(nil);
  else {
   lcIterator=atGraph.atNodeX.find(agTargetKey);

   if (lcIterator==atGraph.atNodeX.end()) send_error(erInvalidNodeKey);
   else setTargetNode(lcIterator->second);
  }
 }
 //---------------------------------------------------------------------------------------Operator =
 /*METHOD clArc */ /* Copies an arc (its data and key). The graph that contains it is updated. */
 template <tdGraph> clArc<tuGraph> & clArc<tuGraph>::operator = (const cpArc & agArc) {
  method_name("arc::operator =");

  typename cpGraph::cpNodeX::const_iterator lcIterator;
  tyNodeKey                                 lcKey;

  if (&agArc!=this) {
   setSourceNode(nil);
   setTargetNode(nil);
   atData=agArc.atData;

   if (atKey!=agArc.atKey) {
    if (atGraph.atArcX.count(agArc.atKey)==1) send_error(erArcKeyAlreadyExists);
    atGraph.atArcX.erase(atKey);
    atKey=agArc.atKey;
    atGraph.atArcX.insert(std_make_pair(atKey,this));
   }

   if (agArc.atSourceNode!=nil) {
    lcKey=agArc.atSourceNode->key();
    lcIterator=atGraph.atNodeX.find(lcKey);
    if (lcIterator==atGraph.atNodeX.end()) send_error(erInvalidNodeKey);
    setSourceNode(lcIterator->second);
   }

   if (agArc.atTargetNode!=nil) {
    lcKey=agArc.atTargetNode->key();
    lcIterator=atGraph.atNodeX.find(lcKey);
    if (lcIterator==atGraph.atNodeX.end()) send_error(erInvalidNodeKey);
    setTargetNode(lcIterator->second);
   }

   atWork=nil;
  }

  return (*this);
 }
 //----------------------------------------------------------------------------------------ChangeKey
 /*METHOD clArc */ /* Changes the key of the arc. */
 template <tdGraph> void clArc<tuGraph>::changeKey(tyArcKey agKey) {
  method_name("arc::changeKey");

  cpNodeP lcSourceNode;
  cpNodeP lcTargetNode;

  if (atGraph.atArcX.count(agKey)==1) send_error(erArcKeyAlreadyExists);
  if (agKey==nilArc()) send_error(erInvalidArcKey);
  lcSourceNode=atSourceNode;
  lcTargetNode=atTargetNode;
  setSourceNode(nil);
  setTargetNode(nil);
  atGraph.atArcX.erase(atKey);
  atKey=agKey;
  atGraph.atArcX.insert(std_make_pair(atKey,this));
  setSourceNode(lcSourceNode);
  setTargetNode(lcTargetNode);
 }
}

// G r a p h  Implementation //---------------------------------------------------------------------
namespace public_area {
 //---------------------------------------------------------------------------------------------Copy
 template <tdGraph> void clGraph<tuGraph>::copy(const cpGraph & agGraph) {
  typedef typename cpArcX::const_iterator  cpArcIterator;
  typedef typename cpNodeX::const_iterator cpNodeIterator;

  cpArcIterator  lcCurrentArc  = agGraph.atArcX.begin();
  cpNodeIterator lcCurrentNode = agGraph.atNodeX.begin();
  cpArcIterator  lcLastArc     = agGraph.atArcX.end();
  cpNodeIterator lcLastNode    = agGraph.atNodeX.end();

  atSolved=agGraph.atSolved;

  while (lcCurrentNode!=lcLastNode) {
   new_object(cpNode(*this,*((*lcCurrentNode).second)));
   lcCurrentNode++;
  }

  while (lcCurrentArc!=lcLastArc) {
   new_object(cpArc(*this,*((*lcCurrentArc).second)));
   lcCurrentArc++;
  }
 }
 //---------------------------------------------------------------------------------------Operator =
 /*METHOD clGraph */ /* Copies completely a graph. */
 template <tdGraph> clGraph<tuGraph> & clGraph<tuGraph>::operator = (const cpGraph & agGraph) {
  clear();
  copy(agGraph);
  return (*this);
 }
 //-------------------------------------------------------------------------------------GetNewArcKey
 /*METHOD clGraph */ /* Gets randomly a new arc key that is not used yet. */
 template <tdGraph> tyArcKey clGraph<tuGraph>::getNewArcKey(void) const {
  tyArcKey lcNewKey;

  do { lcNewKey=tyArcKey(randomCardinal(cardinalMax())); }
  while (atArcX.count(lcNewKey)!=0 or lcNewKey==nilArc());

  return (lcNewKey);
 }
 //------------------------------------------------------------------------------------GetNewNodeKey
 /*METHOD clGraph */ /* Gets randomly a new node key that is not used yet. */
 template <tdGraph> tyArcKey clGraph<tuGraph>::getNewNodeKey(void) const {
  tyArcKey lcNewKey;

  do { lcNewKey=tyNodeKey(randomCardinal(cardinalMax())); }
  while (atNodeX.count(lcNewKey)!=0 or lcNewKey==nilNode());

  return (lcNewKey);
 }
 //---------------------------------------------------------------------------------------MergeNodes
 /*METHOD clGraph */ /* Merges two nodes. */
 template <tdGraph> typename
 clGraph<tuGraph>::cpNode & clGraph<tuGraph>::mergeNodes(cpNode & agNode1,cpNode & agNode2) {
  clArc<tuGraph> * lcArc;

  while (not agNode2.outgoingArcs().empty()) {
   lcArc=(*(agNode2.outgoingArcs().begin())).second;

   if (lcArc->targetNode()==&agNode1) delete_object(lcArc);
   else lcArc->setSourceNode(&agNode1);
  }

  while (not agNode2.incomingArcs().empty()) {
   lcArc=(*(agNode2.incomingArcs().begin())).second;

   if (lcArc->sourceNode()==&agNode1) delete_object(lcArc);
   else lcArc->setTargetNode(&agNode1);
  }

  delete_object(&agNode2);
  return (agNode1);
 }
 //---------------------------------------------------------------------------------------NumberKeys
 /*METHOD clGraph */ /* Numbers from 0 the keys of the arcs and the nodes. */
 template <tdGraph> void clGraph<tuGraph>::numberKeys(void) {
  typedef typename cpArcX::const_iterator   cpArcIterator;
  typedef typename cpNodeX::const_iterator  cpNodeIterator;

  std_vector(cpArc *)  lcArcS;
  std_vector(cpNode *) lcNodeS;

  tyArcKey       lcArcKey      = 0;
  cpArcIterator  lcCurrentArc  = atArcX.begin();
  cpNodeIterator lcCurrentNode = atNodeX.begin();
  cpArcIterator  lcLastArc     = atArcX.end();
  cpNodeIterator lcLastNode    = atNodeX.end();
  tyNodeKey      lcNodeKey     = 0;

  // Nodes List //
  while (lcCurrentNode!=lcLastNode) {
   lcNodeS.push_back((*lcCurrentNode).second);
   lcCurrentNode++;
  }

  // Nodes Numbering //
  while (lcNodeKey<lcNodeS.size()) {
   if (lcNodeS[lcNodeKey]->key()!=lcNodeKey) lcNodeS[lcNodeKey]->changeKey(lcNodeKey);
   lcNodeKey++;
  }

  // Arcs List //
  while (lcCurrentArc!=lcLastArc) {
   lcArcS.push_back((*lcCurrentArc).second);
   lcCurrentArc++;
  }

  // Arcs Numbering //
  while (lcArcKey<lcArcS.size()) {
   if (lcArcS[lcArcKey]->key()!=lcArcKey) lcArcS[lcArcKey]->changeKey(lcArcKey);
   lcArcKey++;
  }
 }
 //---------------------------------------------------------------------------------------RemoveArcs
 /*METHOD clGraph */ /* Removes all the arcs from the graph. */
 template <tdGraph> void clGraph<tuGraph>::removeArcs(void)
 { while (not atArcX.empty()) delete_object((*(atArcX.begin())).second); }
 //--------------------------------------------------------------------------------------RemoveNodes
 /*METHOD clGraph */ /* Removes all the nodes from the graph. */
 template <tdGraph> void clGraph<tuGraph>::removeNodes(void)
 { while (not atNodeX.empty()) delete_object((*(atNodeX.begin())).second); }
}

// N o d e  Implementation //-----------------------------------------------------------------------
namespace public_area {
 //--------------------------------------------------------------------------------------Constructor
 /*METHOD clNode */
 /* Builds a node in a graph by copying another one. The graph that contains it is updated. */
 template <tdGraph> clNode<tuGraph>::clNode(cpGraph & agGraph,const cpNode & agNode)
 : atGraph(agGraph),atKey(agNode.atKey),atMark(agGraph.atMark),atData(agNode.atData),atWork(nil),
   atIncomingArcX(),atOutgoingArcX()
 {
  method_name("node::constructor");

  if (atGraph.atNodeX.count(atKey)==1) send_error(erNodeKeyAlreadyExists);
  if (atKey==nilNode()) send_error(erInvalidNodeKey);
  atGraph.atNodeX.insert(std_make_pair(atKey,this));
 }
 //--------------------------------------------------------------------------------------Constructor
 /*METHOD clNode */
 /* Builds a node in a graph by copying given data. The graph that contains it is updated. */
 template <tdGraph>
 clNode<tuGraph>::clNode(cpGraph & agGraph,tyNodeKey agKey,const prNodeData & agData)
 : atGraph(agGraph),atKey(agKey),atMark(agGraph.atMark),atData(agData),atWork(nil),
   atIncomingArcX(),atOutgoingArcX()
 {
  method_name("node::constructor");

  if (atGraph.atNodeX.count(atKey)==1) send_error(erNodeKeyAlreadyExists);
  if (atKey==nilNode()) send_error(erInvalidNodeKey);
  atGraph.atNodeX.insert(std_make_pair(atKey,this));
 }
 //--------------------------------------------------------------------------------------Constructor
 /*METHOD clNode */
 /* Builds a node in a graph from a stream. The graph that contains it is updated. */
 template <tdGraph> clNode<tuGraph>::clNode(cpGraph & agGraph,tyNodeKey agKey,clInStream & agStream)
 : atGraph(agGraph),atKey(agKey),atMark(agGraph.atMark),atData(agStream,agGraph.atSolved),
   atWork(nil),atIncomingArcX(),atOutgoingArcX()
 {
  method_name("node::constructor");

  if (atGraph.atNodeX.count(atKey)==1) send_error(erNodeKeyAlreadyExists);
  if (atKey==nilNode()) send_error(erInvalidNodeKey);
  atGraph.atNodeX.insert(std_make_pair(atKey,this));
 }
 //---------------------------------------------------------------------------------------Destructor
 /*METHOD clNode */
 /* Destructs the node. The graph that contained it is updated. */
 template <tdGraph> clNode<tuGraph>::~clNode(void) {
  atGraph.atNodeX.erase(atKey);
  while (not atIncomingArcX.empty()) { delete_object((*(atIncomingArcX.begin())).second); }
  while (not atOutgoingArcX.empty()) { delete_object((*(atOutgoingArcX.begin())).second); }
 }
 //---------------------------------------------------------------------------------------Operator =
 /*METHOD clNode */
 /* Copies a node (data and key). The graph that contains it is updated. */
 template <tdGraph> clNode<tuGraph> & clNode<tuGraph>::operator = (const cpNode & agNode) {
  method_name("node::operator =");

  typedef typename cpArcX::const_iterator cpIterator;

  cpIterator lcCurrentArc;
  cpIterator lcLastArc;

  if (&agNode!=this) {
   if (atKey!=agNode.atKey) {
    if (atGraph.atNodeX.count(agNode.atKey)==1) send_error(erNodeKeyAlreadyExists);
    atGraph.atNodeX.erase(atKey);
    atKey=agNode.atKey;
    atGraph.atNodeX.insert(std_make_pair(atKey,this));
   }

   atData=agNode.atData;
   lcCurrentArc=atIncomingArcX.begin();
   lcLastArc=atIncomingArcX.end();

   while (lcCurrentArc!=lcLastArc) {
    (*lcCurrentArc).second->setTargetNode(this);
    lcCurrentArc++;
   }

   lcCurrentArc=atOutgoingArcX.begin();
   lcLastArc=atOutgoingArcX.end();

   while (lcCurrentArc!=lcLastArc) {
    (*lcCurrentArc).second->setSourceNode(this);
    lcCurrentArc++;
   }

   atWork=nil;
  }

  return (*this);
 }
 //----------------------------------------------------------------------------------------ChangeKey
 /*METHOD clNode */ /* Changes the key of the node. */
 template <tdGraph> void clNode<tuGraph>::changeKey(tyNodeKey agKey) {
  method_name("node::changeKey");

  if (atGraph.atNodeX.count(agKey)==1) send_error(erNodeKeyAlreadyExists);
  if (agKey==nilNode()) send_error(erInvalidNodeKey);
  atGraph.atNodeX.erase(atKey);
  atKey=agKey;
  atGraph.atNodeX.insert(std_make_pair(atKey,this));
 }
}

// End //-------------------------------------------------------------------------------------------
}
#undef dll_export
#undef tdGraph
#undef tuGraph
#undef public_area
#undef private_area
#endif
 
//==================================================================================================
// G r a p h                                                                         Implementation
// S t r u c t u r e
//                                                                                By Bruno Bachelet
//==================================================================================================
// Copyright (c) 1999-2016
// Bruno Bachelet - bruno@nawouak.net - http://www.nawouak.net
//
// This file is part of the B++ Library. This library is free software; you can redistribute it
// and/or modify it under the terms of the GNU Library General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
// the GNU Library General Public License for more details (http://www.gnu.org).

// File Name //-------------------------------------------------------------------------------------
#line __LINE__ "graph/structure.cpp"

// DLL Belonging //---------------------------------------------------------------------------------
#define GRAPH_DLL

// Headers //---------------------------------------------------------------------------------------
#include <bpp/graph/structure.hpp> /*INTERFACE*/

namespace bpp {

// Namespaces //------------------------------------------------------------------------------------
#define public_area  graphStructure
#define private_area graphStructure_private
#define dll_export   DLL_EXPORT

namespace public_area  {}
namespace private_area {}

static_module_name("Graph/Structure");

// Initialization //--------------------------------------------------------------------------------
#undef iniGraphStructure
static_constant(private_area::clInitializer,goInitializer);

// Errors //----------------------------------------------------------------------------------------
namespace public_area {
 static_error erArcExtremityNotFixed;
 static_error erArcKeyAlreadyExists;
 static_error erInvalidArcKey;
 static_error erInvalidNodeKey;
 static_error erNodeKeyAlreadyExists;
}

// Constants & Variables //-------------------------------------------------------------------------
static_constant(tyArcKey,goNilArc);
static_constant(tyNodeKey,goNilNode);

static_constant(tcString,goArcFlag);
static_constant(tcString,goArcsEndFlag);
static_constant(tcString,goArcsStartFlag);
static_constant(tcString,goGraphEndFlag);
static_constant(tcString,goGraphStartFlag);
static_constant(tcString,goNbArcsFlag);
static_constant(tcString,goNbNodesFlag);
static_constant(tcString,goNodeFlag);
static_constant(tcString,goNodesEndFlag);
static_constant(tcString,goNodesStartFlag);
static_constant(tcString,goNoArcFlag);
static_constant(tcString,goNoNodeFlag);
static_constant(tcString,goSolvedFlag);

// Static Members //--------------------------------------------------------------------------------
namespace public_area  {}
namespace private_area {}

// Functions Implementation //----------------------------------------------------------------------
namespace public_area  {}
namespace private_area {}

// X X X  Implementation //-------------------------------------------------------------------------
namespace {}

// I n i t i a l i z e r  Implementation //---------------------------------------------------------
namespace private_area {
 //--------------------------------------------------------------------------------------------Start
 property void clInitializer::start(void) {
  if (atCounter++ == 0) {
   try {
    #include <bpp/modules.hpp> /*NEED*/
    registerStop(this);
    environment::informInitialization(goModuleName);

    erArcExtremityNotFixed.create("Graph - An arc extremity isn't fixed.");
    erArcKeyAlreadyExists.create("Graph - The arc key already exists.");
    erInvalidArcKey.create("Graph - Invalid arc key.");
    erInvalidNodeKey.create("Graph - Invalid node key.");
    erNodeKeyAlreadyExists.create("Graph - The node key already exists.");

    goNilArc  = cardinalMax();
    goNilNode = cardinalMax();

    goArcFlag        = "arc";
    goArcsEndFlag    = "<arcs_end>";
    goArcsStartFlag  = "<arcs_start>";
    goGraphEndFlag   = "<graph_end>";
    goGraphStartFlag = "<graph_start>";
    goNbArcsFlag     = "nb_arcs";
    goNbNodesFlag    = "nb_nodes";
    goNodeFlag       = "node";
    goNodesEndFlag   = "<nodes_end>";
    goNodesStartFlag = "<nodes_start>";
    goNoArcFlag      = "none";
    goNoNodeFlag     = "none";
    goSolvedFlag     = "solved";
   }

   initializer_catch;
  }
 }
 //---------------------------------------------------------------------------------------------Stop
 property void clInitializer::stop(void) { environment::informTermination(goModuleName); }
}

// End //-------------------------------------------------------------------------------------------
}