45 |
45 |
46 namespace lemon { |
46 namespace lemon { |
47 |
47 |
48 namespace _writer_bits { |
48 namespace _writer_bits { |
49 |
49 |
|
50 template <typename T> |
|
51 bool operator<(T, T) { |
|
52 throw DataFormatError("Label is not comparable"); |
|
53 } |
|
54 |
|
55 template <typename T> |
|
56 struct Less { |
|
57 bool operator()(const T& p, const T& q) const { |
|
58 return p < q; |
|
59 } |
|
60 }; |
|
61 |
|
62 template <typename Map> |
|
63 struct ComposeLess { |
|
64 ComposeLess(const Map& _map) : map(_map), less() {} |
|
65 |
|
66 bool operator()(const typename Map::Key& p, |
|
67 const typename Map::Key& q) const { |
|
68 return less(map[p], map[q]); |
|
69 } |
|
70 const Map& map; |
|
71 Less<typename Map::Value> less; |
|
72 }; |
|
73 |
50 template <typename Item> |
74 template <typename Item> |
51 class ItemLabelWriter { |
75 class ItemLabelWriter { |
52 public: |
76 public: |
53 |
77 |
54 bool isLabelWriter() { return true; } |
78 bool isLabelWriter() { return true; } |
173 typedef _Item Item; |
197 typedef _Item Item; |
174 |
198 |
175 virtual ~MapWriterBase() {} |
199 virtual ~MapWriterBase() {} |
176 |
200 |
177 virtual void write(std::ostream& os, const Item& item) const = 0; |
201 virtual void write(std::ostream& os, const Item& item) const = 0; |
|
202 virtual void sortByMap(std::vector<Item>&) const = 0; |
178 }; |
203 }; |
179 |
204 |
180 |
205 |
181 template <typename _Item, typename _Map, typename _Writer> |
206 template <typename _Item, typename _Map, typename _Writer> |
182 class MapWriter : public MapWriterBase<_Item> { |
207 class MapWriter : public MapWriterBase<_Item> { |
195 virtual ~MapWriter() {} |
220 virtual ~MapWriter() {} |
196 |
221 |
197 virtual void write(std::ostream& os, const Item& item) const { |
222 virtual void write(std::ostream& os, const Item& item) const { |
198 Value value = map[item]; |
223 Value value = map[item]; |
199 writer.write(os, value); |
224 writer.write(os, value); |
|
225 } |
|
226 |
|
227 virtual void sortByMap(std::vector<Item>& items) const { |
|
228 ComposeLess<Map> less(map); |
|
229 std::sort(items.begin(), items.end(), less); |
200 } |
230 } |
201 |
231 |
202 }; |
232 }; |
203 |
233 |
204 |
234 |
392 /// |
422 /// |
393 /// If the nodeset contains an \c "label" named map then it will be regarded |
423 /// If the nodeset contains an \c "label" named map then it will be regarded |
394 /// as label map. This map should contain only unique values and when the |
424 /// as label map. This map should contain only unique values and when the |
395 /// \c writeLabel() member will be called with a node it will write it's |
425 /// \c writeLabel() member will be called with a node it will write it's |
396 /// label. Otherwise if the \c _forceLabelMap constructor parameter is true |
426 /// label. Otherwise if the \c _forceLabelMap constructor parameter is true |
397 /// then the label map will be the id in the graph. |
427 /// then the label map will be the id in the graph. In addition if the |
|
428 /// the \c _sortByLabel is true then the writer will write the edges |
|
429 /// sorted by the labels. |
398 /// |
430 /// |
399 /// \relates LemonWriter |
431 /// \relates LemonWriter |
400 template <typename _Graph, typename _Traits = DefaultWriterTraits> |
432 template <typename _Graph, typename _Traits = DefaultWriterTraits> |
401 class NodeSetWriter : public LemonWriter::SectionWriter { |
433 class NodeSetWriter : public LemonWriter::SectionWriter { |
402 typedef LemonWriter::SectionWriter Parent; |
434 typedef LemonWriter::SectionWriter Parent; |
409 /// \brief Constructor. |
441 /// \brief Constructor. |
410 /// |
442 /// |
411 /// Constructor for NodeSetWriter. It creates the NodeSetWriter and |
443 /// Constructor for NodeSetWriter. It creates the NodeSetWriter and |
412 /// attach it into the given LemonWriter. If the \c _forceLabelMap |
444 /// attach it into the given LemonWriter. If the \c _forceLabelMap |
413 /// parameter is true then the writer will write own label map when |
445 /// parameter is true then the writer will write own label map when |
414 /// the user does not give "label" named map. |
446 /// the user does not give "label" named map. In addition if the |
|
447 /// the \c _sortByLabel is true then the writer will write the edges |
|
448 /// sorted by the labels. |
415 NodeSetWriter(LemonWriter& _writer, const Graph& _graph, |
449 NodeSetWriter(LemonWriter& _writer, const Graph& _graph, |
416 const std::string& _name = std::string(), |
450 const std::string& _name = std::string(), |
417 bool _forceLabelMap = true) |
451 bool _forceLabelMap = true, bool _sortByLabel = true) |
418 : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap), |
452 : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap), |
419 graph(_graph), name(_name) {} |
453 sortByLabel(_sortByLabel), graph(_graph), name(_name) {} |
420 |
454 |
421 /// \brief Destructor. |
455 /// \brief Destructor. |
422 /// |
456 /// |
423 /// Destructor for NodeSetWriter. |
457 /// Destructor for NodeSetWriter. |
424 virtual ~NodeSetWriter() { |
458 virtual ~NodeSetWriter() { |
475 labelMap = writers[i].second; |
509 labelMap = writers[i].second; |
476 forceLabelMap = false; |
510 forceLabelMap = false; |
477 break; |
511 break; |
478 } |
512 } |
479 } |
513 } |
|
514 std::vector<Node> items; |
|
515 for (typename Graph::NodeIt it(graph); it != INVALID; ++it) { |
|
516 items.push_back(it); |
|
517 } |
|
518 if (sortByLabel) { |
|
519 if (labelMap) { |
|
520 labelMap->sortByMap(items); |
|
521 } else { |
|
522 typedef IdMap<Graph, Node> Map; |
|
523 Map map(graph); |
|
524 _writer_bits::ComposeLess<Map> less(map); |
|
525 std::sort(items.begin(), items.end(), less); |
|
526 } |
|
527 } |
480 if (forceLabelMap) { |
528 if (forceLabelMap) { |
481 os << "label\t"; |
529 os << "label\t"; |
482 } |
530 } |
483 for (int i = 0; i < (int)writers.size(); ++i) { |
531 for (int i = 0; i < (int)writers.size(); ++i) { |
484 os << writers[i].first << '\t'; |
532 os << writers[i].first << '\t'; |
485 } |
533 } |
486 os << std::endl; |
534 os << std::endl; |
487 for (typename Graph::NodeIt it(graph); it != INVALID; ++it) { |
535 for (typename std::vector<Node>::iterator it = items.begin(); |
|
536 it != items.end(); ++it) { |
488 if (forceLabelMap) { |
537 if (forceLabelMap) { |
489 os << graph.id(it) << '\t'; |
538 os << graph.id(*it) << '\t'; |
490 } |
539 } |
491 for (int i = 0; i < (int)writers.size(); ++i) { |
540 for (int i = 0; i < (int)writers.size(); ++i) { |
492 writers[i].second->write(os, it); |
541 writers[i].second->write(os, *it); |
493 os << '\t'; |
542 os << '\t'; |
494 } |
543 } |
495 os << std::endl; |
544 os << std::endl; |
496 } |
545 } |
497 } |
546 } |
549 /// |
599 /// |
550 /// If the edgeset contains an \c "label" named map then it will be regarded |
600 /// If the edgeset contains an \c "label" named map then it will be regarded |
551 /// as label map. This map should contain only unique values and when the |
601 /// as label map. This map should contain only unique values and when the |
552 /// \c writeLabel() member will be called with an edge it will write it's |
602 /// \c writeLabel() member will be called with an edge it will write it's |
553 /// label. Otherwise if the \c _forceLabelMap constructor parameter is true |
603 /// label. Otherwise if the \c _forceLabelMap constructor parameter is true |
554 /// then the label map will be the id in the graph. |
604 /// then the label map will be the id in the graph. In addition if the |
|
605 /// the \c _sortByLabel is true then the writer will write the edges |
|
606 /// sorted by the labels. |
555 /// |
607 /// |
556 /// The edgeset writer needs a node label writer to identify which nodes |
608 /// The edgeset writer needs a node label writer to identify which nodes |
557 /// have to be connected. If a NodeSetWriter can write the nodes' label, |
609 /// have to be connected. If a NodeSetWriter can write the nodes' label, |
558 /// it will be able to use with this class. |
610 /// it will be able to use with this class. |
559 /// |
611 /// |
568 typedef typename Graph::Node Node; |
620 typedef typename Graph::Node Node; |
569 typedef typename Graph::Edge Edge; |
621 typedef typename Graph::Edge Edge; |
570 |
622 |
571 /// \brief Constructor. |
623 /// \brief Constructor. |
572 /// |
624 /// |
573 /// Constructor for EdgeSetWriter. It creates the EdgeSetWriter and |
625 /// Constructor for EdgeSetWriter. It creates the EdgeSetWriter |
574 /// attach it into the given LemonWriter. It will write node labels by |
626 /// and attach it into the given LemonWriter. It will write node |
575 /// the \c _nodeLabelWriter. If the \c _forceLabelMap parameter is true |
627 /// labels by the \c _nodeLabelWriter. If the \c _forceLabelMap |
576 /// then the writer will write own label map if the user does not give |
628 /// parameter is true then the writer will write own label map if |
577 /// "label" named map. |
629 /// the user does not give "label" named map. In addition if the |
|
630 /// the \c _sortByLabel is true then the writer will write the |
|
631 /// edges sorted by the labels. |
578 template <typename NodeLabelWriter> |
632 template <typename NodeLabelWriter> |
579 EdgeSetWriter(LemonWriter& _writer, const Graph& _graph, |
633 EdgeSetWriter(LemonWriter& _writer, const Graph& _graph, |
580 const NodeLabelWriter& _nodeLabelWriter, |
634 const NodeLabelWriter& _nodeLabelWriter, |
581 const std::string& _name = std::string(), |
635 const std::string& _name = std::string(), |
582 bool _forceLabelMap = true) |
636 bool _forceLabelMap = true, bool _sortByLabel = true) |
583 : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap), |
637 : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap), |
584 graph(_graph), name(_name) { |
638 sortByLabel(_sortByLabel), graph(_graph), name(_name) { |
585 checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>(); |
639 checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>(); |
586 nodeLabelWriter.reset(new _writer_bits:: |
640 nodeLabelWriter.reset(new _writer_bits:: |
587 LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter)); |
641 LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter)); |
588 } |
642 } |
589 |
643 |
647 labelMap = writers[i].second; |
701 labelMap = writers[i].second; |
648 forceLabelMap = false; |
702 forceLabelMap = false; |
649 break; |
703 break; |
650 } |
704 } |
651 } |
705 } |
|
706 std::vector<Edge> items; |
|
707 for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) { |
|
708 items.push_back(it); |
|
709 } |
|
710 if (sortByLabel) { |
|
711 if (labelMap) { |
|
712 labelMap->sortByMap(items); |
|
713 } else { |
|
714 typedef IdMap<Graph, Edge> Map; |
|
715 Map map(graph); |
|
716 _writer_bits::ComposeLess<Map> less(map); |
|
717 std::sort(items.begin(), items.end(), less); |
|
718 } |
|
719 } |
652 os << "\t\t"; |
720 os << "\t\t"; |
653 if (forceLabelMap) { |
721 if (forceLabelMap) { |
654 os << "label\t"; |
722 os << "label\t"; |
655 } |
723 } |
656 for (int i = 0; i < (int)writers.size(); ++i) { |
724 for (int i = 0; i < (int)writers.size(); ++i) { |
657 os << writers[i].first << '\t'; |
725 os << writers[i].first << '\t'; |
658 } |
726 } |
659 os << std::endl; |
727 os << std::endl; |
660 for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) { |
728 for (typename std::vector<Edge>::iterator it = items.begin(); |
661 nodeLabelWriter->write(os, graph.source(it)); |
729 it != items.end(); ++it) { |
|
730 nodeLabelWriter->write(os, graph.source(*it)); |
662 os << '\t'; |
731 os << '\t'; |
663 nodeLabelWriter->write(os, graph.target(it)); |
732 nodeLabelWriter->write(os, graph.target(*it)); |
664 os << '\t'; |
733 os << '\t'; |
665 if (forceLabelMap) { |
734 if (forceLabelMap) { |
666 os << graph.id(it) << '\t'; |
735 os << graph.id(*it) << '\t'; |
667 } |
736 } |
668 for (int i = 0; i < (int)writers.size(); ++i) { |
737 for (int i = 0; i < (int)writers.size(); ++i) { |
669 writers[i].second->write(os, it); |
738 writers[i].second->write(os, *it); |
670 os << '\t'; |
739 os << '\t'; |
671 } |
740 } |
672 os << std::endl; |
741 os << std::endl; |
673 } |
742 } |
674 } |
743 } |
729 /// undirected edge map describes one directed edge map. This two maps |
799 /// undirected edge map describes one directed edge map. This two maps |
730 /// are the forward map and the backward map and the names of this map |
800 /// are the forward map and the backward map and the names of this map |
731 /// is near the same just with a prefix \c '+' or \c '-' character |
801 /// is near the same just with a prefix \c '+' or \c '-' character |
732 /// difference. |
802 /// difference. |
733 /// |
803 /// |
734 /// If the edgeset contains an \c "label" named map then it will be regarded |
804 /// If the edgeset contains an \c "label" named map then it will be |
735 /// as label map. This map should contain only unique values and when the |
805 /// regarded as label map. This map should contain only unique |
736 /// \c writeLabel() member will be called with an undirected edge it will |
806 /// values and when the \c writeLabel() member will be called with |
737 /// write it's label. Otherwise if the \c _forceLabelMap constructor |
807 /// an undirected edge it will write it's label. Otherwise if the \c |
738 /// parameter is true then the label map will be the id in the graph. |
808 /// _forceLabelMap constructor parameter is true then the label map |
|
809 /// will be the id in the graph. In addition if the the \c |
|
810 /// _sortByLabel is true then the writer will write the edges sorted |
|
811 /// by the labels. |
739 /// |
812 /// |
740 /// The undirected edgeset writer needs a node label writer to identify |
813 /// The undirected edgeset writer needs a node label writer to identify |
741 /// which nodes have to be connected. If a NodeSetWriter can write the |
814 /// which nodes have to be connected. If a NodeSetWriter can write the |
742 /// nodes' label, it will be able to use with this class. |
815 /// nodes' label, it will be able to use with this class. |
743 /// |
816 /// |
754 typedef typename Graph::UEdge UEdge; |
827 typedef typename Graph::UEdge UEdge; |
755 |
828 |
756 /// \brief Constructor. |
829 /// \brief Constructor. |
757 /// |
830 /// |
758 /// Constructor for UEdgeSetWriter. It creates the UEdgeSetWriter |
831 /// Constructor for UEdgeSetWriter. It creates the UEdgeSetWriter |
759 /// and attach it into the given LemonWriter. It will write node labels by |
832 /// and attach it into the given LemonWriter. It will write node |
760 /// the \c _nodeLabelWriter. If the \c _forceLabelMap parameter is true |
833 /// labels by the \c _nodeLabelWriter. If the \c _forceLabelMap |
761 /// then the writer will write own label map if the user does not give |
834 /// parameter is true then the writer will write own label map if |
762 /// "label" named map. |
835 /// the user does not give "label" named map. In addition if the |
|
836 /// the \c _sortByLabel is true then the writer will write the |
|
837 /// edges sorted by the labels. |
763 template <typename NodeLabelWriter> |
838 template <typename NodeLabelWriter> |
764 UEdgeSetWriter(LemonWriter& _writer, const Graph& _graph, |
839 UEdgeSetWriter(LemonWriter& _writer, const Graph& _graph, |
765 const NodeLabelWriter& _nodeLabelWriter, |
840 const NodeLabelWriter& _nodeLabelWriter, |
766 const std::string& _name = std::string(), |
841 const std::string& _name = std::string(), |
767 bool _forceLabelMap = true) |
842 bool _forceLabelMap = true, bool _sortByLabel = true) |
768 : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap), |
843 : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap), |
769 graph(_graph), name(_name) { |
844 sortByLabel(_sortByLabel), graph(_graph), name(_name) { |
770 checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>(); |
845 checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>(); |
771 nodeLabelWriter.reset(new _writer_bits:: |
846 nodeLabelWriter.reset(new _writer_bits:: |
772 LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter)); |
847 LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter)); |
773 } |
848 } |
774 |
849 |
856 labelMap = writers[i].second; |
931 labelMap = writers[i].second; |
857 forceLabelMap = false; |
932 forceLabelMap = false; |
858 break; |
933 break; |
859 } |
934 } |
860 } |
935 } |
|
936 std::vector<UEdge> items; |
|
937 for (typename Graph::UEdgeIt it(graph); it != INVALID; ++it) { |
|
938 items.push_back(it); |
|
939 } |
|
940 if (sortByLabel) { |
|
941 if (labelMap) { |
|
942 labelMap->sortByMap(items); |
|
943 } else { |
|
944 typedef IdMap<Graph, UEdge> Map; |
|
945 Map map(graph); |
|
946 _writer_bits::ComposeLess<Map> less(map); |
|
947 std::sort(items.begin(), items.end(), less); |
|
948 } |
|
949 } |
861 os << "\t\t"; |
950 os << "\t\t"; |
862 if (forceLabelMap) { |
951 if (forceLabelMap) { |
863 os << "label\t"; |
952 os << "label\t"; |
864 } |
953 } |
865 for (int i = 0; i < (int)writers.size(); ++i) { |
954 for (int i = 0; i < (int)writers.size(); ++i) { |
866 os << writers[i].first << '\t'; |
955 os << writers[i].first << '\t'; |
867 } |
956 } |
868 os << std::endl; |
957 os << std::endl; |
869 for (typename Graph::UEdgeIt it(graph); it != INVALID; ++it) { |
958 for (typename std::vector<Edge>::iterator it = items.begin(); |
870 nodeLabelWriter->write(os, graph.source(it)); |
959 it != items.end(); ++it) { |
|
960 nodeLabelWriter->write(os, graph.source(*it)); |
871 os << '\t'; |
961 os << '\t'; |
872 nodeLabelWriter->write(os, graph.target(it)); |
962 nodeLabelWriter->write(os, graph.target(*it)); |
873 os << '\t'; |
963 os << '\t'; |
874 if (forceLabelMap) { |
964 if (forceLabelMap) { |
875 os << graph.id(it) << '\t'; |
965 os << graph.id(*it) << '\t'; |
876 } |
966 } |
877 for (int i = 0; i < (int)writers.size(); ++i) { |
967 for (int i = 0; i < (int)writers.size(); ++i) { |
878 writers[i].second->write(os, it); |
968 writers[i].second->write(os, *it); |
879 os << '\t'; |
969 os << '\t'; |
880 } |
970 } |
881 os << std::endl; |
971 os << std::endl; |
882 } |
972 } |
883 } |
973 } |