Changeset 1421:7a21e1414c38 in lemon-0.x
- Timestamp:
- 05/14/05 19:39:37 (20 years ago)
- Branch:
- default
- Phase:
- public
- Convert:
- svn:c9d7d8f5-90d6-0310-b91f-818b3a526b0e/lemon/trunk@1891
- Location:
- src/lemon
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/lemon/graph_reader.h
r1408 r1421 57 57 /// 58 58 /// \code 59 /// reader.readNodeMap("x-coord", xCoordMap); 60 /// reader.readNodeMap("y-coord", yCoordMap); 59 /// reader.readNodeMap("coords", coords); 61 60 /// 62 61 /// reader.readNodeMap<QuotedStringReader>("label", labelMap); … … 115 114 /// Construct a new GraphReader. It reads into the given graph 116 115 /// and it use the given reader as the default skipper. 117 GraphReader(std::istream& _is, Graph& _graph, 116 GraphReader(std::istream& _is, 117 typename SmartParameter<Graph>::Type _graph, 118 118 const DefaultSkipper& _skipper = DefaultSkipper()) 119 : reader(new LemonReader(_is)), own_reader(true), 120 graph(_graph), skipper(_skipper),121 nodeset_reader(*reader, graph, std::string(), skipper),122 edgeset_reader(*reader, graph, nodeset_reader,std::string(), skipper),119 : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper), 120 nodeset_reader(*reader, _graph, std::string(), skipper), 121 edgeset_reader(*reader, _graph, nodeset_reader, 122 std::string(), skipper), 123 123 node_reader(*reader, nodeset_reader, std::string()), 124 124 edge_reader(*reader, edgeset_reader, std::string()), … … 129 129 /// Construct a new GraphReader. It reads into the given graph 130 130 /// and it use the given reader as the default skipper. 131 GraphReader(const std::string& _filename, Graph& _graph, 131 GraphReader(const std::string& _filename, 132 typename SmartParameter<Graph>::Type _graph, 132 133 const DefaultSkipper& _skipper = DefaultSkipper()) 133 134 : reader(new LemonReader(_filename)), own_reader(true), 134 graph(_graph), skipper(_skipper), 135 nodeset_reader(*reader, graph, std::string(), skipper), 136 edgeset_reader(*reader, graph, nodeset_reader, std::string(), skipper), 135 skipper(_skipper), 136 nodeset_reader(*reader, _graph, std::string(), skipper), 137 edgeset_reader(*reader, _graph, nodeset_reader, 138 std::string(), skipper), 137 139 node_reader(*reader, nodeset_reader, std::string()), 138 140 edge_reader(*reader, edgeset_reader, std::string()), … … 143 145 /// Construct a new GraphReader. It reads into the given graph 144 146 /// and it use the given reader as the default skipper. 145 GraphReader(LemonReader& _reader, Graph& _graph, 147 GraphReader(LemonReader& _reader, 148 typename SmartParameter<Graph>::Type _graph, 146 149 const DefaultSkipper& _skipper = DefaultSkipper()) 147 : reader(_reader), own_reader(false), 148 graph(_graph), skipper(_skipper),149 nodeset_reader(*reader, graph, std::string(), skipper),150 edgeset_reader(*reader, graph, nodeset_reader,std::string(), skipper),150 : reader(_reader), own_reader(false), skipper(_skipper), 151 nodeset_reader(*reader, _graph, std::string(), skipper), 152 edgeset_reader(*reader, _graph, nodeset_reader, 153 std::string(), skipper), 151 154 node_reader(*reader, nodeset_reader, std::string()), 152 155 edge_reader(*reader, edgeset_reader, std::string()), … … 166 169 template <typename Map> 167 170 GraphReader& readNodeMap(std::string name, Map& map) { 168 nodeset_reader.readMap(name, map); 171 nodeset_reader.readNodeMap(name, map); 172 return *this; 173 } 174 175 template <typename Map> 176 GraphReader& readNodeMap(std::string name, const Map& map) { 177 nodeset_reader.readNodeMap(name, map); 169 178 return *this; 170 179 } … … 176 185 GraphReader& readNodeMap(std::string name, Map& map, 177 186 const Reader& reader = Reader()) { 178 nodeset_reader.readMap(name, map, reader); 187 nodeset_reader.readNodeMap(name, map, reader); 188 return *this; 189 } 190 191 template <typename Reader, typename Map> 192 GraphReader& readNodeMap(std::string name, const Map& map, 193 const Reader& reader = Reader()) { 194 nodeset_reader.readNodeMap(name, map, reader); 179 195 return *this; 180 196 } … … 186 202 GraphReader& skipNodeMap(std::string name, 187 203 const Reader& reader = Reader()) { 188 nodeset_reader.skip Map(name, reader);204 nodeset_reader.skipNodeMap(name, reader); 189 205 return *this; 190 206 } … … 195 211 template <typename Map> 196 212 GraphReader& readEdgeMap(std::string name, Map& map) { 197 edgeset_reader.readMap(name, map); 213 edgeset_reader.readEdgeMap(name, map); 214 return *this; 215 } 216 217 template <typename Map> 218 GraphReader& readEdgeMap(std::string name, const Map& map) { 219 edgeset_reader.readEdgeMap(name, map); 198 220 return *this; 199 221 } … … 206 228 GraphReader& readEdgeMap(std::string name, Map& map, 207 229 const Reader& reader = Reader()) { 208 edgeset_reader.readMap(name, map, reader); 230 edgeset_reader.readEdgeMap(name, map, reader); 231 return *this; 232 } 233 234 template <typename Reader, typename Map> 235 GraphReader& readEdgeMap(std::string name, const Map& map, 236 const Reader& reader = Reader()) { 237 edgeset_reader.readEdgeMap(name, map, reader); 209 238 return *this; 210 239 } … … 214 243 /// Add a new edge map skipper command for the reader. 215 244 template <typename Reader> 216 GraphReader& skipEdgeMap(std::string name, 245 GraphReader& skipEdgeMap(std::string name, 217 246 const Reader& reader = Reader()) { 218 219 edgeset_reader.skipMap(name, reader); 247 edgeset_reader.skipEdgeMap(name, reader); 220 248 return *this; 221 249 } … … 276 304 LemonReader* reader; 277 305 bool own_reader; 278 279 Graph& graph;280 306 281 307 DefaultSkipper skipper; … … 369 395 } 370 396 397 /// \brief The undir graph reader class. 398 /// 399 /// The given file format may contain several maps and labeled nodes or 400 /// edges. 401 /// 402 /// If you read a graph you need not read all the maps and items just those 403 /// that you need. The interface of the \c GraphReader is very similar to 404 /// the GraphWriter but the reading method does not depend on the order the 405 /// given commands. 406 /// 407 /// The reader object suppose that each not readed value does not contain 408 /// whitespaces, therefore it has some extra possibilities to control how 409 /// it should skip the values when the string representation contains spaces. 410 /// 411 /// \code 412 /// UndirGraphReader<UndirListGraph> reader(std::cin, graph); 413 /// \endcode 414 /// 415 /// The \c readNodeMap() function reads a map from the \c \@nodeset section. 416 /// If there is a map that you do not want to read from the file and there is 417 /// whitespace in the string represenation of the values then you should 418 /// call the \c skipNodeMap() template member function with proper 419 /// parameters. 420 /// 421 /// \code 422 /// reader.readNodeMap("coords", coords); 423 /// 424 /// reader.readNodeMap<QuotedStringReader>("label", labelMap); 425 /// reader.skipNodeMap<QuotedStringReader>("description"); 426 /// 427 /// reader.readNodeMap("color", colorMap); 428 /// \endcode 429 /// 430 /// With the \c readUndirEdgeMap() member function you can give an 431 /// undir edge map reading command similar to the NodeMaps. 432 /// 433 /// \code 434 /// reader.readUndirEdgeMap("capacity", capacityMap); 435 /// \endcode 436 /// 437 /// The reading of the directed edge maps is just a syntactical sugar. 438 /// It reads two undirected edgemaps into a directed edge map. The 439 /// undirected edge maps' name should be start with the \c '+' and the 440 /// \c '-' character and the same. 441 /// 442 /// \code 443 /// reader.readEdgeMap("flow", flowMap); 444 /// \endcode 445 /// 446 /// With \c readNode() and \c readUndirEdge() functions you can read 447 /// labeled Nodes and UndirEdges. 448 /// 449 /// \code 450 /// reader.readNode("source", sourceNode); 451 /// reader.readNode("target", targetNode); 452 /// 453 /// reader.readUndirEdge("observed", undirEdge); 454 /// \endcode 455 /// 456 /// With the \c readAttribute() functions you can read an attribute 457 /// in a variable. You can specify the reader for the attribute as 458 /// the nodemaps. 459 /// 460 /// After you give all read commands you must call the \c run() member 461 /// function, which execute all the commands. 462 /// 463 /// \code 464 /// reader.run(); 465 /// \endcode 466 /// 467 /// \see GraphReader 468 /// \see DefaultReaderTraits 469 /// \see \ref UndirGraphWriter 470 /// \see \ref graph-io-page 471 /// 472 /// \author Balazs Dezso 473 template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> 474 class UndirGraphReader { 475 public: 476 477 typedef _Graph Graph; 478 typedef typename Graph::Node Node; 479 typedef typename Graph::Edge Edge; 480 typedef typename Graph::UndirEdge UndirEdge; 481 482 typedef _ReaderTraits ReaderTraits; 483 typedef typename ReaderTraits::Skipper DefaultSkipper; 484 485 /// \brief Construct a new UndirGraphReader. 486 /// 487 /// Construct a new UndirGraphReader. It reads into the given graph 488 /// and it use the given reader as the default skipper. 489 UndirGraphReader(std::istream& _is, Graph& _graph, 490 const DefaultSkipper& _skipper = DefaultSkipper()) 491 : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper), 492 nodeset_reader(*reader, _graph, std::string(), skipper), 493 undir_edgeset_reader(*reader, _graph, nodeset_reader, 494 std::string(), skipper), 495 node_reader(*reader, nodeset_reader, std::string()), 496 undir_edge_reader(*reader, undir_edgeset_reader, std::string()), 497 attribute_reader(*reader, std::string()) {} 498 499 /// \brief Construct a new UndirGraphReader. 500 /// 501 /// Construct a new UndirGraphReader. It reads into the given graph 502 /// and it use the given reader as the default skipper. 503 UndirGraphReader(const std::string& _filename, Graph& _graph, 504 const DefaultSkipper& _skipper = DefaultSkipper()) 505 : reader(new LemonReader(_filename)), own_reader(true), 506 skipper(_skipper), 507 nodeset_reader(*reader, _graph, std::string(), skipper), 508 undir_edgeset_reader(*reader, _graph, nodeset_reader, 509 std::string(), skipper), 510 node_reader(*reader, nodeset_reader, std::string()), 511 undir_edge_reader(*reader, undir_edgeset_reader, std::string()), 512 attribute_reader(*reader, std::string()) {} 513 514 /// \brief Construct a new UndirGraphReader. 515 /// 516 /// Construct a new UndirGraphReader. It reads into the given graph 517 /// and it use the given reader as the default skipper. 518 UndirGraphReader(LemonReader& _reader, Graph& _graph, 519 const DefaultSkipper& _skipper = DefaultSkipper()) 520 : reader(_reader), own_reader(false), skipper(_skipper), 521 nodeset_reader(*reader, _graph, std::string(), skipper), 522 undir_edgeset_reader(*reader, _graph, nodeset_reader, 523 std::string(), skipper), 524 node_reader(*reader, nodeset_reader, std::string()), 525 undir_edge_reader(*reader, undir_edgeset_reader, std::string()), 526 attribute_reader(*reader, std::string()) {} 527 528 /// \brief Destruct the graph reader. 529 /// 530 /// Destruct the graph reader. 531 ~UndirGraphReader() { 532 if (own_reader) 533 delete reader; 534 } 535 536 /// \brief Add a new node map reader command for the reader. 537 /// 538 /// Add a new node map reader command for the reader. 539 template <typename Map> 540 UndirGraphReader& readNodeMap(std::string name, Map& map) { 541 nodeset_reader.readNodeMap(name, map); 542 return *this; 543 } 544 545 template <typename Map> 546 UndirGraphReader& readNodeMap(std::string name, const Map& map) { 547 nodeset_reader.readNodeMap(name, map); 548 return *this; 549 } 550 551 /// \brief Add a new node map reader command for the reader. 552 /// 553 /// Add a new node map reader command for the reader. 554 template <typename Reader, typename Map> 555 UndirGraphReader& readNodeMap(std::string name, Map& map, 556 const Reader& reader = Reader()) { 557 nodeset_reader.readNodeMap(name, map, reader); 558 return *this; 559 } 560 561 template <typename Reader, typename Map> 562 UndirGraphReader& readNodeMap(std::string name, const Map& map, 563 const Reader& reader = Reader()) { 564 nodeset_reader.readNodeMap(name, map, reader); 565 return *this; 566 } 567 568 /// \brief Add a new node map skipper command for the reader. 569 /// 570 /// Add a new node map skipper command for the reader. 571 template <typename Reader> 572 UndirGraphReader& skipNodeMap(std::string name, 573 const Reader& reader = Reader()) { 574 nodeset_reader.skipNodeMap(name, reader); 575 return *this; 576 } 577 578 /// \brief Add a new undirected edge map reader command for the reader. 579 /// 580 /// Add a new undirected edge map reader command for the reader. 581 template <typename Map> 582 UndirGraphReader& readUndirEdgeMap(std::string name, Map& map) { 583 undir_edgeset_reader.readUndirEdgeMap(name, map); 584 return *this; 585 } 586 587 template <typename Map> 588 UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map) { 589 undir_edgeset_reader.readUndirEdgeMap(name, map); 590 return *this; 591 } 592 593 594 /// \brief Add a new undirected edge map reader command for the reader. 595 /// 596 /// Add a new undirected edge map reader command for the reader. 597 template <typename Reader, typename Map> 598 UndirGraphReader& readUndirEdgeMap(std::string name, Map& map, 599 const Reader& reader = Reader()) { 600 undir_edgeset_reader.readUndirEdgeMap(name, map, reader); 601 return *this; 602 } 603 604 template <typename Reader, typename Map> 605 UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map, 606 const Reader& reader = Reader()) { 607 undir_edgeset_reader.readUndirEdgeMap(name, map, reader); 608 return *this; 609 } 610 611 /// \brief Add a new undirected edge map skipper command for the reader. 612 /// 613 /// Add a new undirected edge map skipper command for the reader. 614 template <typename Reader> 615 UndirGraphReader& skipUndirEdgeMap(std::string name, 616 const Reader& reader = Reader()) { 617 undir_edgeset_reader.skipUndirMap(name, reader); 618 return *this; 619 } 620 621 622 /// \brief Add a new edge map reader command for the reader. 623 /// 624 /// Add a new edge map reader command for the reader. 625 template <typename Map> 626 UndirGraphReader& readEdgeMap(std::string name, Map& map) { 627 undir_edgeset_reader.readEdgeMap(name, map); 628 return *this; 629 } 630 631 template <typename Map> 632 UndirGraphReader& readEdgeMap(std::string name, const Map& map) { 633 undir_edgeset_reader.readEdgeMap(name, map); 634 return *this; 635 } 636 637 638 /// \brief Add a new edge map reader command for the reader. 639 /// 640 /// Add a new edge map reader command for the reader. 641 template <typename Reader, typename Map> 642 UndirGraphReader& readEdgeMap(std::string name, Map& map, 643 const Reader& reader = Reader()) { 644 undir_edgeset_reader.readEdgeMap(name, map, reader); 645 return *this; 646 } 647 648 template <typename Reader, typename Map> 649 UndirGraphReader& readEdgeMap(std::string name, const Map& map, 650 const Reader& reader = Reader()) { 651 undir_edgeset_reader.readEdgeMap(name, map, reader); 652 return *this; 653 } 654 655 /// \brief Add a new edge map skipper command for the reader. 656 /// 657 /// Add a new edge map skipper command for the reader. 658 template <typename Reader> 659 UndirGraphReader& skipEdgeMap(std::string name, 660 const Reader& reader = Reader()) { 661 undir_edgeset_reader.skipEdgeMap(name, reader); 662 return *this; 663 } 664 665 /// \brief Add a new labeled node reader for the reader. 666 /// 667 /// Add a new labeled node reader for the reader. 668 UndirGraphReader& readNode(std::string name, Node& node) { 669 node_reader.readNode(name, node); 670 return *this; 671 } 672 673 /// \brief Add a new labeled edge reader for the reader. 674 /// 675 /// Add a new labeled edge reader for the reader. 676 UndirGraphReader& readUndirEdge(std::string name, UndirEdge& edge) { 677 undir_edge_reader.readUndirEdge(name, edge); 678 } 679 680 /// \brief Add a new attribute reader command. 681 /// 682 /// Add a new attribute reader command. 683 template <typename Value> 684 UndirGraphReader& readAttribute(std::string name, Value& value) { 685 attribute_reader.readAttribute(name, value); 686 return *this; 687 } 688 689 /// \brief Add a new attribute reader command. 690 /// 691 /// Add a new attribute reader command. 692 template <typename Reader, typename Value> 693 UndirGraphReader& readAttribute(std::string name, Value& value, 694 const Reader& reader) { 695 attribute_reader.readAttribute<Reader>(name, value, reader); 696 return *this; 697 } 698 699 /// \brief Conversion operator to LemonReader. 700 /// 701 /// Conversion operator to LemonReader. It make possible 702 /// to access the encapsulated \e LemonReader, this way 703 /// you can attach to this reader new instances of 704 /// \e LemonReader::SectionReader. 705 operator LemonReader&() { 706 return *reader; 707 } 708 709 /// \brief Executes the reader commands. 710 /// 711 /// Executes the reader commands. 712 void run() { 713 reader->run(); 714 } 715 716 private: 717 718 LemonReader* reader; 719 bool own_reader; 720 721 DefaultSkipper skipper; 722 723 NodeSetReader<Graph, ReaderTraits> nodeset_reader; 724 UndirEdgeSetReader<Graph, ReaderTraits> undir_edgeset_reader; 725 726 NodeReader<Graph> node_reader; 727 UndirEdgeReader<Graph> undir_edge_reader; 728 729 AttributeReader<ReaderTraits> attribute_reader; 730 }; 731 732 /// \brief Read an undir graph from the input. 733 /// 734 /// Read an undir graph from the input. 735 /// \param is The input stream. 736 /// \param g The graph. 737 /// \param capacity The capacity map. 738 template<typename Graph, typename CapacityMap> 739 void readUndirGraph(std::istream& is, Graph &g, CapacityMap& capacity) { 740 UndirGraphReader<Graph> reader(is, g); 741 reader.readUndirEdgeMap("capacity", capacity); 742 reader.run(); 743 } 744 745 /// \brief Read an undir graph from the input. 746 /// 747 /// Read an undir graph from the input. 748 /// \param is The input stream. 749 /// \param g The graph. 750 template<typename Graph> 751 void readUndirGraph(std::istream& is, Graph &g) { 752 UndirGraphReader<Graph> reader(is, g); 753 reader.run(); 754 } 755 371 756 /// @} 372 757 } -
src/lemon/graph_writer.h
r1410 r1421 53 53 /// writer.writeNodeMap("id", nodeIdMap); 54 54 /// 55 /// writer.writeNodeMap("x-coord", xCoordMap); 56 /// writer.writeNodeMap("y-coord", yCoordMap); 55 /// writer.writeNodeMap("coords", coords); 57 56 /// writer.writeNodeMap("color", colorMap); 58 57 /// \endcode … … 92 91 /// \see IdMap 93 92 /// \see DescriptorMap 94 /// \see \ref Graph Writer93 /// \see \ref GraphReader 95 94 /// \see \ref graph-io-page 96 95 /// \author Balazs Dezso … … 111 110 GraphWriter(std::ostream& _os, const Graph& _graph) 112 111 : writer(new LemonWriter(_os)), own_writer(true), 113 graph(_graph), 114 nodeset_writer(*writer, graph, std::string()), 115 edgeset_writer(*writer, graph, nodeset_writer, std::string()), 112 nodeset_writer(*writer, _graph, std::string()), 113 edgeset_writer(*writer, _graph, nodeset_writer, std::string()), 116 114 node_writer(*writer, nodeset_writer, std::string()), 117 115 edge_writer(*writer, edgeset_writer, std::string()), … … 124 122 GraphWriter(const std::string& _filename, const Graph& _graph) 125 123 : writer(new LemonWriter(_filename)), own_writer(true), 126 graph(_graph), 127 nodeset_writer(*writer, graph, std::string()), 128 edgeset_writer(*writer, graph, nodeset_writer, std::string()), 124 nodeset_writer(*writer, _graph, std::string()), 125 edgeset_writer(*writer, _graph, nodeset_writer, std::string()), 129 126 node_writer(*writer, nodeset_writer, std::string()), 130 127 edge_writer(*writer, edgeset_writer, std::string()), … … 137 134 GraphWriter(LemonWriter& _writer, const Graph& _graph) 138 135 : writer(_writer), own_writer(false), 139 graph(_graph), 140 nodeset_writer(*writer, graph, std::string()), 141 edgeset_writer(*writer, graph, nodeset_writer, std::string()), 136 nodeset_writer(*writer, _graph, std::string()), 137 edgeset_writer(*writer, _graph, nodeset_writer, std::string()), 142 138 node_writer(*writer, nodeset_writer, std::string()), 143 139 edge_writer(*writer, edgeset_writer, std::string()), … … 157 153 template <typename Map> 158 154 GraphWriter& writeNodeMap(std::string name, const Map& map) { 159 nodeset_writer.write Map(name, map);155 nodeset_writer.writeNodeMap(name, map); 160 156 return *this; 161 157 } … … 166 162 template <typename Writer, typename Map> 167 163 GraphWriter& writeNodeMap(std::string name, const Map& map, 168 const Writer& writer = Writer()) {169 nodeset_writer.write Map(name, map, writer);164 const Writer& writer = Writer()) { 165 nodeset_writer.writeNodeMap(name, map, writer); 170 166 return *this; 171 167 } … … 177 173 template <typename Map> 178 174 GraphWriter& writeEdgeMap(std::string name, const Map& map) { 179 edgeset_writer.write Map(name, map);175 edgeset_writer.writeEdgeMap(name, map); 180 176 return *this; 181 177 } … … 187 183 template <typename Writer, typename Map> 188 184 GraphWriter& writeEdgeMap(std::string name, const Map& map, 189 const Writer& writer = Writer()) {190 edgeset_writer.write Map(name, map, writer);185 const Writer& writer = Writer()) { 186 edgeset_writer.writeEdgeMap(name, map, writer); 191 187 return *this; 192 188 } … … 247 243 LemonWriter* writer; 248 244 bool own_writer; 249 250 const Graph& graph;251 245 252 246 NodeSetWriter<Graph, WriterTraits> nodeset_writer; … … 361 355 } 362 356 357 /// \brief The undirected graph writer class. 358 /// 359 /// The \c UndirGraphWriter class provides the undir graph output. To write 360 /// a graph you should first give writing commands for the writer. You can 361 /// declare write command as \c NodeMap, \c EdgeMap or \c UndirEdgeMap 362 /// writing and labeled Node, Edge or UndirEdge writing. 363 /// 364 /// \code 365 /// UndirGraphWriter<UndirListGraph> writer(std::cout, graph); 366 /// \endcode 367 /// 368 /// The \c writeNodeMap() function declares a \c NodeMap writing 369 /// command in the \c UndirGraphWriter. You should give as parameter 370 /// the name of the map and the map object. The NodeMap writing 371 /// command with name "id" should write a unique map because it 372 /// is regarded as ID map. 373 /// 374 /// \code 375 /// IdMap<UndirListGraph, Node> nodeIdMap; 376 /// writer.writeNodeMap("id", nodeIdMap); 377 /// 378 /// writer.writeNodeMap("coords", coords); 379 /// writer.writeNodeMap("color", colorMap); 380 /// \endcode 381 /// 382 /// With the \c writeUndirEdgeMap() member function you can give an 383 /// undirected edge map writing command similar to the NodeMaps. 384 /// 385 /// \code 386 /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> > 387 /// edgeDescMap(graph); 388 /// writer.writeUndirEdgeMap("descriptor", edgeDescMap); 389 /// 390 /// writer.writeUndirEdgeMap("weight", weightMap); 391 /// writer.writeUndirEdgeMap("label", labelMap); 392 /// \endcode 393 /// 394 /// The EdgeMap handling is just a syntactical sugar. It writes 395 /// two undirected edge map with '+' and '-' prefix in the name. 396 /// 397 /// \code 398 /// writer.writeEdgeMap("capacity", capacityMap); 399 /// \endcode 400 /// 401 /// 402 /// With \c writeNode() and \c writeUndirEdge() functions you can 403 /// point out nodes and undirected edges in the graph. By example, you can 404 /// write out the source and target of the graph. 405 /// 406 /// \code 407 /// writer.writeNode("source", sourceNode); 408 /// writer.writeNode("target", targetNode); 409 /// 410 /// writer.writeUndirEdge("observed", undirEdge); 411 /// \endcode 412 /// 413 /// After you give all write commands you must call the \c run() member 414 /// function, which execute all the writer commands. 415 /// 416 /// \code 417 /// writer.run(); 418 /// \endcode 419 /// 420 /// \see DefaultWriterTraits 421 /// \see QuotedStringWriter 422 /// \see IdMap 423 /// \see DescriptorMap 424 /// \see \ref GraphWriter 425 /// \see \ref graph-io-page 426 /// \author Balazs Dezso 427 template <typename _Graph, typename _WriterTraits = DefaultWriterTraits> 428 class UndirGraphWriter { 429 public: 430 431 typedef _Graph Graph; 432 typedef typename Graph::Node Node; 433 typedef typename Graph::Edge Edge; 434 typedef typename Graph::UndirEdge UndirEdge; 435 436 typedef _WriterTraits WriterTraits; 437 438 /// \brief Construct a new UndirGraphWriter. 439 /// 440 /// Construct a new UndirGraphWriter. It writes the given graph 441 /// to the given stream. 442 UndirGraphWriter(std::ostream& _os, const Graph& _graph) 443 : writer(new LemonWriter(_os)), own_writer(true), 444 nodeset_writer(*writer, _graph, std::string()), 445 undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()), 446 node_writer(*writer, nodeset_writer, std::string()), 447 undir_edge_writer(*writer, undir_edgeset_writer, std::string()), 448 attribute_writer(*writer, std::string()) {} 449 450 /// \brief Construct a new UndirGraphWriter. 451 /// 452 /// Construct a new UndirGraphWriter. It writes into the given graph 453 /// to the given file. 454 UndirGraphWriter(const std::string& _filename, const Graph& _graph) 455 : writer(new LemonWriter(_filename)), own_writer(true), 456 nodeset_writer(*writer, _graph, std::string()), 457 undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()), 458 node_writer(*writer, nodeset_writer, std::string()), 459 undir_edge_writer(*writer, undir_edgeset_writer, std::string()), 460 attribute_writer(*writer, std::string()) {} 461 462 /// \brief Construct a new UndirGraphWriter. 463 /// 464 /// Construct a new UndirGraphWriter. It writes into the given graph 465 /// to given LemonReader. 466 UndirGraphWriter(LemonWriter& _writer, const Graph& _graph) 467 : writer(_writer), own_writer(false), 468 nodeset_writer(*writer, _graph, std::string()), 469 undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()), 470 node_writer(*writer, nodeset_writer, std::string()), 471 undir_edge_writer(*writer, undir_edgeset_writer, std::string()), 472 attribute_writer(*writer, std::string()) {} 473 474 /// \brief Destruct the graph writer. 475 /// 476 /// Destruct the graph writer. 477 ~UndirGraphWriter() { 478 if (own_writer) 479 delete writer; 480 } 481 482 /// \brief Add a new node map writer command for the writer. 483 /// 484 /// Add a new node map writer command for the writer. 485 template <typename Map> 486 UndirGraphWriter& writeNodeMap(std::string name, const Map& map) { 487 nodeset_writer.writeNodeMap(name, map); 488 return *this; 489 } 490 491 /// \brief Add a new node map writer command for the writer. 492 /// 493 /// Add a new node map writer command for the writer. 494 template <typename Writer, typename Map> 495 UndirGraphWriter& writeNodeMap(std::string name, const Map& map, 496 const Writer& writer = Writer()) { 497 nodeset_writer.writeNodeMap(name, map, writer); 498 return *this; 499 } 500 501 /// \brief Add a new edge map writer command for the writer. 502 /// 503 /// Add a new edge map writer command for the writer. 504 template <typename Map> 505 UndirGraphWriter& writeEdgeMap(std::string name, const Map& map) { 506 undir_edgeset_writer.writeEdgeMap(name, map); 507 return *this; 508 } 509 510 /// \brief Add a new edge map writer command for the writer. 511 /// 512 /// Add a new edge map writer command for the writer. 513 template <typename Writer, typename Map> 514 UndirGraphWriter& writeEdgeMap(std::string name, const Map& map, 515 const Writer& writer = Writer()) { 516 undir_edgeset_writer.writeEdgeMap(name, map, writer); 517 return *this; 518 } 519 520 /// \brief Add a new undirected edge map writer command for the writer. 521 /// 522 /// Add a new undirected edge map writer command for the writer. 523 template <typename Map> 524 UndirGraphWriter& writeUndirEdgeMap(std::string name, const Map& map) { 525 undir_edgeset_writer.writeUndirEdgeMap(name, map); 526 return *this; 527 } 528 529 /// \brief Add a new undirected edge map writer command for the writer. 530 /// 531 /// Add a new edge undirected map writer command for the writer. 532 template <typename Writer, typename Map> 533 UndirGraphWriter& writeUndirEdgeMap(std::string name, const Map& map, 534 const Writer& writer = Writer()) { 535 undir_edgeset_writer.writeUndirEdgeMap(name, map, writer); 536 return *this; 537 } 538 539 /// \brief Add a new labeled node writer for the writer. 540 /// 541 /// Add a new labeled node writer for the writer. 542 UndirGraphWriter& writeNode(std::string name, const Node& node) { 543 node_writer.writeNode(name, node); 544 return *this; 545 } 546 547 /// \brief Add a new labeled edge writer for the writer. 548 /// 549 /// Add a new labeled edge writer for the writer. 550 UndirGraphWriter& writeUndirEdge(std::string name, const UndirEdge& edge) { 551 undir_edge_writer.writeUndirEdge(name, edge); 552 } 553 554 /// \brief Add a new attribute writer command. 555 /// 556 /// Add a new attribute writer command. 557 template <typename Value> 558 UndirGraphWriter& writeAttribute(std::string name, const Value& value) { 559 attribute_writer.writeAttribute(name, value); 560 return *this; 561 } 562 563 /// \brief Add a new attribute writer command. 564 /// 565 /// Add a new attribute writer command. 566 template <typename Writer, typename Value> 567 UndirGraphWriter& writeAttribute(std::string name, const Value& value, 568 const Writer& writer) { 569 attribute_writer.writeAttribute<Writer>(name, value, writer); 570 return *this; 571 } 572 573 /// \brief Conversion operator to LemonWriter. 574 /// 575 /// Conversion operator to LemonWriter. It make possible 576 /// to access the encapsulated \e LemonWriter, this way 577 /// you can attach to this writer new instances of 578 /// \e LemonWriter::SectionWriter. 579 operator LemonWriter&() { 580 return *writer; 581 } 582 583 /// \brief Executes the writer commands. 584 /// 585 /// Executes the writer commands. 586 void run() { 587 writer->run(); 588 } 589 590 private: 591 592 LemonWriter* writer; 593 bool own_writer; 594 595 NodeSetWriter<Graph, WriterTraits> nodeset_writer; 596 UndirEdgeSetWriter<Graph, WriterTraits> undir_edgeset_writer; 597 598 NodeWriter<Graph> node_writer; 599 UndirEdgeWriter<Graph> undir_edge_writer; 600 601 AttributeWriter<WriterTraits> attribute_writer; 602 }; 603 604 605 /// \brief Write an undirected graph to the output. 606 /// 607 /// Write an undirected graph to the output. 608 /// \param os The output stream. 609 /// \param g The graph. 610 /// \param capacity The capacity undirected map. 611 template<typename Graph, typename CapacityMap> 612 void writeUndirGraph(std::ostream& os, const Graph &g, 613 const CapacityMap& capacity) { 614 UndirGraphWriter<Graph> writer(os, g); 615 writer.writeUndirEdgeMap("capacity", capacity); 616 writer.run(); 617 } 618 619 /// \brief Write an undirected graph to the output. 620 /// 621 /// Write an undirected graph to the output. 622 /// \param os The output stream. 623 /// \param g The graph. 624 template<typename Graph> 625 void writeUndirGraph(std::ostream& os, const Graph &g) { 626 UndirGraphWriter<Graph> writer(os, g); 627 writer.run(); 628 } 629 363 630 /// @} 364 631 -
src/lemon/lemon_reader.h
r1409 r1421 19 19 ///\brief Lemon Format reader. 20 20 21 21 22 #ifndef LEMON_LEMON_READER_H 22 23 #define LEMON_LEMON_READER_H 24 23 25 24 26 #include <iostream> … … 31 33 32 34 #include <lemon/error.h> 35 #include <lemon/graph_utils.h> 36 #include <lemon/utility.h> 33 37 #include <lemon/bits/item_reader.h> 34 38 35 39 36 40 namespace lemon { 41 42 namespace _reader_bits { 43 44 template <typename T> 45 bool operator<(T, T) { 46 throw DataFormatError("Id is not comparable"); 47 } 48 49 template <typename T> 50 struct Less { 51 bool operator()(const T& p, const T& q) const { 52 return p < q; 53 } 54 }; 55 56 template <typename M1, typename M2> 57 class WriteComposeMap { 58 public: 59 typedef True NeedCopy; 60 61 typedef typename M2::Key Key; 62 typedef typename M1::Value Value; 63 64 WriteComposeMap(typename SmartParameter<M1>::Type _m1, const M2& _m2) 65 : m1(_m1), m2(_m2) {} 66 67 void set(const Key& key, const Value& value) { 68 m1.set(m2[key], value); 69 } 70 71 private: 72 73 typename SmartReference<M1>::Type m1; 74 typename SmartConstReference<M2>::Type m2; 75 76 }; 77 78 template <typename M1, typename M2> 79 WriteComposeMap<M1, M2> writeComposeMap(M1& m1, const M2& m2) { 80 return WriteComposeMap<M1, M2>(m1, m2); 81 } 82 83 template <typename M1, typename M2> 84 WriteComposeMap<M1, M2> writeComposeMap(const M1& m1, const M2& m2) { 85 return WriteComposeMap<M1, M2>(m1, m2); 86 } 87 88 } 37 89 38 90 /// \ingroup io_group … … 339 391 return this; 340 392 } 341 342 343 393 }; 344 394 … … 350 400 typedef typename Reader::Value Value; 351 401 typedef _Map Map; 352 typedef std::map<Value, Item> Inverse; 353 354 Map& map; 402 typedef std::map<Value, Item, 403 typename _reader_bits::template Less<Value> > Inverse; 404 405 typename SmartReference<Map>::Type map; 355 406 Reader reader; 356 407 Inverse inverse; 357 408 358 MapReaderInverter(Map& _map, const Reader& _reader) 409 MapReaderInverter(typename SmartParameter<Map>::Type _map, 410 const Reader& _reader) 359 411 : map(_map), reader(_reader) {} 360 412 … … 383 435 } 384 436 } 385 386 437 }; 387 438 … … 392 443 typedef _Reader Reader; 393 444 typedef typename Reader::Value Value; 394 typedef std::map<Value, Item> Inverse; 445 typedef std::map<Value, Item, 446 typename _reader_bits::template Less<Value> > Inverse; 395 447 396 448 Reader reader; … … 427 479 }; 428 480 429 // Readers430 431 481 template <typename _Item> 432 482 class ReaderBase { … … 448 498 typedef _Item Item; 449 499 450 Map↦500 typename SmartReference<Map>::Type map; 451 501 Reader reader; 452 502 453 MapReader(Map& _map, const Reader& _reader) 503 MapReader(typename SmartParameter<Map>::Type _map, 504 const Reader& _reader) 454 505 : map(_map), reader(_reader) {} 455 506 … … 570 621 /// add the readed nodes to the given Graph. The reader will read 571 622 /// the section when the \c section_id and the \c _id are the same. 572 NodeSetReader(LemonReader& _reader, Graph& _graph, 623 NodeSetReader(LemonReader& _reader, 624 typename SmartParameter<Graph>::Type _graph, 573 625 const std::string& _id = std::string(), 574 626 const DefaultSkipper& _skipper = DefaultSkipper()) … … 596 648 /// Add a new node map reader command for the reader. 597 649 template <typename Map> 598 NodeSetReader& readMap(std::string name, Map& map) { 599 return readMap<typename Traits:: 600 template Reader<typename Map::Value>, Map>(name, map); 650 NodeSetReader& readNodeMap(std::string name, Map& map) { 651 return _readMap< 652 typename Traits::template Reader<typename Map::Value>, Map, 653 typename SmartParameter<Map>::Type>(name, map); 654 } 655 656 template <typename Map> 657 NodeSetReader& readNodeMap(std::string name, const Map& map) { 658 return _readMap< 659 typename Traits::template Reader<typename Map::Value>, Map, 660 typename SmartParameter<Map>::Type>(name, map); 601 661 } 602 662 … … 605 665 /// Add a new node map reader command for the reader. 606 666 template <typename Reader, typename Map> 607 NodeSetReader& readMap(std::string name, Map& map, 608 const Reader& reader = Reader()) { 667 NodeSetReader& readNodeMap(std::string name, Map& map, 668 const Reader& reader = Reader()) { 669 return _readMap< 670 typename Traits::template Reader<typename Map::Value>, Map, 671 typename SmartParameter<Map>::Type>(name, map, reader); 672 } 673 674 template <typename Reader, typename Map> 675 NodeSetReader& readNodeMap(std::string name, const Map& map, 676 const Reader& reader = Reader()) { 677 return _readMap< 678 typename Traits::template Reader<typename Map::Value>, Map, 679 typename SmartParameter<Map>::Type>(name, map, reader); 680 } 681 682 private: 683 684 template <typename Reader, typename Map, typename MapParameter> 685 NodeSetReader& _readMap(std::string name, MapParameter map, 686 const Reader& reader = Reader()) { 609 687 if (readers.find(name) != readers.end()) { 610 688 ErrorMessage msg; … … 617 695 } 618 696 697 public: 698 619 699 /// \brief Add a new node map skipper command for the reader. 620 700 /// 621 701 /// Add a new node map skipper command for the reader. 622 702 template <typename Reader> 623 NodeSetReader& skip Map(std::string name,703 NodeSetReader& skipNodeMap(std::string name, 624 704 const Reader& reader = Reader()) { 625 705 if (readers.find(name) != readers.end()) { … … 637 717 /// the section with the given header line. 638 718 /// 639 /// It gives back true when the header line starts with \c @nodeset,719 /// It gives back true when the header line starts with \c \@nodeset, 640 720 /// and the header line's id and the nodeset's id are the same. 641 721 virtual bool header(const std::string& line) { … … 691 771 /// It reads an id from the stream and gives back which node belongs to 692 772 /// it. It is possible only if there was read an "id" named map. 693 typename Graph::NodereadId(std::istream& is) const {773 Item readId(std::istream& is) const { 694 774 return inverter->read(is); 695 775 } … … 700 780 MapReaders readers; 701 781 702 Graph&graph;782 typename SmartReference<Graph>::Type graph; 703 783 std::string id; 704 784 SkipReader<Item, DefaultSkipper> skipper; … … 715 795 /// 716 796 /// The first line of the section contains the names of the maps separated 717 /// with white spaces. Each next lines describes a node in the nodeset. The 718 /// line contains the two nodes' id and the mapped values for each map. 797 /// with white spaces. Each next lines describes an edge in the edgeset. The 798 /// line contains the source and the target nodes' id and the mapped 799 /// values for each map. 719 800 /// 720 801 /// If the edgeset contains an \c "id" named map then it will be regarded … … 747 828 /// \c edgset_id are the same. 748 829 template <typename NodeIdReader> 749 EdgeSetReader(LemonReader& _reader, Graph& _graph, 830 EdgeSetReader(LemonReader& _reader, 831 typename SmartParameter<Graph>::Type _graph, 750 832 const NodeIdReader& _nodeIdReader, 751 833 const std::string& _id = std::string(), … … 775 857 /// Add a new edge map reader command for the reader. 776 858 template <typename Map> 777 EdgeSetReader& readMap(std::string name, Map& map) { 778 return readMap<typename Traits:: 779 template Reader<typename Map::Value>, Map>(name, map); 859 EdgeSetReader& readEdgeMap(std::string name, Map& map) { 860 return _readMap< 861 typename Traits::template Reader<typename Map::Value>, Map, 862 typename SmartParameter<Map>::Type>(name, map); 863 } 864 865 template <typename Map> 866 EdgeSetReader& readEdgeMap(std::string name, const Map& map) { 867 return _readMap< 868 typename Traits::template Reader<typename Map::Value>, Map, 869 typename SmartParameter<Map>::Type>(name, map); 780 870 } 781 871 … … 784 874 /// Add a new edge map reader command for the reader. 785 875 template <typename Reader, typename Map> 786 EdgeSetReader& readMap(std::string name, Map& map, 787 const Reader& reader = Reader()) { 876 EdgeSetReader& readEdgeMap(std::string name, Map& map, 877 const Reader& reader = Reader()) { 878 return _readMap< 879 typename Traits::template Reader<typename Map::Value>, Map, 880 typename SmartParameter<Map>::Type>(name, map, reader); 881 } 882 883 template <typename Reader, typename Map> 884 EdgeSetReader& readEdgeMap(std::string name, const Map& map, 885 const Reader& reader = Reader()) { 886 return _readMap< 887 typename Traits::template Reader<typename Map::Value>, Map, 888 typename SmartParameter<Map>::Type>(name, map, reader); 889 } 890 891 private: 892 893 template <typename Reader, typename Map, typename MapParameter> 894 EdgeSetReader& _readMap(std::string name, MapParameter map, 895 const Reader& reader = Reader()) { 788 896 if (readers.find(name) != readers.end()) { 789 897 ErrorMessage msg; … … 796 904 } 797 905 906 public: 907 798 908 /// \brief Add a new edge map skipper command for the reader. 799 909 /// 800 910 /// Add a new edge map skipper command for the reader. 801 911 template <typename Reader> 802 EdgeSetReader& skip Map(std::string name,803 const Reader& reader = Reader()) {912 EdgeSetReader& skipEdgeMap(std::string name, 913 const Reader& reader = Reader()) { 804 914 if (readers.find(name) != readers.end()) { 805 915 ErrorMessage msg; 806 msg << "Multiple read rule for node map: " << name;916 msg << "Multiple read rule for edge map: " << name; 807 917 throw IOParameterError(msg.message()); 808 918 } … … 816 926 /// the section with the given header line. 817 927 /// 818 /// It gives back true when the header line starts with \c @edgeset,928 /// It gives back true when the header line starts with \c \@edgeset, 819 929 /// and the header line's id and the edgeset's id are the same. 820 930 virtual bool header(const std::string& line) { … … 872 982 /// It reads an id from the stream and gives back which edge belongs to 873 983 /// it. It is possible only if there was read an "id" named map. 874 typename Graph::EdgereadId(std::istream& is) const {984 Item readId(std::istream& is) const { 875 985 return inverter->read(is); 876 986 } … … 881 991 MapReaders readers; 882 992 883 Graph& graph; 993 typename SmartReference<Graph>::Type graph; 994 std::string id; 995 SkipReader<Item, DefaultSkipper> skipper; 996 997 std::auto_ptr<InverterBase<Item> > inverter; 998 std::auto_ptr<IdReaderBase<typename Graph::Node> > nodeIdReader; 999 }; 1000 1001 /// \ingroup io_group 1002 /// \brief SectionReader for reading a undirected graph's edgeset. 1003 /// 1004 /// The lemon format can store multiple undirected edgesets with several 1005 /// maps. The undirected edgeset section's header line is \c \@undiredgeset 1006 /// \c undiredgeset_id, but the \c undiredgeset_id may be empty. 1007 /// 1008 /// The first line of the section contains the names of the maps separated 1009 /// with white spaces. Each next lines describes an edge in the edgeset. The 1010 /// line contains the connected nodes' id and the mapped values for each map. 1011 /// 1012 /// The section can handle the directed as a syntactical sugar. Two 1013 /// undirected edge map describes one directed edge map. This two maps 1014 /// are the forward map and the backward map and the names of this map 1015 /// is near the same just with a prefix \c '+' or \c '-' character 1016 /// difference. 1017 /// 1018 /// If the edgeset contains an \c "id" named map then it will be regarded 1019 /// as id map. This map should contain only unique values and when the 1020 /// \c readId() member will read a value from the given stream it will 1021 /// give back that undiricted edge which is mapped to this value. 1022 /// 1023 /// The undirected edgeset reader needs a node id reader to identify which 1024 /// nodes have to be connected. If a NodeSetReader reads an "id" named map, 1025 /// it will be able to resolve the nodes by ids. 1026 /// 1027 /// \relates LemonReader 1028 template <typename _Graph, typename _Traits = DefaultReaderTraits> 1029 class UndirEdgeSetReader : public CommonSectionReaderBase { 1030 typedef CommonSectionReaderBase Parent; 1031 public: 1032 1033 typedef _Graph Graph; 1034 typedef _Traits Traits; 1035 typedef typename Graph::UndirEdge Item; 1036 typedef typename Traits::Skipper DefaultSkipper; 1037 1038 /// \brief Constructor. 1039 /// 1040 /// Constructor for UndirEdgeSetReader. It creates the UndirEdgeSetReader 1041 /// and attach it into the given LemonReader. The undirected edgeset 1042 /// reader will add the readed undirected edges to the given Graph. It 1043 /// will use the given node id reader to read the source and target 1044 /// nodes of the edges. The reader will read the section only if the 1045 /// \c _id and the \c undiredgset_id are the same. 1046 template <typename NodeIdReader> 1047 UndirEdgeSetReader(LemonReader& _reader, 1048 typename SmartParameter<Graph>::Type _graph, 1049 const NodeIdReader& _nodeIdReader, 1050 const std::string& _id = std::string(), 1051 const DefaultSkipper& _skipper = DefaultSkipper()) 1052 : Parent(_reader), graph(_graph), id(_id), skipper(_skipper), 1053 nodeIdReader(new IdReader<typename Graph::Node, NodeIdReader> 1054 (_nodeIdReader)) {} 1055 1056 /// \brief Destructor. 1057 /// 1058 /// Destructor for UndirEdgeSetReader. 1059 virtual ~UndirEdgeSetReader() { 1060 for (typename MapReaders::iterator it = readers.begin(); 1061 it != readers.end(); ++it) { 1062 delete it->second; 1063 } 1064 } 1065 1066 private: 1067 UndirEdgeSetReader(const UndirEdgeSetReader&); 1068 void operator=(const UndirEdgeSetReader&); 1069 1070 public: 1071 1072 /// \brief Add a new undirected edge map reader command for the reader. 1073 /// 1074 /// Add a new edge undirected map reader command for the reader. 1075 template <typename Map> 1076 UndirEdgeSetReader& readUndirEdgeMap(std::string name, Map& map) { 1077 return _readMap< 1078 typename Traits::template Reader<typename Map::Value>, Map, 1079 typename SmartParameter<Map>::Type>(name, map); 1080 } 1081 1082 template <typename Map> 1083 UndirEdgeSetReader& readUndirEdgeMap(std::string name, const Map& map) { 1084 return _readMap< 1085 typename Traits::template Reader<typename Map::Value>, Map, 1086 typename SmartParameter<Map>::Type>(name, map); 1087 } 1088 1089 /// \brief Add a new undirected edge map reader command for the reader. 1090 /// 1091 /// Add a new edge undirected map reader command for the reader. 1092 template <typename Reader, typename Map> 1093 UndirEdgeSetReader& readUndirEdgeMap(std::string name, Map& map, 1094 const Reader& reader = Reader()) { 1095 return _readMap<Reader, Map, typename SmartParameter<Map>::Type> 1096 (name, map, reader); 1097 } 1098 1099 template <typename Reader, typename Map> 1100 UndirEdgeSetReader& readUndirEdgeMap(std::string name, const Map& map, 1101 const Reader& reader = Reader()) { 1102 return _readMap<Reader, Map, typename SmartParameter<Map>::Type > 1103 (name, map, reader); 1104 } 1105 1106 private: 1107 1108 template <typename Reader, typename Map, typename MapParameter> 1109 UndirEdgeSetReader& _readMap(std::string name, MapParameter map, 1110 const Reader& reader = Reader()) { 1111 if (readers.find(name) != readers.end()) { 1112 ErrorMessage msg; 1113 msg << "Multiple read rule for edge map: " << name; 1114 throw IOParameterError(msg.message()); 1115 } 1116 readers.insert( 1117 make_pair(name, new MapReader<Item, Map, Reader>(map, reader))); 1118 return *this; 1119 } 1120 1121 public: 1122 1123 /// \brief Add a new undirected edge map skipper command for the reader. 1124 /// 1125 /// Add a new undirected edge map skipper command for the reader. 1126 template <typename Reader> 1127 UndirEdgeSetReader& skipUndirEdgeMap(std::string name, 1128 const Reader& reader = Reader()) { 1129 if (readers.find(name) != readers.end()) { 1130 ErrorMessage msg; 1131 msg << "Multiple read rule for node map: " << name; 1132 throw IOParameterError(msg.message()); 1133 } 1134 readers.insert(make_pair(name, new SkipReader<Item, Reader>(reader))); 1135 return *this; 1136 } 1137 1138 /// \brief Add a new directed edge map reader command for the reader. 1139 /// 1140 /// Add a new directed edge map reader command for the reader. 1141 template <typename Map> 1142 UndirEdgeSetReader& readEdgeMap(std::string name, Map& map) { 1143 return _readDirMap< 1144 typename Traits::template Reader<typename Map::Value>, Map, 1145 typename SmartParameter<Map>::Type>(name, map); 1146 } 1147 1148 template <typename Map> 1149 UndirEdgeSetReader& readEdgeMap(std::string name, const Map& map) { 1150 return _readDirMap< 1151 typename Traits::template Reader<typename Map::Value>, Map, 1152 typename SmartParameter<Map>::Type>(name, map); 1153 } 1154 1155 /// \brief Add a new directed edge map reader command for the reader. 1156 /// 1157 /// Add a new directed edge map reader command for the reader. 1158 template <typename Reader, typename Map> 1159 UndirEdgeSetReader& readEdgeMap(std::string name, Map& map, 1160 const Reader& reader = Reader()) { 1161 return _readDirMap<Reader, Map, typename SmartParameter<Map>::Type> 1162 (name, map, reader); 1163 } 1164 1165 template <typename Reader, typename Map> 1166 UndirEdgeSetReader& readEdgeMap(std::string name, const Map& map, 1167 const Reader& reader = Reader()) { 1168 return _readDirMap<Reader, Map, typename SmartParameter<Map>::Type> 1169 (name, map, reader); 1170 } 1171 1172 private: 1173 1174 template <typename Reader, typename Map, typename MapParameter> 1175 UndirEdgeSetReader& _readDirMap(std::string name, MapParameter map, 1176 const Reader& reader = Reader()) { 1177 readMap("+" + name, 1178 _reader_bits::writeComposeMap(map, forwardMap(graph)), reader); 1179 readMap("-" + name, 1180 _reader_bits::writeComposeMap(map, backwardMap(graph)), reader); 1181 return *this; 1182 } 1183 1184 public: 1185 1186 /// \brief Add a new directed edge map skipper command for the reader. 1187 /// 1188 /// Add a new directed edge map skipper command for the reader. 1189 template <typename Reader> 1190 UndirEdgeSetReader& skipEdgeMap(std::string name, 1191 const Reader& reader = Reader()) { 1192 skipMap("+" + name, reader); 1193 skipMap("-" + name, reader); 1194 return *this; 1195 } 1196 1197 protected: 1198 1199 /// \brief Gives back true when the SectionReader can process 1200 /// the section with the given header line. 1201 /// 1202 /// It gives back true when the header line starts with \c \@undiredgeset, 1203 /// and the header line's id and the edgeset's id are the same. 1204 virtual bool header(const std::string& line) { 1205 std::istringstream ls(line); 1206 std::string command; 1207 std::string name; 1208 ls >> command >> name; 1209 return command == "@undiredgeset" && name == id; 1210 } 1211 1212 /// \brief Reader function of the section. 1213 /// 1214 /// It reads the content of the section. 1215 virtual void read(std::istream& is) { 1216 std::vector<ReaderBase<Item>* > index; 1217 std::string line; 1218 1219 getline(is, line); 1220 std::istringstream ls(line); 1221 while (ls >> id) { 1222 typename MapReaders::iterator it = readers.find(id); 1223 if (it != readers.end()) { 1224 index.push_back(it->second); 1225 } else { 1226 index.push_back(&skipper); 1227 } 1228 if (id == "id" && inverter.get() == 0) { 1229 inverter.reset(index.back()->getInverter()); 1230 index.back() = inverter.get(); 1231 } 1232 } 1233 while (getline(is, line)) { 1234 std::istringstream ls(line); 1235 typename Graph::Node from = nodeIdReader->read(ls); 1236 typename Graph::Node to = nodeIdReader->read(ls); 1237 typename Graph::UndirEdge edge = graph.addEdge(from, to); 1238 for (int i = 0; i < (int)index.size(); ++i) { 1239 index[i]->read(ls, edge); 1240 } 1241 } 1242 } 1243 1244 public: 1245 1246 /// \brief Returns true if the edgeset can give back the edge by its id. 1247 /// 1248 /// Returns true if the edgeset can give back the undirected edge by its 1249 /// id. It is possible only if an "id" named map was read. 1250 bool isIdReader() const { 1251 return inverter.get() != 0; 1252 } 1253 1254 /// \brief Gives back the undirected edge by its id. 1255 /// 1256 /// It reads an id from the stream and gives back which undirected edge 1257 /// belongs to it. It is possible only if there was read an "id" named map. 1258 Item readId(std::istream& is) const { 1259 return inverter->read(is); 1260 } 1261 1262 private: 1263 1264 typedef std::map<std::string, ReaderBase<Item>*> MapReaders; 1265 MapReaders readers; 1266 1267 typename SmartReference<Graph>::Type graph; 884 1268 std::string id; 885 1269 SkipReader<Item, DefaultSkipper> skipper; … … 946 1330 /// the section with the given header line. 947 1331 /// 948 /// It gives back true when the header line start with \c @nodes,1332 /// It gives back true when the header line start with \c \@nodes, 949 1333 /// and the header line's id and the reader's id are the same. 950 1334 virtual bool header(const std::string& line) { … … 1003 1387 /// attach it into the given LemonReader. It will use the given 1004 1388 /// edge id reader to give back the edges. The reader will read the 1005 /// section only if the \c _id and the \c nodes_id are the same.1389 /// section only if the \c _id and the \c edges_id are the same. 1006 1390 template <typename _IdReader> 1007 1391 EdgeReader(LemonReader& _reader, const _IdReader& _idReader, … … 1037 1421 /// the section with the given header line. 1038 1422 /// 1039 /// It gives back true when the header line start with \c @edges,1423 /// It gives back true when the header line start with \c \@edges, 1040 1424 /// and the header line's id and the reader's id are the same. 1041 1425 virtual bool header(const std::string& line) { … … 1073 1457 1074 1458 /// \ingroup io_group 1459 /// \brief SectionReader for reading labeled undirected edges. 1460 /// 1461 /// The undirected edges section's header line is \c \@undiredges 1462 /// \c undiredges_id, but the \c undiredges_id may be empty. 1463 /// 1464 /// Each line in the section contains the name of the undirected edge 1465 /// and then the undirected edge id. 1466 /// 1467 /// \relates LemonReader 1468 template <typename _Graph> 1469 class UndirEdgeReader : public CommonSectionReaderBase { 1470 typedef CommonSectionReaderBase Parent; 1471 typedef _Graph Graph; 1472 typedef typename Graph::UndirEdge Item; 1473 public: 1474 1475 /// \brief Constructor. 1476 /// 1477 /// Constructor for UndirEdgeReader. It creates the UndirEdgeReader and 1478 /// attach it into the given LemonReader. It will use the given 1479 /// undirected edge id reader to give back the edges. The reader will 1480 /// read the section only if the \c _id and the \c undiredges_id are 1481 /// the same. 1482 template <typename _IdReader> 1483 UndirEdgeReader(LemonReader& _reader, const _IdReader& _idReader, 1484 const std::string& _id = std::string()) 1485 : Parent(_reader), id(_id), 1486 idReader(new IdReader<typename Graph::UndirEdge, _IdReader>(_idReader)) 1487 {} 1488 1489 /// \brief Destructor. 1490 /// 1491 /// Destructor for UndirEdgeReader. 1492 virtual ~UndirEdgeReader() {} 1493 private: 1494 UndirEdgeReader(const UndirEdgeReader&); 1495 void operator=(const UndirEdgeReader&); 1496 1497 public: 1498 1499 /// \brief Add an undirected edge reader command for the UndirEdgeReader. 1500 /// 1501 /// Add an undirected edge reader command for the UndirEdgeReader. 1502 void readUndirEdge(const std::string& name, Item& item) { 1503 if (readers.find(name) != readers.end()) { 1504 ErrorMessage msg; 1505 msg << "Multiple read rule for edge: " << name; 1506 throw IOParameterError(msg.message()); 1507 } 1508 readers.insert(make_pair(name, &item)); 1509 } 1510 1511 protected: 1512 1513 /// \brief Gives back true when the SectionReader can process 1514 /// the section with the given header line. 1515 /// 1516 /// It gives back true when the header line start with \c \@edges, 1517 /// and the header line's id and the reader's id are the same. 1518 virtual bool header(const std::string& line) { 1519 std::istringstream ls(line); 1520 std::string command; 1521 std::string name; 1522 ls >> command >> name; 1523 return command == "@edges" && name == id; 1524 } 1525 1526 /// \brief Reader function of the section. 1527 /// 1528 /// It reads the content of the section. 1529 virtual void read(std::istream& is) { 1530 std::string line; 1531 while (getline(is, line)) { 1532 std::istringstream ls(line); 1533 std::string id; 1534 ls >> id; 1535 typename ItemReaders::iterator it = readers.find(id); 1536 if (it != readers.end()) { 1537 *(it->second) = idReader->read(ls); 1538 } 1539 } 1540 } 1541 1542 private: 1543 1544 std::string id; 1545 1546 typedef std::map<std::string, Item*> ItemReaders; 1547 ItemReaders readers; 1548 std::auto_ptr<IdReaderBase<Item> > idReader; 1549 }; 1550 1551 /// \ingroup io_group 1075 1552 /// \brief SectionReader for attributes. 1076 1553 /// … … 1142 1619 /// the section with the given header line. 1143 1620 /// 1144 /// It gives back true when the header line start with \c @attributes,1621 /// It gives back true when the header line start with \c \@attributes, 1145 1622 /// and the header line's id and the attributeset's id are the same. 1146 1623 bool header(const std::string& line) { … … 1175 1652 }; 1176 1653 1177 1178 1654 } 1179 1655 #endif -
src/lemon/lemon_writer.h
r1411 r1421 32 32 #include <lemon/error.h> 33 33 #include <lemon/invalid.h> 34 #include <lemon/graph_utils.h> 34 35 #include <lemon/bits/item_writer.h> 36 #include <lemon/utility.h> 37 #include <lemon/maps.h> 35 38 36 39 … … 164 167 : Parent(_writer) {} 165 168 166 // Writers167 168 169 template <typename _Item> 169 170 class WriterBase { … … 185 186 typedef _Item Item; 186 187 187 const Map↦188 typename SmartConstReference<Map>::Type map; 188 189 Writer writer; 189 190 … … 307 308 /// Add a new node map writer command for the writer. 308 309 template <typename Map> 309 NodeSetWriter& write Map(std::string name, const Map& map) {310 return write Map<typename Traits::310 NodeSetWriter& writeNodeMap(std::string name, const Map& map) { 311 return writeNodeMap<typename Traits:: 311 312 template Writer<typename Map::Value>, Map>(name, map); 312 313 } … … 316 317 /// Add a new node map writer command for the writer. 317 318 template <typename Writer, typename Map> 318 NodeSetWriter& write Map(std::string name, const Map& map,319 319 NodeSetWriter& writeNodeMap(std::string name, const Map& map, 320 const Writer& writer = Writer()) { 320 321 writers.push_back( 321 322 make_pair(name, new MapWriter<Item, Map, Writer>(map, writer))); … … 395 396 bool forceIdMap; 396 397 397 const Graph&graph;398 typename SmartConstReference<Graph>::Type graph; 398 399 std::string id; 399 400 … … 401 402 402 403 /// \ingroup io_group 403 /// \brief SectionWriter for writing a graph's edgeset .404 /// 405 /// The lemon format can store multiple graph edgesets with several maps. 404 /// \brief SectionWriter for writing a graph's edgesets. 405 /// 406 /// The lemon format can store multiple graph edgesets with several maps. 406 407 /// The edgeset section's header line is \c \@edgeset \c edgeset_id, but the 407 408 /// \c edgeset_id may be empty. … … 414 415 /// If the edgeset contains an \c "id" named map then it will be regarded 415 416 /// as id map. This map should contain only unique values and when the 416 /// \c writeId() member will be called with a edge it will write it's id.417 /// \c writeId() member will be called with an edge it will write it's id. 417 418 /// Otherwise if the \c _forceIdMap constructor parameter is true then 418 419 /// the id map will be the id in the graph. … … 437 438 /// attach it into the given LemonWriter. It will write node ids by 438 439 /// the \c _nodeIdWriter. If the \c _forceIdMap parameter is true 439 /// then the writer will write own id map whenthe user does not give440 /// then the writer will write own id map if the user does not give 440 441 /// "id" named map. 441 442 template <typename NodeIdWriter> … … 465 466 public: 466 467 467 /// \brief Add a new node map writer command for the writer.468 /// 469 /// Add a new node map writer command for the writer.468 /// \brief Add a new edge map writer command for the writer. 469 /// 470 /// Add a new edge map writer command for the writer. 470 471 template <typename Map> 471 EdgeSetWriter& write Map(std::string name, const Map& map) {472 return write Map<typename Traits::472 EdgeSetWriter& writeEdgeMap(std::string name, const Map& map) { 473 return writeEdgeMap<typename Traits:: 473 474 template Writer<typename Map::Value>, Map>(name, map); 474 475 } 475 476 476 /// \brief Add a new node map writer command for the writer.477 /// 478 /// Add a new node map writer command for the writer.477 /// \brief Add a new edge map writer command for the writer. 478 /// 479 /// Add a new edge map writer command for the writer. 479 480 template <typename Writer, typename Map> 480 EdgeSetWriter& write Map(std::string name, const Map& map,481 481 EdgeSetWriter& writeEdgeMap(std::string name, const Map& map, 482 const Writer& writer = Writer()) { 482 483 writers.push_back( 483 484 make_pair(name, new MapWriter<Item, Map, Writer>(map, writer))); … … 562 563 bool forceIdMap; 563 564 564 const Graph& graph; 565 typename SmartConstReference<Graph>::Type graph; 566 std::string id; 567 568 std::auto_ptr<IdWriterBase<typename Graph::Node> > nodeIdWriter; 569 }; 570 571 /// \ingroup io_group 572 /// \brief SectionWriter for writing a undirected edgeset. 573 /// 574 /// The lemon format can store multiple undirected edgesets with several 575 /// maps. The undirected edgeset section's header line is \c \@undiredgeset 576 /// \c undiredgeset_id, but the \c undiredgeset_id may be empty. 577 /// 578 /// The first line of the section contains the names of the maps separated 579 /// with white spaces. Each next lines describes an undirected edge in the 580 /// edgeset. The line contains the two connected nodes' id and the mapped 581 /// values for each undirected map. 582 /// 583 /// The section can handle the directed as a syntactical sugar. Two 584 /// undirected edge map describes one directed edge map. This two maps 585 /// are the forward map and the backward map and the names of this map 586 /// is near the same just with a prefix \c '+' or \c '-' character 587 /// difference. 588 /// 589 /// If the edgeset contains an \c "id" named map then it will be regarded 590 /// as id map. This map should contain only unique values and when the 591 /// \c writeId() member will be called with an undirected edge it will 592 /// write it's id. Otherwise if the \c _forceIdMap constructor parameter 593 /// is true then the id map will be the id in the graph. 594 /// 595 /// The undirected edgeset writer needs a node id writer to identify 596 /// which nodes have to be connected. If a NodeSetWriter can write the 597 /// nodes' id, it will be able to use with this class. 598 /// 599 /// \relates LemonWriter 600 template <typename _Graph, typename _Traits = DefaultWriterTraits> 601 class UndirEdgeSetWriter : public CommonSectionWriterBase { 602 typedef CommonSectionWriterBase Parent; 603 public: 604 605 typedef _Graph Graph; 606 typedef _Traits Traits; 607 typedef typename Graph::UndirEdge Item; 608 609 /// \brief Constructor. 610 /// 611 /// Constructor for UndirEdgeSetWriter. It creates the UndirEdgeSetWriter 612 /// and attach it into the given LemonWriter. It will write node ids by 613 /// the \c _nodeIdWriter. If the \c _forceIdMap parameter is true 614 /// then the writer will write own id map if the user does not give 615 /// "id" named map. 616 template <typename NodeIdWriter> 617 UndirEdgeSetWriter(LemonWriter& _writer, const Graph& _graph, 618 const NodeIdWriter& _nodeIdWriter, 619 const std::string& _id = std::string(), 620 bool _forceIdMap = true) 621 : Parent(_writer), idMap(0), forceIdMap(_forceIdMap), 622 graph(_graph), id(_id), 623 nodeIdWriter(new IdWriter<typename Graph::Node, NodeIdWriter> 624 (_nodeIdWriter)) {} 625 626 /// \brief Destructor. 627 /// 628 /// Destructor for UndirEdgeSetWriter. 629 virtual ~UndirEdgeSetWriter() { 630 typename MapWriters::iterator it; 631 for (it = writers.begin(); it != writers.end(); ++it) { 632 delete it->second; 633 } 634 } 635 636 private: 637 UndirEdgeSetWriter(const UndirEdgeSetWriter&); 638 void operator=(const UndirEdgeSetWriter&); 639 640 public: 641 642 /// \brief Add a new undirected edge map writer command for the writer. 643 /// 644 /// Add a new undirected map writer command for the writer. 645 template <typename Map> 646 UndirEdgeSetWriter& writeUndirEdgeMap(std::string name, const Map& map) { 647 return writeUndirEdgeMap<typename Traits:: 648 template Writer<typename Map::Value>, Map>(name, map); 649 } 650 651 /// \brief Add a new undirected map writer command for the writer. 652 /// 653 /// Add a new undirected map writer command for the writer. 654 template <typename Writer, typename Map> 655 UndirEdgeSetWriter& writeUndirEdgeMap(std::string name, const Map& map, 656 const Writer& writer = Writer()) { 657 writers.push_back( 658 make_pair(name, new MapWriter<Item, Map, Writer>(map, writer))); 659 return *this; 660 } 661 662 /// \brief Add a new directed edge map writer command for the writer. 663 /// 664 /// Add a new directed map writer command for the writer. 665 template <typename Map> 666 UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map) { 667 writeUndirEdgeMap("+" + name, composeMap(forwardMap(graph), map)); 668 writeUndirEdgeMap("-" + name, composeMap(backwardMap(graph), map)); 669 return *this; 670 } 671 672 /// \brief Add a new directed map writer command for the writer. 673 /// 674 /// Add a new directed map writer command for the writer. 675 template <typename Writer, typename Map> 676 UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map, 677 const Writer& writer = Writer()) { 678 writeUndirEdge("+" + name, composeMap(forwardMap(graph), map), writer); 679 writeUndirEdge("-" + name, composeMap(forwardMap(graph), map), writer); 680 return *this; 681 } 682 683 protected: 684 685 /// \brief The header of the section. 686 /// 687 /// It gives back the header of the section. 688 virtual std::string header() { 689 return "@undiredgeset " + id; 690 } 691 692 /// \brief Writer function of the section. 693 /// 694 /// Write the content of the section. 695 virtual void write(std::ostream& os) { 696 for (int i = 0; i < (int)writers.size(); ++i) { 697 if (writers[i].first == "id") { 698 idMap = writers[i].second; 699 forceIdMap = false; 700 break; 701 } 702 } 703 os << "\t\t"; 704 if (forceIdMap) { 705 os << "id\t"; 706 } 707 for (int i = 0; i < (int)writers.size(); ++i) { 708 os << writers[i].first << '\t'; 709 } 710 os << std::endl; 711 for (typename Graph::UndirEdgeIt it(graph); it != INVALID; ++it) { 712 nodeIdWriter->write(os, graph.source(it)); 713 os << '\t'; 714 nodeIdWriter->write(os, graph.target(it)); 715 os << '\t'; 716 if (forceIdMap) { 717 os << graph.id(it) << '\t'; 718 } 719 for (int i = 0; i < (int)writers.size(); ++i) { 720 writers[i].second->write(os, it); 721 os << '\t'; 722 } 723 os << std::endl; 724 } 725 } 726 727 public: 728 729 /// \brief Returns true if the undirected edgeset can write the ids of 730 /// the edges. 731 /// 732 /// Returns true if the undirected edgeset can write the ids of the 733 /// undirected edges. It is possible only if an "id" named map was 734 /// written or the \c _forceIdMap constructor parameter was true. 735 bool isIdWriter() const { 736 return forceIdMap || idMap != 0; 737 } 738 739 /// \brief Write the id of the given undirected edge. 740 /// 741 /// It writes the id of the given undirected edge. If there was written 742 /// an "id" named map then it will write the map value belongs to the 743 /// undirected edge. Otherwise if the \c forceId parameter was true it 744 /// will write its id in the graph. 745 void writeId(std::ostream& os, const Item& item) const { 746 if (forceIdMap) { 747 os << graph.id(item); 748 } else { 749 idMap->write(os, item); 750 } 751 } 752 753 private: 754 755 typedef std::vector<std::pair<std::string, WriterBase<Item>*> > MapWriters; 756 MapWriters writers; 757 758 WriterBase<Item>* idMap; 759 bool forceIdMap; 760 761 typename SmartConstReference<Graph>::Type graph; 565 762 std::string id; 566 763 … … 618 815 /// \brief Header checking function. 619 816 /// 620 /// It gives back true when the header line start with \c @nodes,817 /// It gives back true when the header line start with \c \@nodes, 621 818 /// and the header line's id and the writer's id are the same. 622 819 virtual std::string header() { … … 645 842 646 843 /// \ingroup io_group 647 /// \brief SectionWriter for writ eing labeled edges.844 /// \brief SectionWriter for writing labeled edges. 648 845 /// 649 846 /// The edges section's header line is \c \@edges \c edges_id, but the … … 682 879 public: 683 880 684 /// \brief Add an edge writer command for the NodeWriter.685 /// 686 /// Add an edge writer command for the NodeWriter.881 /// \brief Add an edge writer command for the EdgeWriter. 882 /// 883 /// Add an edge writer command for the EdgeWriter. 687 884 void writeEdge(const std::string& name, const Item& item) { 688 885 writers.push_back(make_pair(name, &item)); … … 693 890 /// \brief Header checking function. 694 891 /// 695 /// It gives back true when the header line start with \c @nodes, 892 /// It gives back true when the header line start with \c \@edges, 893 /// and the header line's id and the writer's id are the same. 894 virtual std::string header() { 895 return "@edges " + id; 896 } 897 898 /// \brief Writer function of the section. 899 /// 900 /// Write the content of the section. 901 virtual void write(std::ostream& os) { 902 for (int i = 0; i < (int)writers.size(); ++i) { 903 os << writers[i].first << ' '; 904 idWriter->write(os, *(writers[i].second)); 905 os << std::endl; 906 } 907 } 908 909 private: 910 911 std::string id; 912 913 typedef std::vector<std::pair<std::string, const Item*> > ItemWriters; 914 ItemWriters writers; 915 916 std::auto_ptr<IdWriterBase<Item> > idWriter; 917 }; 918 919 /// \ingroup io_group 920 /// \brief SectionWriter for writing labeled undirected edges. 921 /// 922 /// The undirected edges section's header line is \c \@undiredges 923 /// \c undiredges_id, but the \c undiredges_id may be empty. 924 /// 925 /// Each line in the section contains the label of the undirected edge and 926 /// then the undirected edge id. 927 /// 928 /// \relates LemonWriter 929 template <typename _Graph> 930 class UndirEdgeWriter : public CommonSectionWriterBase { 931 typedef CommonSectionWriterBase Parent; 932 typedef _Graph Graph; 933 typedef typename Graph::UndirEdge Item; 934 public: 935 936 /// \brief Constructor. 937 /// 938 /// Constructor for UndirEdgeWriter. It creates the UndirEdgeWriter and 939 /// attach it into the given LemonWriter. The given \c _IdWriter 940 /// will write the undirected edges' id what can be an undirected 941 /// edgeset writer. 942 template <typename _IdWriter> 943 UndirEdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter, 944 const std::string& _id = std::string()) 945 : Parent(_writer), id(_id), 946 idWriter(new IdWriter<typename Graph::UndirEdge, _IdWriter> 947 (_idWriter)) {} 948 949 /// \brief Destructor. 950 /// 951 /// Destructor for UndirEdgeWriter. 952 virtual ~UndirEdgeWriter() {} 953 private: 954 UndirEdgeWriter(const UndirEdgeWriter&); 955 void operator=(const UndirEdgeWriter&); 956 957 public: 958 959 /// \brief Add an undirected edge writer command for the UndirEdgeWriter. 960 /// 961 /// Add an edge writer command for the UndirEdgeWriter. 962 void writeUndirEdge(const std::string& name, const Item& item) { 963 writers.push_back(make_pair(name, &item)); 964 } 965 966 protected: 967 968 /// \brief Header checking function. 969 /// 970 /// It gives back true when the header line start with \c \@undiredges, 696 971 /// and the header line's id and the writer's id are the same. 697 972 virtual std::string header() {
Note: See TracChangeset
for help on using the changeset viewer.