COIN-OR::LEMON - Graph Library

Changeset 2502:9c23c3762bc5 in lemon-0.x


Ignore:
Timestamp:
10/24/07 18:31:49 (12 years ago)
Author:
Balazs Dezso
Branch:
default
Phase:
public
Convert:
svn:c9d7d8f5-90d6-0310-b91f-818b3a526b0e/lemon/trunk@3342
Message:

BpUGraphReader and Writer

Files:
5 edited

Legend:

Unmodified
Added
Removed
  • doc/graph_io.dox

    r2391 r2502  
    336336The specialization of writing is very similar to that of reading.
    337337
    338 \section u Undirected graphs
     338\section undir Undirected and Bipartite graphs
    339339
    340340In a file describing an undirected graph (ugraph, for short) you find an
     
    344344values of the map.
    345345
    346 The format handles directed edge maps as a syntactical sugar???, if there
    347 are two maps with names being the same with a \c '+' and a \c '-' prefix
    348 then this will be read as a directed map.
     346The format could store directed edge maps, if there are two maps with
     347names being the same with a \c '+' and a \c '-' prefix then this could
     348be read as such a map.
    349349
    350350\code
     
    385385reader.readUEdge("u_edge", u_edge);
    386386reader.readEdge("edge", edge);
     387\endcode
     388
     389The undirected bipartite graphs could be read with the \c BpUGraph
     390class and it has specialized nodeset section, which should be start
     391with \c "@bpnodeset". This section is separated to two
     392subsections. The header line of these sections start with "&anodeset"
     393or "&bnodeset" and after that the line contains the names of the
     394regular and A-node or B-node maps accordingly. The lines of each
     395section contains the mapped values. The labels of the graph should be
     396unique overall both subsections.
     397
     398\code
     399@bpnodeset
     400&anodeset label   coords        radius
     401          0       (0, 0)        14.0
     402          1       (0, 1)        12.0
     403&bnodeset label   coords
     404          2       (1, 0)
     405          3       (1, 1)
     406\endcode
     407
     408The reading can be done with \ref lemon::BpUGraphReader::readANodeMap()
     409"readANodeMap()", \ref lemon::BpUGraphReader::readBNodeMap()
     410"readBNodeMap()" or \ref lemon::BpUGraphReader::readNodeMap()
     411"readNodeMap()" members.
     412
     413\code
     414reader.readNodeMap("coords", coords);
     415reader.readAnodeMap("radius", radius);
    387416\endcode
    388417
  • lemon/graph_reader.h

    r2467 r2502  
    726726  };
    727727
     728  /// \brief The bipartite graph reader class.
     729  ///
     730  /// The \c BpUGraphReader class provides the graph input.
     731  /// Before you read this documentation it might be useful to read the general
     732  /// description of  \ref graph-io-page "Graph Input-Output".
     733  ///
     734  /// The given file format may contain several maps and labeled nodes or
     735  /// edges.
     736  ///
     737  /// If you read a graph you need not read all the maps and items just those
     738  /// that you need. The interface of the \c BpUGraphReader is very similar
     739  /// to the BpUGraphWriter but the reading method does not depend on the
     740  /// order of the given commands.
     741  ///
     742  /// The reader object suppose that each not read value does not contain
     743  /// whitespaces, therefore it has some extra possibilities to control how
     744  /// it should skip the values when the string representation contains spaces.
     745  ///
     746  ///\code
     747  /// BpUGraphReader<ListBpUGraph> reader(std::cin, graph);
     748  ///\endcode
     749  ///
     750  /// The \c readANodeMap() function reads a map from the A-part of
     751  /// the\c \@bpnodeset section, while the \c readBNodeMap() reads
     752  /// from the B-part of the section.  If you use the \c readNodeMap()
     753  /// function, then the given map should appear in both part of the
     754  /// section. If there is a map that you do not want to read from the
     755  /// file and there is whitespace in the string represenation of the
     756  /// values then you should call the \c skipANodeMap(), \c
     757  /// skipBNodeMap() or \c skipNodeMap() template member function with
     758  /// proper parameters.
     759  ///
     760  ///\code
     761  /// reader.readNodeMap("coords", coords);
     762  /// reader.readANodeMap("range", range);
     763  /// reader.readANodeMap("benefit", benefit);
     764  ///
     765  /// reader.skipNodeMap("description", desc);
     766  ///
     767  /// reader.readNodeMap("color", colorMap);
     768  ///\endcode
     769  ///
     770  /// With the \c readUEdgeMap() member function you can give an
     771  /// uedge map reading command similar to the NodeMaps.
     772  ///
     773  ///\code
     774  /// reader.readUEdgeMap("capacity", capacityMap);
     775  /// reader.readEdgeMap("flow", flowMap);
     776  ///\endcode
     777  ///
     778  /// With \c readNode() and \c readUEdge() functions you can read
     779  /// labeled Nodes and UEdges.
     780  ///
     781  ///\code
     782  /// reader.readNode("source", sourceNode);
     783  /// reader.readNode("target", targetNode);
     784  ///
     785  /// reader.readUEdge("observed", uEdge);
     786  ///\endcode
     787  ///
     788  /// With the \c readAttribute() functions you can read an attribute
     789  /// in a variable. You can specify the reader for the attribute as
     790  /// the nodemaps.
     791  ///
     792  /// After you give all read commands you must call the \c run() member
     793  /// function, which execute all the commands.
     794  ///
     795  ///\code
     796  /// reader.run();
     797  ///\endcode
     798  ///
     799  /// \see GraphReader
     800  /// \see DefaultReaderTraits
     801  /// \see \ref UGraphWriter
     802  /// \see \ref graph-io-page
     803  ///
     804  /// \author Balazs Dezso
     805  template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits>
     806  class BpUGraphReader {
     807  public:
     808   
     809    typedef _Graph Graph;
     810    typedef typename Graph::Node Node;
     811    typedef typename Graph::Edge Edge;
     812    typedef typename Graph::UEdge UEdge;
     813
     814    typedef _ReaderTraits ReaderTraits;
     815    typedef typename ReaderTraits::Skipper DefaultSkipper;
     816
     817    /// \brief Construct a new BpUGraphReader.
     818    ///
     819    /// Construct a new BpUGraphReader. It reads into the given graph
     820    /// and it use the given reader as the default skipper.
     821    BpUGraphReader(std::istream& _is, Graph& _graph,
     822                     const DefaultSkipper& _skipper = DefaultSkipper())
     823      : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
     824        nodeset_reader(*reader, _graph, std::string(), skipper),
     825        uedgeset_reader(*reader, _graph, nodeset_reader,
     826                             std::string(), skipper),
     827        node_reader(*reader, nodeset_reader, std::string()),
     828        uedge_reader(*reader, uedgeset_reader, std::string()),
     829        attribute_reader(*reader, std::string()) {}
     830
     831    /// \brief Construct a new BpUGraphReader.
     832    ///
     833    /// Construct a new BpUGraphReader. It reads into the given graph
     834    /// and it use the given reader as the default skipper.
     835    BpUGraphReader(const std::string& _filename, Graph& _graph,
     836                     const DefaultSkipper& _skipper = DefaultSkipper())
     837      : reader(new LemonReader(_filename)), own_reader(true),
     838        skipper(_skipper),
     839        nodeset_reader(*reader, _graph, std::string(), skipper),
     840        uedgeset_reader(*reader, _graph, nodeset_reader,
     841                             std::string(), skipper),
     842        node_reader(*reader, nodeset_reader, std::string()),
     843        uedge_reader(*reader, uedgeset_reader, std::string()),
     844        attribute_reader(*reader, std::string()) {}
     845
     846    /// \brief Construct a new BpUGraphReader.
     847    ///
     848    /// Construct a new BpUGraphReader. It reads into the given graph
     849    /// and it use the given reader as the default skipper.
     850    BpUGraphReader(LemonReader& _reader, Graph& _graph,
     851                     const DefaultSkipper& _skipper = DefaultSkipper())
     852      : reader(_reader), own_reader(false), skipper(_skipper),
     853        nodeset_reader(*reader, _graph, std::string(), skipper),
     854        uedgeset_reader(*reader, _graph, nodeset_reader,
     855                             std::string(), skipper),
     856        node_reader(*reader, nodeset_reader, std::string()),
     857        uedge_reader(*reader, uedgeset_reader, std::string()),
     858        attribute_reader(*reader, std::string()) {}
     859
     860    /// \brief Destruct the graph reader.
     861    ///
     862    /// Destruct the graph reader.
     863    ~BpUGraphReader() {
     864      if (own_reader)
     865        delete reader;
     866    }
     867
     868    /// \brief Give a new node map reading command to the reader.
     869    ///
     870    /// Give a new node map reading command to the reader.
     871    template <typename Map>
     872    BpUGraphReader& readNodeMap(std::string name, Map& map) {
     873      nodeset_reader.readNodeMap(name, map);
     874      return *this;
     875    }
     876
     877    template <typename Map>
     878    BpUGraphReader& readNodeMap(std::string name, const Map& map) {
     879      nodeset_reader.readNodeMap(name, map);
     880      return *this;
     881    }
     882
     883    /// \brief Give a new node map reading command to the reader.
     884    ///
     885    /// Give a new node map reading command to the reader.
     886    template <typename ItemReader, typename Map>
     887    BpUGraphReader& readNodeMap(std::string name, Map& map,
     888                              const ItemReader& ir = ItemReader()) {
     889      nodeset_reader.readNodeMap(name, map, ir);
     890      return *this;
     891    }
     892
     893    template <typename ItemReader, typename Map>
     894    BpUGraphReader& readNodeMap(std::string name, const Map& map,
     895                              const ItemReader& ir = ItemReader()) {
     896      nodeset_reader.readNodeMap(name, map, ir);
     897      return *this;
     898    }
     899
     900    /// \brief Give a new node map skipping command to the reader.
     901    ///
     902    /// Give a new node map skipping command to the reader.
     903    template <typename ItemReader>
     904    BpUGraphReader& skipNodeMap(std::string name,
     905                              const ItemReader& ir = ItemReader()) {
     906      nodeset_reader.skipNodeMap(name, ir);
     907      return *this;
     908    }
     909
     910    /// \brief Give a new A-node map reading command to the reader.
     911    ///
     912    /// Give a new A-node map reading command to the reader.
     913    template <typename Map>
     914    BpUGraphReader& readANodeMap(std::string name, Map& map) {
     915      nodeset_reader.readANodeMap(name, map);
     916      return *this;
     917    }
     918
     919    template <typename Map>
     920    BpUGraphReader& readANodeMap(std::string name, const Map& map) {
     921      nodeset_reader.readANodeMap(name, map);
     922      return *this;
     923    }
     924
     925    /// \brief Give a new A-node map reading command to the reader.
     926    ///
     927    /// Give a new A-node map reading command to the reader.
     928    template <typename ItemReader, typename Map>
     929    BpUGraphReader& readANodeMap(std::string name, Map& map,
     930                              const ItemReader& ir = ItemReader()) {
     931      nodeset_reader.readANodeMap(name, map, ir);
     932      return *this;
     933    }
     934
     935    template <typename ItemReader, typename Map>
     936    BpUGraphReader& readANodeMap(std::string name, const Map& map,
     937                              const ItemReader& ir = ItemReader()) {
     938      nodeset_reader.readNodeMap(name, map, ir);
     939      return *this;
     940    }
     941
     942    /// \brief Give a new A-node map skipping command to the reader.
     943    ///
     944    /// Give a new A-node map skipping command to the reader.
     945    template <typename ItemReader>
     946    BpUGraphReader& skipANodeMap(std::string name,
     947                              const ItemReader& ir = ItemReader()) {
     948      nodeset_reader.skipANodeMap(name, ir);
     949      return *this;
     950    }
     951
     952    /// \brief Give a new B-node map reading command to the reader.
     953    ///
     954    /// Give a new B-node map reading command to the reader.
     955    template <typename Map>
     956    BpUGraphReader& readBNodeMap(std::string name, Map& map) {
     957      nodeset_reader.readBNodeMap(name, map);
     958      return *this;
     959    }
     960
     961    template <typename Map>
     962    BpUGraphReader& readBNodeMap(std::string name, const Map& map) {
     963      nodeset_reader.readBNodeMap(name, map);
     964      return *this;
     965    }
     966
     967    /// \brief Give a new B-node map reading command to the reader.
     968    ///
     969    /// Give a new B-node map reading command to the reader.
     970    template <typename ItemReader, typename Map>
     971    BpUGraphReader& readBNodeMap(std::string name, Map& map,
     972                              const ItemReader& ir = ItemReader()) {
     973      nodeset_reader.readBNodeMap(name, map, ir);
     974      return *this;
     975    }
     976
     977    template <typename ItemReader, typename Map>
     978    BpUGraphReader& readBNodeMap(std::string name, const Map& map,
     979                              const ItemReader& ir = ItemReader()) {
     980      nodeset_reader.readNodeMap(name, map, ir);
     981      return *this;
     982    }
     983
     984    /// \brief Give a new B-node map skipping command to the reader.
     985    ///
     986    /// Give a new B-node map skipping command to the reader.
     987    template <typename ItemReader>
     988    BpUGraphReader& skipBNodeMap(std::string name,
     989                              const ItemReader& ir = ItemReader()) {
     990      nodeset_reader.skipBNodeMap(name, ir);
     991      return *this;
     992    }
     993
     994    /// \brief Give a new undirected edge map reading command to the reader.
     995    ///
     996    /// Give a new undirected edge map reading command to the reader.
     997    template <typename Map>
     998    BpUGraphReader& readUEdgeMap(std::string name, Map& map) {
     999      uedgeset_reader.readUEdgeMap(name, map);
     1000      return *this;
     1001    }
     1002
     1003    template <typename Map>
     1004    BpUGraphReader& readUEdgeMap(std::string name, const Map& map) {
     1005      uedgeset_reader.readUEdgeMap(name, map);
     1006      return *this;
     1007    }
     1008
     1009
     1010    /// \brief Give a new undirected edge map reading command to the reader.
     1011    ///
     1012    /// Give a new undirected edge map reading command to the reader.
     1013    template <typename ItemReader, typename Map>
     1014    BpUGraphReader& readUEdgeMap(std::string name, Map& map,
     1015                               const ItemReader& ir = ItemReader()) {
     1016      uedgeset_reader.readUEdgeMap(name, map, ir);
     1017      return *this;
     1018    }
     1019
     1020    template <typename ItemReader, typename Map>
     1021    BpUGraphReader& readUEdgeMap(std::string name, const Map& map,
     1022                               const ItemReader& ir = ItemReader()) {
     1023      uedgeset_reader.readUEdgeMap(name, map, ir);
     1024      return *this;
     1025    }
     1026
     1027    /// \brief Give a new undirected edge map skipping command to the reader.
     1028    ///
     1029    /// Give a new undirected edge map skipping command to the reader.
     1030    template <typename ItemReader>
     1031    BpUGraphReader& skipUEdgeMap(std::string name,
     1032                                       const ItemReader& ir = ItemReader()) {
     1033      uedgeset_reader.skipUMap(name, ir);
     1034      return *this;
     1035    }
     1036
     1037
     1038    /// \brief Give a new edge map reading command to the reader.
     1039    ///
     1040    /// Give a new edge map reading command to the reader.
     1041    template <typename Map>
     1042    BpUGraphReader& readEdgeMap(std::string name, Map& map) {
     1043      uedgeset_reader.readEdgeMap(name, map);
     1044      return *this;
     1045    }
     1046
     1047    template <typename Map>
     1048    BpUGraphReader& readEdgeMap(std::string name, const Map& map) {
     1049      uedgeset_reader.readEdgeMap(name, map);
     1050      return *this;
     1051    }
     1052
     1053
     1054    /// \brief Give a new edge map reading command to the reader.
     1055    ///
     1056    /// Give a new edge map reading command to the reader.
     1057    template <typename ItemReader, typename Map>
     1058    BpUGraphReader& readEdgeMap(std::string name, Map& map,
     1059                              const ItemReader& ir = ItemReader()) {
     1060      uedgeset_reader.readEdgeMap(name, map, ir);
     1061      return *this;
     1062    }
     1063
     1064    template <typename ItemReader, typename Map>
     1065    BpUGraphReader& readEdgeMap(std::string name, const Map& map,
     1066                              const ItemReader& ir = ItemReader()) {
     1067      uedgeset_reader.readEdgeMap(name, map, ir);
     1068      return *this;
     1069    }
     1070
     1071    /// \brief Give a new edge map skipping command to the reader.
     1072    ///
     1073    /// Give a new edge map skipping command to the reader.
     1074    template <typename ItemReader>
     1075    BpUGraphReader& skipEdgeMap(std::string name,
     1076                              const ItemReader& ir = ItemReader()) {
     1077      uedgeset_reader.skipEdgeMap(name, ir);
     1078      return *this;
     1079    }
     1080
     1081    /// \brief Give a new labeled node reading command to the reader.
     1082    ///
     1083    /// Give a new labeled node reading command to the reader.
     1084    BpUGraphReader& readNode(std::string name, Node& node) {
     1085      node_reader.readNode(name, node);
     1086      return *this;
     1087    }
     1088
     1089    /// \brief Give a new labeled edge reading command to the reader.
     1090    ///
     1091    /// Give a new labeled edge reading command to the reader.
     1092    BpUGraphReader& readEdge(std::string name, Edge& edge) {
     1093      uedge_reader.readEdge(name, edge);
     1094    }
     1095
     1096    /// \brief Give a new labeled undirected edge reading command to the
     1097    /// reader.
     1098    ///
     1099    /// Give a new labeled undirected edge reading command to the reader.
     1100    BpUGraphReader& readUEdge(std::string name, UEdge& edge) {
     1101      uedge_reader.readUEdge(name, edge);
     1102    }
     1103
     1104    /// \brief Give a new attribute reading command.
     1105    ///
     1106    ///  Give a new attribute reading command.
     1107    template <typename Value>
     1108    BpUGraphReader& readAttribute(std::string name, Value& value) {
     1109      attribute_reader.readAttribute(name, value);
     1110      return *this;
     1111    }
     1112   
     1113    /// \brief Give a new attribute reading command.
     1114    ///
     1115    ///  Give a new attribute reading command.
     1116    template <typename ItemReader, typename Value>
     1117    BpUGraphReader& readAttribute(std::string name, Value& value,
     1118                               const ItemReader& ir = ItemReader()) {
     1119      attribute_reader.readAttribute(name, value, ir);
     1120      return *this;
     1121    }
     1122
     1123    /// \brief Conversion operator to LemonReader.
     1124    ///
     1125    /// Conversion operator to LemonReader. It make possible
     1126    /// to access the encapsulated \e LemonReader, this way
     1127    /// you can attach to this reader new instances of
     1128    /// \e LemonReader::SectionReader.
     1129    operator LemonReader&() {
     1130      return *reader;
     1131    }
     1132
     1133    /// \brief Executes the reading commands.
     1134    ///
     1135    /// Executes the reading commands.
     1136    void run() {
     1137      reader->run();
     1138    }
     1139
     1140
     1141    /// \brief Returns true if the reader can give back the items by its label.
     1142    ///
     1143    /// Returns true if the reader can give back the items by its label.
     1144    bool isLabelReader() const {
     1145      return nodeset_reader.isLabelReader() &&
     1146        uedgeset_reader.isLabelReader();
     1147    }
     1148
     1149    /// \brief Gives back the node by its label.
     1150    ///
     1151    /// It reads an label from the stream and gives back which node belongs to
     1152    /// it. It is possible only if there was read a "label" named node map.
     1153    void readLabel(std::istream& is, Node& node) const {
     1154      return nodeset_reader.readLabel(is, node);
     1155    }
     1156
     1157    /// \brief Gives back the edge by its label
     1158    ///
     1159    /// It reads an label from the stream and gives back which edge belongs to
     1160    /// it. It is possible only if there was read a "label" named edge map.
     1161    void readLabel(std::istream& is, Edge& edge) const {
     1162      return uedgeset_reader.readLabel(is, edge);
     1163    }
     1164
     1165    /// \brief Gives back the undirected edge by its label.
     1166    ///
     1167    /// It reads an label from the stream and gives back which undirected edge
     1168    /// belongs to it. It is possible only if there was read a "label" named
     1169    /// edge map.
     1170    void readLabel(std::istream& is, UEdge& uedge) const {
     1171      return uedgeset_reader.readLabel(is, uedge);
     1172    }
     1173   
     1174
     1175  private:
     1176
     1177    LemonReader* reader;
     1178    bool own_reader;
     1179
     1180    DefaultSkipper skipper;
     1181
     1182    BpNodeSetReader<Graph, ReaderTraits> nodeset_reader;
     1183    UEdgeSetReader<Graph, ReaderTraits> uedgeset_reader;
     1184
     1185    NodeReader<Graph> node_reader;
     1186    UEdgeReader<Graph> uedge_reader;
     1187   
     1188    AttributeReader<ReaderTraits> attribute_reader;
     1189  };
     1190
    7281191
    7291192  /// @}
  • lemon/graph_writer.h

    r2467 r2502  
    157157    /// \brief Issue a new node map writing command for the writer.
    158158    ///
    159    /// This function issues a new <i> node map writing command</i> to the writer.
     159    /// This function issues a new <i> node map writing command</i> to the writer.
    160160    template <typename Map>
    161161    GraphWriter& writeNodeMap(std::string label, const Map& map) {
     
    167167    /// \brief Issue a new node map writing command for the writer.
    168168    ///
    169    /// This function issues a new <i> node map writing command</i> to the writer.
     169    /// This function issues a new <i> node map writing command</i> to the writer.
    170170    template <typename ItemWriter, typename Map>
    171171    GraphWriter& writeNodeMap(std::string label, const Map& map,
     
    640640  };
    641641
     642  /// \brief The bipartite graph writer class.
     643  ///
     644  /// The \c BpUGraphWriter class provides the ugraph output. To write
     645  /// a graph you should first give writing commands to the writer. You can
     646  /// declare write command as \c NodeMap, \c EdgeMap or \c UEdgeMap
     647  /// writing and labeled Node, Edge or UEdge writing.
     648  ///
     649  ///\code
     650  /// BpUGraphWriter<ListUGraph> writer(std::cout, graph);
     651  ///\endcode
     652  ///
     653  /// The \c writeNodeMap() function declares a \c NodeMap writing
     654  /// command in the \c BpUGraphWriter. You should give as parameter
     655  /// the name of the map and the map object. The NodeMap writing
     656  /// command with name "label" should write a unique map because it
     657  /// is regarded as label map.
     658  ///
     659  ///\code
     660  /// IdMap<ListUGraph, Node> nodeLabelMap;
     661  /// writer.writeNodeMap("label", nodeLabelMap);
     662  ///
     663  /// writer.writeNodeMap("coords", coords);
     664  /// writer.writeNodeMap("color", colorMap);
     665  ///\endcode
     666  ///
     667  /// With the \c writeUEdgeMap() member function you can give an
     668  /// undirected edge map writing command similar to the NodeMaps.
     669  ///
     670  ///\code
     671  /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> >
     672  ///   edgeDescMap(graph);
     673  /// writer.writeUEdgeMap("descriptor", edgeDescMap);
     674  ///
     675  /// writer.writeUEdgeMap("weight", weightMap);
     676  /// writer.writeUEdgeMap("label", labelMap);
     677  ///\endcode
     678  ///
     679  /// The EdgeMap handling is just a syntactical sugar. It writes
     680  /// two undirected edge map with '+' and '-' prefix in the name.
     681  ///
     682  ///\code
     683  /// writer.writeEdgeMap("capacity", capacityMap);
     684  ///\endcode
     685  ///
     686  ///
     687  /// With \c writeNode() and \c writeUEdge() functions you can
     688  /// designate nodes and undirected edges in the graph. For example, you can
     689  /// write out the source and target of the graph.
     690  ///
     691  ///\code
     692  /// writer.writeNode("source", sourceNode);
     693  /// writer.writeNode("target", targetNode);
     694  ///
     695  /// writer.writeUEdge("observed", uEdge);
     696  ///\endcode
     697  ///
     698  /// After you give all write commands you must call the \c run() member
     699  /// function, which executes all the writing commands.
     700  ///
     701  ///\code
     702  /// writer.run();
     703  ///\endcode
     704  ///
     705  /// \see DefaultWriterTraits
     706  /// \see QuotedStringWriter
     707  /// \see IdMap
     708  /// \see DescriptorMap
     709  /// \see \ref GraphWriter
     710  /// \see \ref graph-io-page
     711  /// \author Balazs Dezso
     712  template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
     713  class BpUGraphWriter {
     714  public:
     715   
     716    typedef _Graph Graph;
     717    typedef typename Graph::Node Node;
     718    typedef typename Graph::Edge Edge;
     719    typedef typename Graph::UEdge UEdge;
     720
     721    typedef _WriterTraits WriterTraits;
     722
     723    /// \brief Construct a new BpUGraphWriter.
     724    ///
     725    /// Construct a new BpUGraphWriter. It writes the given graph
     726    /// to the given stream.
     727    BpUGraphWriter(std::ostream& _os, const Graph& _graph)
     728      : writer(new LemonWriter(_os)), own_writer(true),
     729        nodeset_writer(*writer, _graph, std::string()),
     730        uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
     731        node_writer(*writer, nodeset_writer, std::string()),
     732        uedge_writer(*writer, uedgeset_writer, std::string()),
     733        attribute_writer(*writer, std::string()) {}
     734
     735    /// \brief Construct a new BpUGraphWriter.
     736    ///
     737    /// Construct a new BpUGraphWriter. It writes the given graph
     738    /// to the given file.
     739    BpUGraphWriter(const std::string& _filename, const Graph& _graph)
     740      : writer(new LemonWriter(_filename)), own_writer(true),
     741        nodeset_writer(*writer, _graph, std::string()),
     742        uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
     743        node_writer(*writer, nodeset_writer, std::string()),
     744        uedge_writer(*writer, uedgeset_writer, std::string()),
     745        attribute_writer(*writer, std::string()) {}
     746
     747    /// \brief Construct a new BpUGraphWriter.
     748    ///
     749    /// Construct a new BpUGraphWriter. It writes the given graph
     750    /// to given LemonWriter.
     751    BpUGraphWriter(LemonWriter& _writer, const Graph& _graph)
     752      : writer(_writer), own_writer(false),
     753        nodeset_writer(*writer, _graph, std::string()),
     754        uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
     755        node_writer(*writer, nodeset_writer, std::string()),
     756        uedge_writer(*writer, uedgeset_writer, std::string()),
     757        attribute_writer(*writer, std::string()) {}
     758
     759    /// \brief Destruct the graph writer.
     760    ///
     761    /// Destruct the graph writer.
     762    ~BpUGraphWriter() {
     763      if (own_writer)
     764        delete writer;
     765    }
     766
     767    /// \brief Issue a new node map writing command to the writer.
     768    ///
     769    /// This function issues a new <i> node map writing command</i> to
     770    /// the writer.
     771    template <typename Map>
     772    BpUGraphWriter& writeNodeMap(std::string label, const Map& map) {
     773      nodeset_writer.writeNodeMap(label, map);
     774      return *this;
     775    }
     776
     777    /// \brief Issue a new node map writing command to the writer.
     778    ///
     779    /// This function issues a new <i> node map writing command</i> to
     780    /// the writer.
     781    template <typename ItemWriter, typename Map>
     782    BpUGraphWriter& writeNodeMap(std::string label, const Map& map,
     783                              const ItemWriter& iw = ItemWriter()) {
     784      nodeset_writer.writeNodeMap(label, map, iw);
     785      return *this;
     786    }
     787
     788    /// \brief Issue a new A-node map writing command to the writer.
     789    ///
     790    /// This function issues a new <i> A-node map writing command</i> to
     791    /// the writer.
     792    template <typename Map>
     793    BpUGraphWriter& writeANodeMap(std::string label, const Map& map) {
     794      nodeset_writer.writeANodeMap(label, map);
     795      return *this;
     796    }
     797
     798    /// \brief Issue a new A-node map writing command to the writer.
     799    ///
     800    /// This function issues a new <i> A-node map writing command</i> to
     801    /// the writer.
     802    template <typename ItemWriter, typename Map>
     803    BpUGraphWriter& writeANodeMap(std::string label, const Map& map,
     804                              const ItemWriter& iw = ItemWriter()) {
     805      nodeset_writer.writeANodeMap(label, map, iw);
     806      return *this;
     807    }
     808    /// \brief Issue a new B-node map writing command to the writer.
     809    ///
     810    /// This function issues a new <i> B-node map writing command</i> to
     811    /// the writer.
     812    template <typename Map>
     813    BpUGraphWriter& writeBNodeMap(std::string label, const Map& map) {
     814      nodeset_writer.writeBNodeMap(label, map);
     815      return *this;
     816    }
     817
     818    /// \brief Issue a new B-node map writing command to the writer.
     819    ///
     820    /// This function issues a new <i> B-node map writing command</i> to
     821    /// the writer.
     822    template <typename ItemWriter, typename Map>
     823    BpUGraphWriter& writeBNodeMap(std::string label, const Map& map,
     824                              const ItemWriter& iw = ItemWriter()) {
     825      nodeset_writer.writeBNodeMap(label, map, iw);
     826      return *this;
     827    }
     828
     829    /// \brief Issue a new edge map writing command to the writer.
     830    ///
     831    /// This function issues a new <i> edge map writing command</i> to
     832    /// the writer.
     833    template <typename Map>
     834    BpUGraphWriter& writeEdgeMap(std::string label, const Map& map) {
     835      uedgeset_writer.writeEdgeMap(label, map);
     836      return *this;
     837    }
     838
     839    /// \brief Issue a new edge map writing command to the writer.
     840    ///
     841    /// This function issues a new <i> edge map writing command</i> to
     842    /// the writer.
     843    template <typename ItemWriter, typename Map>
     844    BpUGraphWriter& writeEdgeMap(std::string label, const Map& map,
     845                                   const ItemWriter& iw = ItemWriter()) {
     846      uedgeset_writer.writeEdgeMap(label, map, iw);
     847      return *this;
     848    }
     849
     850    /// \brief Issue a new undirected edge map writing command to the writer.
     851    ///
     852    /// This function issues a new <i> undirected edge map writing
     853    /// command</i> to the writer.
     854    template <typename Map>
     855    BpUGraphWriter& writeUEdgeMap(std::string label, const Map& map) {
     856      uedgeset_writer.writeUEdgeMap(label, map);
     857      return *this;
     858    }
     859
     860    /// \brief Issue a new undirected edge map writing command to the writer.
     861    ///
     862    /// This function issues a new <i> undirected edge map writing
     863    /// command</i> to the writer.
     864   template <typename ItemWriter, typename Map>
     865    BpUGraphWriter& writeUEdgeMap(std::string label, const Map& map,
     866                                        const ItemWriter& iw = ItemWriter()) {
     867      uedgeset_writer.writeUEdgeMap(label, map, iw);
     868      return *this;
     869    }
     870
     871    /// \brief Issue a new labeled node writer to the writer.
     872    ///
     873    /// This function issues a new <i> labeled node writing
     874    /// command</i> to the writer.
     875    BpUGraphWriter& writeNode(std::string label, const Node& node) {
     876      node_writer.writeNode(label, node);
     877      return *this;
     878    }
     879
     880    /// \brief Issue a new labeled edge writer to the writer.
     881    ///
     882    /// This function issues a new <i> labeled edge writing
     883    /// command</i> to the writer.
     884    BpUGraphWriter& writeEdge(std::string label, const Edge& edge) {
     885      uedge_writer.writeEdge(label, edge);
     886    }
     887
     888    /// \brief Issue a new labeled undirected edge writing command to
     889    /// the writer.
     890    ///
     891    /// Issue a new <i>labeled undirected edge writing command</i> to
     892    /// the writer.
     893    BpUGraphWriter& writeUEdge(std::string label, const UEdge& edge) {
     894      uedge_writer.writeUEdge(label, edge);
     895    }
     896
     897    /// \brief Issue a new attribute writing command.
     898    ///
     899    /// This function issues a new <i> attribute writing
     900    /// command</i> to the writer.
     901    template <typename Value>
     902    BpUGraphWriter& writeAttribute(std::string label, const Value& value) {
     903      attribute_writer.writeAttribute(label, value);
     904      return *this;
     905    }
     906   
     907    /// \brief Issue a new attribute writing command.
     908    ///
     909    /// This function issues a new <i> attribute writing
     910    /// command</i> to the writer.
     911    template <typename ItemWriter, typename Value>
     912    BpUGraphWriter& writeAttribute(std::string label, const Value& value,
     913                               const ItemWriter& iw = ItemWriter()) {
     914      attribute_writer.writeAttribute(label, value, iw);
     915      return *this;
     916    }
     917
     918    /// \brief Conversion operator to LemonWriter.
     919    ///
     920    /// Conversion operator to LemonWriter. It makes possible
     921    /// to access the encapsulated \e LemonWriter, this way
     922    /// you can attach to this writer new instances of
     923    /// \e LemonWriter::SectionWriter.
     924    operator LemonWriter&() {
     925      return *writer;
     926    }
     927
     928    /// \brief Executes the writing commands.
     929    ///
     930    /// Executes the writing commands.
     931    void run() {
     932      writer->run();
     933    }
     934
     935    /// \brief Returns true if the writer can give back the labels by the items.
     936    ///
     937    /// Returns true if the writer can give back the the labels by the items.
     938    bool isLabelWriter() const {
     939      return nodeset_writer.isLabelWriter() &&
     940        uedgeset_writer.isLabelWriter();
     941    }
     942
     943    /// \brief Write the label of the given node.
     944    ///
     945    /// It writes the label of the given node. If there was written a "label"
     946    /// named node map then it will write the map value belonging to the node.
     947    void writeLabel(std::ostream& os, const Node& item) const {
     948      nodeset_writer.writeLabel(os, item);
     949    }
     950
     951    /// \brief Write the label of the given edge.
     952    ///
     953    /// It writes the label of the given edge. If there was written a "label"
     954    /// named edge map then it will write the map value belonging to the edge.
     955    void writeLabel(std::ostream& os, const Edge& item) const {
     956      uedgeset_writer.writeLabel(os, item);
     957    }
     958
     959    /// \brief Write the label of the given undirected edge.
     960    ///
     961    /// It writes the label of the given undirected edge. If there was
     962    /// written a "label" named edge map then it will write the map
     963    /// value belonging to the edge.
     964    void writeLabel(std::ostream& os, const UEdge& item) const {
     965      uedgeset_writer.writeLabel(os, item);
     966    }
     967
     968    /// \brief Sorts the given node vector by label.
     969    ///
     970    /// Sorts the given node vector by label. If there was written an
     971    /// "label" named map then the vector will be sorted by the values
     972    /// of this map. Otherwise if the \c forceLabel parameter was true
     973    /// it will be sorted by its id in the graph.
     974    void sortByLabel(std::vector<Node>& nodes) const {
     975      nodeset_writer.sortByLabel(nodes);
     976    }
     977
     978    /// \brief Sorts the given edge vector by label.
     979    ///
     980    /// Sorts the given edge vector by label. If there was written an
     981    /// "label" named map then the vector will be sorted by the values
     982    /// of this map. Otherwise if the \c forceLabel parameter was true
     983    /// it will be sorted by its id in the graph.
     984    void sortByLabel(std::vector<Edge>& edges) const {
     985      uedgeset_writer.sortByLabel(edges);
     986    }
     987
     988    /// \brief Sorts the given undirected edge vector by label.
     989    ///
     990    /// Sorts the given undirected edge vector by label. If there was
     991    /// written an "label" named map then the vector will be sorted by
     992    /// the values of this map. Otherwise if the \c forceLabel
     993    /// parameter was true it will be sorted by its id in the graph.
     994    void sortByLabel(std::vector<UEdge>& uedges) const {
     995      uedgeset_writer.sortByLabel(uedges);
     996    }
     997
     998  private:
     999
     1000    LemonWriter* writer;
     1001    bool own_writer;
     1002
     1003    BpNodeSetWriter<Graph, WriterTraits> nodeset_writer;
     1004    UEdgeSetWriter<Graph, WriterTraits> uedgeset_writer;
     1005
     1006    NodeWriter<Graph> node_writer;
     1007    UEdgeWriter<Graph> uedge_writer;
     1008   
     1009    AttributeWriter<WriterTraits> attribute_writer;
     1010  };
     1011
    6421012  /// @}
    6431013
  • lemon/lemon_reader.h

    r2476 r2502  
    312312      MapReaderBase() { _touched = false; }
    313313     
    314       void touch() { _touched = true; }
     314      void touch(bool value = true) { _touched = value; }
    315315      bool touched() const { return _touched; }
    316316
     
    594594      virtual int_type underflow() {
    595595        char c;
    596         if (_is.read(&c, 1)) {
    597           _is.putback(c);
     596        if ((c = _is.peek()) != EOF) {
    598597          if (c == '@') {
    599598            return EOF;
     
    604603        char_type *ptr;
    605604        for (ptr = base(); ptr != eptr(); ++ptr) {
    606           if (_is.read(&c, 1)) {
     605          if ((c = _is.get()) != EOF) {
    607606            if (c == '\n') ++_num;
    608607            if (put_char(c)) {
     
    610609            } else {
    611610              if (skip_state == after_endl && c == '@') {
    612                 _is.putback('@');
     611                _is.putback(c);
    613612                break;
    614613              }
     
    638637
    639638    };
     639
     640    static void skipPreSection(std::istream& is, int& line_num) {
     641      enum skip_state_type { skip, after_endl };
     642
     643      skip_state_type skip_state = after_endl;
     644      char c;
     645     
     646      while ((c = is.get()) != EOF) {
     647        if (c == '\n') ++line_num;
     648
     649        switch (skip_state) {
     650        case skip:
     651          if (c == '\n') skip_state = after_endl;
     652          break;
     653        case after_endl:
     654          switch (c) {
     655          case '@':
     656            is.putback(c);
     657            return;
     658          case '\n':
     659            continue;
     660          default:
     661            if (!isspace(c)) {
     662              skip_state = skip;
     663            }
     664            break;
     665          }
     666        }       
     667      }
     668    }
    640669
    641670  public:
     
    723752     
    724753      SectionReaders::iterator it;
     754      skipPreSection(*is, line_num);
    725755      while ((++line_num, getline(*is, line)) && line.find("@end") != 0) {
    726756        for (it = readers.begin(); it != readers.end(); ++it) {
     
    733763              std::istream ss(&buffer);
    734764              it->first->read(ss);
     765              skipPreSection(*is, line_num);
    735766              break;
    736767            } catch (DataFormatError& error) {
     
    9831014    std::auto_ptr<_reader_bits::MapInverterBase<Node> > inverter;
    9841015  };
     1016
     1017  /// \ingroup section_io
     1018  /// \brief SectionReader for reading a bipartite graph's nodeset.
     1019  ///
     1020  /// The lemon format can store multiple bipartite graph nodesets
     1021  /// with several maps. The bipartite graph nodeset section's header
     1022  /// line is \c \@bpnodeset \c bpnodeset_name, but the \c bpnodeset_name
     1023  /// may be empty.
     1024  ///
     1025  /// The first line of the section contains \c "&anodeset" and the
     1026  /// the names of the A-node maps and regular maps separated with
     1027  /// white spaces. Each next lines describes an A-node in the anodeset,
     1028  /// and contains the mapped values for each map. If one of the line
     1029  /// starts with \c "&bnodeset" then this line contains the names of
     1030  /// the B-node maps and the regular node maps. And the remaining lines
     1031  /// contains the mapped values to the B-nodes.
     1032  ///
     1033  /// If there is "label" named map then it should be defined in both
     1034  /// nodeset, and it will be regarded as id map. This map should
     1035  /// contain only unique values and when the \c readLabel() member
     1036  /// will read a value from the given stream it will give back that
     1037  /// node which is mapped to this value.
     1038  ///
     1039  /// \relates LemonReader
     1040  template <typename _Graph, typename _Traits = DefaultReaderTraits>
     1041  class BpNodeSetReader : public LemonReader::SectionReader {
     1042    typedef LemonReader::SectionReader Parent;
     1043  public:
     1044
     1045    typedef _Graph Graph;
     1046    typedef _Traits Traits;
     1047    typedef typename Graph::Node Node;
     1048    typedef typename Traits::Skipper DefaultSkipper;
     1049
     1050    /// \brief Constructor.
     1051    ///
     1052    /// Constructor for BpNodeSetReader. It creates the BpNodeSetReader and
     1053    /// attach it into the given LemonReader. The nodeset reader will
     1054    /// add the read nodes to the given Graph. The reader will read
     1055    /// the section when the \c section_name and the \c _name are the same.
     1056    BpNodeSetReader(LemonReader& _reader,
     1057                  Graph& _graph,
     1058                  const std::string& _name = std::string(),
     1059                  const DefaultSkipper& _skipper = DefaultSkipper())
     1060      : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) {}
     1061
     1062
     1063    /// \brief Destructor.
     1064    ///
     1065    /// Destructor for BpNodeSetReader.
     1066    virtual ~BpNodeSetReader() {
     1067      for (typename MapReaders::iterator it = readers.begin();
     1068           it != readers.end(); ++it) {
     1069        delete it->second;
     1070      }
     1071    }
     1072
     1073  private:
     1074    BpNodeSetReader(const BpNodeSetReader&);
     1075    void operator=(const BpNodeSetReader&);
     1076 
     1077  public:
     1078
     1079    /// \brief Add a new node map reader command for the reader.
     1080    ///
     1081    /// Add a new node map reader command for the reader.
     1082    template <typename Map>
     1083    BpNodeSetReader& readNodeMap(std::string label, Map& map) {
     1084      return _readMap<
     1085        typename Traits::template Reader<typename Map::Value>, Map,
     1086        typename _reader_bits::Arg<Map>::Type>(label, map);
     1087    }
     1088
     1089    template <typename Map>
     1090    BpNodeSetReader& readNodeMap(std::string label, const Map& map) {
     1091      return _readMap<
     1092        typename Traits::template Reader<typename Map::Value>, Map,
     1093        typename _reader_bits::Arg<Map>::Type>(label, map);
     1094    }
     1095
     1096    /// \brief Add a new node map reader command for the reader.
     1097    ///
     1098    /// Add a new node map reader command for the reader.
     1099    template <typename ItemReader, typename Map>
     1100    BpNodeSetReader& readNodeMap(std::string label, Map& map,
     1101                               const ItemReader& ir = ItemReader()) {
     1102      return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
     1103        (label, map, ir);
     1104    }
     1105
     1106    template <typename ItemReader, typename Map>
     1107    BpNodeSetReader& readNodeMap(std::string label, const Map& map,
     1108                               const ItemReader& ir = ItemReader()) {
     1109      return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
     1110        (label, map, ir);
     1111    }
     1112
     1113  private:
     1114
     1115    template <typename ItemReader, typename Map, typename MapParameter>
     1116    BpNodeSetReader& _readMap(std::string label, MapParameter map,
     1117                            const ItemReader& ir = ItemReader()) {
     1118      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
     1119      checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
     1120      if (areaders.find(label) != areaders.end() ||
     1121          breaders.find(label) != breaders.end() ||
     1122          readers.find(label) != readers.end()) {
     1123        ErrorMessage msg;
     1124        msg << "Multiple read rule for node map: " << label;
     1125        throw IoParameterError(msg.message());
     1126      }     
     1127      readers.insert(make_pair(label, new _reader_bits::
     1128                  MapReader<Node, Map, ItemReader>(map, ir)));
     1129      return *this;
     1130    }
     1131
     1132  public:
     1133
     1134    /// \brief Add a new A-node map reader command for the reader.
     1135    ///
     1136    /// Add a new A-node map reader command for the reader.
     1137    template <typename Map>
     1138    BpNodeSetReader& readANodeMap(std::string label, Map& map) {
     1139      return _readAMap<
     1140        typename Traits::template Reader<typename Map::Value>, Map,
     1141        typename _reader_bits::Arg<Map>::Type>(label, map);
     1142    }
     1143
     1144    template <typename Map>
     1145    BpNodeSetReader& readANodeMap(std::string label, const Map& map) {
     1146      return _readAMap<
     1147        typename Traits::template Reader<typename Map::Value>, Map,
     1148        typename _reader_bits::Arg<Map>::Type>(label, map);
     1149    }
     1150
     1151    /// \brief Add a new A-node map reader command for the reader.
     1152    ///
     1153    /// Add a new A-node map reader command for the reader.
     1154    template <typename ItemReader, typename Map>
     1155    BpNodeSetReader& readANodeMap(std::string label, Map& map,
     1156                               const ItemReader& ir = ItemReader()) {
     1157      return _readAMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
     1158        (label, map, ir);
     1159    }
     1160
     1161    template <typename ItemReader, typename Map>
     1162    BpNodeSetReader& readANodeMap(std::string label, const Map& map,
     1163                               const ItemReader& ir = ItemReader()) {
     1164      return _readAMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
     1165        (label, map, ir);
     1166    }
     1167
     1168  private:
     1169
     1170    template <typename ItemReader, typename Map, typename MapParameter>
     1171    BpNodeSetReader& _readAMap(std::string label, MapParameter map,
     1172                            const ItemReader& ir = ItemReader()) {
     1173      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
     1174      checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
     1175      if (label == "label") {
     1176        throw IoParameterError("Label cannot be A-node map");
     1177      }
     1178      if (areaders.find(label) != areaders.end() ||
     1179          readers.find(label) != readers.end()) {
     1180        ErrorMessage msg;
     1181        msg << "Multiple read rule for A-node map: " << label;
     1182        throw IoParameterError(msg.message());
     1183      }
     1184      areaders.insert(make_pair(label, new _reader_bits::
     1185                                MapReader<Node, Map, ItemReader>(map, ir)));
     1186      return *this;
     1187    }
     1188
     1189  public:
     1190
     1191    /// \brief Add a new B-node map reader command for the reader.
     1192    ///
     1193    /// Add a new B-node map reader command for the reader.
     1194    template <typename Map>
     1195    BpNodeSetReader& readBNodeMap(std::string label, Map& map) {
     1196      return _readBMap<
     1197        typename Traits::template Reader<typename Map::Value>, Map,
     1198        typename _reader_bits::Arg<Map>::Type>(label, map);
     1199    }
     1200
     1201    template <typename Map>
     1202    BpNodeSetReader& readBNodeMap(std::string label, const Map& map) {
     1203      return _readBMap<
     1204        typename Traits::template Reader<typename Map::Value>, Map,
     1205        typename _reader_bits::Arg<Map>::Type>(label, map);
     1206    }
     1207
     1208    /// \brief Add a new B-node map reader command for the reader.
     1209    ///
     1210    /// Add a new B-node map reader command for the reader.
     1211    template <typename ItemReader, typename Map>
     1212    BpNodeSetReader& readBNodeMap(std::string label, Map& map,
     1213                               const ItemReader& ir = ItemReader()) {
     1214      return _readBMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
     1215        (label, map, ir);
     1216    }
     1217
     1218    template <typename ItemReader, typename Map>
     1219    BpNodeSetReader& readBNodeMap(std::string label, const Map& map,
     1220                               const ItemReader& ir = ItemReader()) {
     1221      return _readBMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type>
     1222        (label, map, ir);
     1223    }
     1224
     1225  private:
     1226
     1227    template <typename ItemReader, typename Map, typename MapParameter>
     1228    BpNodeSetReader& _readBMap(std::string label, MapParameter map,
     1229                            const ItemReader& ir = ItemReader()) {
     1230      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
     1231      checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>();
     1232      if (label == "label") {
     1233        throw IoParameterError("Label cannot be B-node map");
     1234      }
     1235      if (breaders.find(label) != breaders.end() ||
     1236          readers.find(label) != readers.end()) {
     1237        ErrorMessage msg;
     1238        msg << "Multiple read rule for B-node map: " << label;
     1239        throw IoParameterError(msg.message());
     1240      }
     1241      breaders.insert(make_pair(label, new _reader_bits::
     1242                                MapReader<Node, Map, ItemReader>(map, ir)));
     1243      return *this;
     1244    }
     1245
     1246  public:
     1247
     1248    /// \brief Add a new node map skipper command for the reader.
     1249    ///
     1250    /// Add a new node map skipper command for the reader.
     1251    template <typename ItemReader>
     1252    BpNodeSetReader& skipNodeMap(std::string label,
     1253                                 const ItemReader& ir = ItemReader()) {
     1254      if (areaders.find(label) != areaders.end() ||
     1255          breaders.find(label) != breaders.end() ||
     1256          readers.find(label) != readers.end()) {
     1257        ErrorMessage msg;
     1258        msg << "Multiple read rule for node map: " << label;
     1259        throw IoParameterError(msg.message());
     1260      }
     1261      readers.insert(make_pair(label, new _reader_bits::
     1262                               SkipReader<Node, ItemReader>(ir)));
     1263      return *this;
     1264    }
     1265
     1266    /// \brief Add a new A-node map skipper command for the reader.
     1267    ///
     1268    /// Add a new A-node map skipper command for the reader.
     1269    template <typename ItemReader>
     1270    BpNodeSetReader& skipANodeMap(std::string label,
     1271                                  const ItemReader& ir = ItemReader()) {
     1272      if (label == "label") {
     1273        throw IoParameterError("Label cannot be A-node map");
     1274      }
     1275      if (areaders.find(label) != areaders.end() ||
     1276          readers.find(label) != readers.end()) {
     1277        ErrorMessage msg;
     1278        msg << "Multiple read rule for A-node map: " << label;
     1279        throw IoParameterError(msg.message());
     1280      }
     1281      areaders.insert(make_pair(label, new _reader_bits::
     1282                                SkipReader<Node, ItemReader>(ir)));
     1283      return *this;
     1284    }
     1285
     1286    /// \brief Add a new B-node map skipper command for the reader.
     1287    ///
     1288    /// Add a new B-node map skipper command for the reader.
     1289    template <typename ItemReader>
     1290    BpNodeSetReader& skipBNodeMap(std::string label,
     1291                                  const ItemReader& ir = ItemReader()) {
     1292      if (label == "label") {
     1293        throw IoParameterError("Label cannot be B-node map");
     1294      }
     1295      if (breaders.find(label) != breaders.end() ||
     1296          readers.find(label) != readers.end()) {
     1297        ErrorMessage msg;
     1298        msg << "Multiple read rule for B-node map: " << label;
     1299        throw IoParameterError(msg.message());
     1300      }
     1301      breaders.insert(make_pair(label, new _reader_bits::
     1302                                SkipReader<Node, ItemReader>(ir)));
     1303      return *this;
     1304    }
     1305
     1306
     1307  protected:
     1308
     1309    /// \brief Gives back true when the SectionReader can process
     1310    /// the section with the given header line.
     1311    ///
     1312    /// It gives back true when the header line starts with \c \@nodeset,
     1313    /// and the header line's name and the nodeset's name are the same.
     1314    virtual bool header(const std::string& line) {
     1315      std::istringstream ls(line);
     1316      std::string command;
     1317      std::string id;
     1318      ls >> command >> id;
     1319      return command == "@bpnodeset" && name == id;
     1320    }
     1321
     1322    /// \brief Reader function of the section.
     1323    ///
     1324    /// It reads the content of the section.
     1325    virtual void read(std::istream& is) {
     1326      std::string line;
     1327      {
     1328        std::vector<_reader_bits::MapReaderBase<Node>* > index;
     1329        {
     1330          getline(is, line);
     1331          std::istringstream ls(line);
     1332          std::string id;
     1333          ls >> id;
     1334          if (id != "&anodeset") {
     1335            throw IoParameterError("Cannot find &anodeset subsection");
     1336          }
     1337          while (ls >> id) {
     1338            typename MapReaders::iterator it = readers.find(id);
     1339            typename MapReaders::iterator ait = areaders.find(id);
     1340            if (it != readers.end()) {
     1341              it->second->touch();
     1342              index.push_back(it->second);
     1343            } else if (ait != areaders.end()) {
     1344              ait->second->touch();
     1345              index.push_back(ait->second);
     1346            }
     1347            if (id == "label") {
     1348              inverter.reset(index.back()->getInverter());
     1349              index.back() = inverter.get();
     1350            }
     1351          }
     1352        }
     1353        for (typename MapReaders::iterator it = areaders.begin();
     1354             it != areaders.end(); ++it) {
     1355          if (!it->second->touched()) {
     1356            ErrorMessage msg;
     1357            msg << "Map not found in file: " << it->first;
     1358            throw IoParameterError(msg.message());
     1359          }
     1360        }
     1361        for (typename MapReaders::iterator it = readers.begin();
     1362             it != readers.end(); ++it) {
     1363          if (!it->second->touched()) {
     1364            ErrorMessage msg;
     1365            msg << "Map not found in file: " << it->first;
     1366            throw IoParameterError(msg.message());
     1367          }
     1368          it->second->touch(false);
     1369        }
     1370
     1371        while (getline(is, line)) {
     1372          if (line[0] == '&') {
     1373            std::istringstream ls(line);
     1374            std::string id;
     1375            ls >> id;
     1376            if (id == "&bnodeset") break;
     1377          }
     1378          Node node = graph.addANode();
     1379          std::istringstream ls(line);
     1380          for (int i = 0; i < int(index.size()); ++i) {
     1381            index[i]->read(ls, node);
     1382          }
     1383        }
     1384      }
     1385
     1386      {
     1387        std::vector<_reader_bits::MapReaderBase<Node>* > index;
     1388        {
     1389          std::istringstream ls(line);
     1390          std::string id;
     1391          ls >> id;
     1392          if (id != "&bnodeset") {
     1393            throw IoParameterError("Cannot find &bnodeset subsection");
     1394          }
     1395          while (ls >> id) {
     1396            typename MapReaders::iterator it = readers.find(id);
     1397            typename MapReaders::iterator bit = breaders.find(id);
     1398            if (it != readers.end()) {
     1399              it->second->touch();
     1400              index.push_back(it->second);
     1401            } else if (bit != breaders.end()) {
     1402              bit->second->touch();
     1403              index.push_back(bit->second);
     1404            }
     1405            if (id == "label" && inverter.get() != 0) {
     1406              index.back() = inverter.get();
     1407            }
     1408          }
     1409        }
     1410        for (typename MapReaders::iterator it = breaders.begin();
     1411             it != breaders.end(); ++it) {
     1412          if (!it->second->touched()) {
     1413            ErrorMessage msg;
     1414            msg << "Map not found in file: " << it->first;
     1415            throw IoParameterError(msg.message());
     1416          }
     1417        }
     1418        for (typename MapReaders::iterator it = readers.begin();
     1419             it != readers.end(); ++it) {
     1420          if (!it->second->touched()) {
     1421            ErrorMessage msg;
     1422            msg << "Map not found in file: " << it->first;
     1423            throw IoParameterError(msg.message());
     1424          }
     1425        }
     1426        while (getline(is, line)) {     
     1427          Node node = graph.addBNode();
     1428          std::istringstream ls(line);
     1429          for (int i = 0; i < int(index.size()); ++i) {
     1430            index[i]->read(ls, node);
     1431          }
     1432        }
     1433      }
     1434    }
     1435
     1436    virtual void missing() {
     1437      if (readers.empty()) return;
     1438      ErrorMessage msg;
     1439      msg << "BpNodeSet section not found in file: @bpnodeset " << name;
     1440      throw IoParameterError(msg.message());
     1441    }
     1442
     1443  public:
     1444
     1445    /// \brief Returns true if the nodeset can give back the node by its label.
     1446    ///
     1447    /// Returns true if the nodeset can give back the node by its label.
     1448    /// It is possible only if an "label" named map was read.
     1449    bool isLabelReader() const {
     1450      return inverter.get() != 0;
     1451    }
     1452
     1453    /// \brief Gives back the node by its label.
     1454    ///
     1455    /// It reads an id from the stream and gives back which node belongs to
     1456    /// it. It is possible only if there was read an "label" named map.
     1457    void readLabel(std::istream& is, Node& node) const {
     1458      node = inverter->read(is);
     1459    }
     1460
     1461  private:
     1462
     1463    typedef std::map<std::string, _reader_bits::MapReaderBase<Node>*>
     1464    MapReaders;
     1465   
     1466    MapReaders areaders, breaders, readers;
     1467   
     1468    Graph& graph;
     1469    std::string name;
     1470    _reader_bits::SkipReader<Node, DefaultSkipper> skipper;
     1471
     1472    std::auto_ptr<_reader_bits::MapInverterBase<Node> > inverter;
     1473  };
     1474
    9851475
    9861476  /// \ingroup section_io
  • lemon/lemon_writer.h

    r2467 r2502  
    145145
    146146    private:
     147      const Graph& graph;
    147148      typename Ref<Map>::Type map;
    148       const Graph& graph;
    149149    };
    150150
     
    169169
    170170    private:
     171      const Graph& graph;
    171172      typename Ref<Map>::Type map;
    172       const Graph& graph;
    173173    };
    174174
     
    503503  /// label. Otherwise if the \c _forceLabelMap constructor parameter is true
    504504  /// then the label map will be the id in the graph. In addition if the
    505   /// the \c _forceSort is true then the writer will write the edges
     505  /// the \c _forceSort is true then the writer will write the nodes
    506506  /// sorted by the labels.
    507507  ///
     
    671671    MapWriters writers;
    672672
     673    _writer_bits::MapWriterBase<Node>* labelMap;
     674    bool forceLabelMap;
     675    bool forceSort;
     676   
     677    const Graph& graph;   
     678    std::string name;
     679
     680  };
     681
     682  /// \ingroup section_io
     683  /// \brief SectionWriter for writing a bipartite graph's nodeset.
     684  ///
     685  /// The lemon format can store multiple bipartite graph nodesets
     686  /// with several maps.  The nodeset section's header line is \c
     687  /// \@bpnodeset \c bpnodeset_name, but the \c bpnodeset_name may be empty.
     688  ///
     689  /// The first line of the section contains the names of the maps separated
     690  /// with white spaces. Each next lines describes a node in the nodeset, and
     691  /// contains the mapped values for each map.
     692  ///
     693  /// If the nodeset contains an \c "label" named map then it will be regarded
     694  /// as label map. This map should contain only unique values and when the
     695  /// \c writeLabel() member will be called with a node it will write it's
     696  /// label. Otherwise if the \c _forceLabelMap constructor parameter is true
     697  /// then the label map will be the id in the graph. In addition if the
     698  /// the \c _forceSort is true then the writer will write the edges
     699  /// sorted by the labels.
     700  ///
     701  /// \relates LemonWriter
     702  template <typename _Graph, typename _Traits = DefaultWriterTraits>
     703  class BpNodeSetWriter : public LemonWriter::SectionWriter {
     704    typedef LemonWriter::SectionWriter Parent;
     705  public:
     706
     707    typedef _Graph Graph;
     708    typedef _Traits Traits;
     709    typedef typename Graph::Node Node;
     710
     711    /// \brief Constructor.
     712    ///
     713    /// Constructor for BpNodeSetWriter. It creates the BpNodeSetWriter and
     714    /// attach it into the given LemonWriter. If the \c _forceLabelMap
     715    /// parameter is true then the writer will write own label map when
     716    /// the user does not give "label" named map. In addition if the
     717    /// the \c _forceSort is true then the writer will write the nodes
     718    /// sorted by the labels.
     719    BpNodeSetWriter(LemonWriter& _writer, const Graph& _graph,
     720                  const std::string& _name = std::string(),
     721                  bool _forceLabelMap = true, bool _forceSort = true)
     722      : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
     723        forceSort(_forceSort), graph(_graph), name(_name) {}
     724
     725    /// \brief Destructor.
     726    ///
     727    /// Destructor for BpNodeSetWriter.
     728    virtual ~BpNodeSetWriter() {
     729      typename MapWriters::iterator it;
     730      for (it = writers.begin(); it != writers.end(); ++it) {
     731        delete it->second;
     732      }
     733    }
     734
     735  private:
     736    BpNodeSetWriter(const BpNodeSetWriter&);
     737    void operator=(const BpNodeSetWriter&);
     738 
     739  public:
     740
     741    /// \brief Add a new A-node map writer command for the writer.
     742    ///
     743    /// Add a new A-node map writer command for the writer.
     744    template <typename Map>
     745    BpNodeSetWriter& writeANodeMap(std::string label, const Map& map) {
     746      return writeANodeMap<typename Traits::
     747        template Writer<typename Map::Value>, Map>(label, map);
     748    }
     749
     750    /// \brief Add a new A-node map writer command for the writer.
     751    ///
     752    /// Add a new A-node map writer command for the writer.
     753    template <typename ItemWriter, typename Map>
     754    BpNodeSetWriter& writeANodeMap(std::string label, const Map& map,
     755                                   const ItemWriter& iw = ItemWriter()) {
     756      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
     757      checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
     758      if (label == "label") {
     759        throw IoParameterError("Label cannot be A-node map");
     760      }
     761      awriters.push_back(make_pair(label, new _writer_bits::
     762                                   MapWriter<Node, Map, ItemWriter>(map, iw)));
     763      return *this;
     764    }
     765
     766    /// \brief Add a new B-node map writer command for the writer.
     767    ///
     768    /// Add a new B-node map writer command for the writer.
     769    template <typename Map>
     770    BpNodeSetWriter& writeBNodeMap(std::string label, const Map& map) {
     771      return writeBNodeMap<typename Traits::
     772        template Writer<typename Map::Value>, Map>(label, map);
     773    }
     774
     775    /// \brief Add a new B-node map writer command for the writer.
     776    ///
     777    /// Add a new B-node map writer command for the writer.
     778    template <typename ItemWriter, typename Map>
     779    BpNodeSetWriter& writeBNodeMap(std::string label, const Map& map,
     780                                   const ItemWriter& iw = ItemWriter()) {
     781      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
     782      checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
     783      if (label == "label") {
     784        throw IoParameterError("Label cannot be B-node map");
     785      }
     786      bwriters.push_back(make_pair(label, new _writer_bits::
     787                                   MapWriter<Node, Map, ItemWriter>(map, iw)));
     788      return *this;
     789    }
     790
     791    /// \brief Add a new node map writer command for the writer.
     792    ///
     793    /// Add a new node map writer command for the writer.
     794    template <typename Map>
     795    BpNodeSetWriter& writeNodeMap(std::string label, const Map& map) {
     796      return writeNodeMap<typename Traits::
     797        template Writer<typename Map::Value>, Map>(label, map);
     798    }
     799
     800    /// \brief Add a new node map writer command for the writer.
     801    ///
     802    /// Add a new node map writer command for the writer.
     803    template <typename ItemWriter, typename Map>
     804    BpNodeSetWriter& writeNodeMap(std::string label, const Map& map,
     805                                  const ItemWriter& iw = ItemWriter()) {
     806      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
     807      checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
     808      writers.push_back(make_pair(label, new _writer_bits::
     809                                  MapWriter<Node, Map, ItemWriter>(map, iw)));
     810      return *this;
     811    }
     812
     813  protected:
     814
     815    /// \brief The header of the section.
     816    ///
     817    /// It gives back the header of the section.
     818    virtual std::string header() {
     819      return "@bpnodeset " + name;
     820    }
     821
     822    /// \brief Writer function of the section.
     823    ///
     824    /// Write the content of the section.
     825    virtual void write(std::ostream& os) {
     826      for (int i = 0; i < int(writers.size()); ++i) {
     827        if (writers[i].first == "label") {
     828          labelMap = writers[i].second;
     829          forceLabelMap = false;
     830          break;
     831        }
     832      }
     833      {
     834        os << "&anodeset ";
     835        std::vector<Node> items;
     836        for (typename Graph::ANodeIt it(graph); it != INVALID; ++it) {
     837          items.push_back(it);
     838        }
     839        if (forceSort) {
     840          if (labelMap) {
     841            labelMap->sort(items);
     842          } else {
     843            typedef IdMap<Graph, Node> Map;
     844            Map map(graph);
     845            _writer_bits::ComposeLess<Map> less(map);
     846            std::sort(items.begin(), items.end(), less);
     847          }
     848        }
     849        if (forceLabelMap) {
     850          os << "label\t";
     851        }
     852        for (int i = 0; i < int(writers.size()); ++i) {
     853          os << writers[i].first << '\t';
     854        }
     855        for (int i = 0; i < int(awriters.size()); ++i) {
     856          os << awriters[i].first << '\t';
     857        }
     858        os << std::endl;
     859        for (typename std::vector<Node>::iterator it = items.begin();
     860             it != items.end(); ++it) {
     861          if (forceLabelMap) {
     862            os << graph.id(*it) << '\t';
     863          }
     864          for (int i = 0; i < int(writers.size()); ++i) {
     865            writers[i].second->write(os, *it);
     866            os << '\t';
     867          }
     868          for (int i = 0; i < int(awriters.size()); ++i) {
     869            awriters[i].second->write(os, *it);
     870            os << '\t';
     871          }
     872          os << std::endl;
     873        }
     874      }
     875      {
     876        os << "&bnodeset ";
     877        std::vector<Node> items;
     878        for (typename Graph::BNodeIt it(graph); it != INVALID; ++it) {
     879          items.push_back(it);
     880        }
     881        if (forceSort) {
     882          if (labelMap) {
     883            labelMap->sort(items);
     884          } else {
     885            typedef IdMap<Graph, Node> Map;
     886            Map map(graph);
     887            _writer_bits::ComposeLess<Map> less(map);
     888            std::sort(items.begin(), items.end(), less);
     889          }
     890        }
     891        if (forceLabelMap) {
     892          os << "label\t";
     893        }
     894        for (int i = 0; i < int(writers.size()); ++i) {
     895          os << writers[i].first << '\t';
     896        }
     897        for (int i = 0; i < int(bwriters.size()); ++i) {
     898          os << bwriters[i].first << '\t';
     899        }
     900        os << std::endl;
     901        for (typename std::vector<Node>::iterator it = items.begin();
     902             it != items.end(); ++it) {
     903          if (forceLabelMap) {
     904            os << graph.id(*it) << '\t';
     905          }
     906          for (int i = 0; i < int(writers.size()); ++i) {
     907            writers[i].second->write(os, *it);
     908            os << '\t';
     909          }
     910          for (int i = 0; i < int(bwriters.size()); ++i) {
     911            bwriters[i].second->write(os, *it);
     912            os << '\t';
     913          }
     914          os << std::endl;
     915        }
     916      }
     917    }
     918
     919  public:
     920
     921    /// \brief Returns true if the nodeset can write the labels of the nodes.
     922    ///
     923    /// Returns true if the nodeset can write the labels of the nodes.
     924    /// It is possible only if a "label" named map was written or the
     925    /// \c _forceLabelMap constructor parameter was true.
     926    bool isLabelWriter() const {
     927      return labelMap != 0 || forceLabelMap;
     928    }
     929
     930    /// \brief Write the label of the given node.
     931    ///
     932    /// It writes the label of the given node. If there was written a "label"
     933    /// named map then it will write the map value belongs to the node.
     934    /// Otherwise if the \c forceLabel parameter was true it will write
     935    /// its label in the graph.
     936    void writeLabel(std::ostream& os, const Node& item) const {
     937      if (forceLabelMap) {
     938        os << graph.id(item);
     939      } else {
     940        labelMap->write(os, item);
     941      }
     942    }
     943
     944    /// \brief Sorts the given node vector by label.
     945    ///
     946    /// Sorts the given node vector by label. If there was written an
     947    /// "label" named map then the vector will be sorted by the values
     948    /// of this map. Otherwise if the \c forceLabel parameter was true
     949    /// it will be sorted by its id in the graph.
     950    void sortByLabel(std::vector<Node>& nodes) const {
     951      if (labelMap) {
     952        labelMap->sort(nodes);
     953      } else {
     954        typedef IdMap<Graph, Node> Map;
     955        Map map(graph);
     956        _writer_bits::ComposeLess<Map> less(map);
     957        std::sort(nodes.begin(), nodes.end(), less);
     958      }
     959    }
     960
     961  private:
     962
     963    typedef std::vector<std::pair<std::string, _writer_bits::
     964                                  MapWriterBase<Node>*> > MapWriters;
     965    MapWriters awriters, bwriters, writers;
     966   
    673967    _writer_bits::MapWriterBase<Node>* labelMap;
    674968    bool forceLabelMap;
Note: See TracChangeset for help on using the changeset viewer.