183 Converter _converter; |
183 Converter _converter; |
184 |
184 |
185 public: |
185 public: |
186 ValueStorage(const Value& value, const Converter& converter = Converter()) |
186 ValueStorage(const Value& value, const Converter& converter = Converter()) |
187 : _value(value), _converter(converter) {} |
187 : _value(value), _converter(converter) {} |
188 |
188 |
189 virtual std::string get() { |
189 virtual std::string get() { |
190 return _converter(_value); |
190 return _converter(_value); |
191 } |
191 } |
192 }; |
192 }; |
193 |
193 |
194 template <typename Value> |
194 template <typename Value, |
|
195 typename Map = std::map<Value, std::string> > |
195 struct MapLookUpConverter { |
196 struct MapLookUpConverter { |
196 const std::map<Value, std::string>& _map; |
197 const Map& _map; |
197 |
198 |
198 MapLookUpConverter(const std::map<Value, std::string>& map) |
199 MapLookUpConverter(const Map& map) |
199 : _map(map) {} |
200 : _map(map) {} |
200 |
201 |
201 std::string operator()(const Value& str) { |
202 std::string operator()(const Value& value) { |
202 typename std::map<Value, std::string>::const_iterator it = |
203 typename Map::const_iterator it = _map.find(value); |
203 _map.find(str); |
|
204 if (it == _map.end()) { |
204 if (it == _map.end()) { |
205 throw FormatError("Item not found"); |
205 throw FormatError("Item not found"); |
206 } |
206 } |
207 return it->second; |
207 return it->second; |
|
208 } |
|
209 }; |
|
210 |
|
211 template <typename Value, |
|
212 typename Map1 = std::map<Value, std::string>, |
|
213 typename Map2 = std::map<Value, std::string> > |
|
214 struct DoubleMapLookUpConverter { |
|
215 const Map1& _map1; |
|
216 const Map2& _map2; |
|
217 |
|
218 DoubleMapLookUpConverter(const Map1& map1, const Map2& map2) |
|
219 : _map1(map1), _map2(map2) {} |
|
220 |
|
221 std::string operator()(const Value& value) { |
|
222 typename Map1::const_iterator it1 = _map1.find(value); |
|
223 typename Map1::const_iterator it2 = _map2.find(value); |
|
224 if (it1 == _map1.end()) { |
|
225 if (it2 == _map2.end()) { |
|
226 throw FormatError("Item not found"); |
|
227 } else { |
|
228 return it2->second; |
|
229 } |
|
230 } else { |
|
231 if (it2 == _map2.end()) { |
|
232 return it1->second; |
|
233 } else { |
|
234 throw FormatError("Item is ambigous"); |
|
235 } |
|
236 } |
208 } |
237 } |
209 }; |
238 }; |
210 |
239 |
211 template <typename Graph> |
240 template <typename Graph> |
212 struct GraphArcLookUpConverter { |
241 struct GraphArcLookUpConverter { |
1649 |
1678 |
1650 std::string _nodes_caption; |
1679 std::string _nodes_caption; |
1651 std::string _edges_caption; |
1680 std::string _edges_caption; |
1652 std::string _attributes_caption; |
1681 std::string _attributes_caption; |
1653 |
1682 |
1654 typedef std::map<Node, std::string> NodeIndex; |
1683 typedef std::map<Node, std::string> RedNodeIndex; |
1655 NodeIndex _node_index; |
1684 RedNodeIndex _red_node_index; |
|
1685 typedef std::map<Node, std::string> BlueNodeIndex; |
|
1686 BlueNodeIndex _blue_node_index; |
1656 typedef std::map<Edge, std::string> EdgeIndex; |
1687 typedef std::map<Edge, std::string> EdgeIndex; |
1657 EdgeIndex _edge_index; |
1688 EdgeIndex _edge_index; |
1658 |
1689 |
1659 typedef std::vector<std::pair<std::string, |
1690 typedef std::vector<std::pair<std::string, |
1660 _writer_bits::MapStorageBase<Node>* > > NodeMaps; |
1691 _writer_bits::MapStorageBase<RedNode>* > > RedNodeMaps; |
1661 NodeMaps _red_maps; |
1692 RedNodeMaps _red_node_maps; |
1662 NodeMaps _blue_maps; |
1693 typedef std::vector<std::pair<std::string, |
|
1694 _writer_bits::MapStorageBase<BlueNode>* > > BlueNodeMaps; |
|
1695 BlueNodeMaps _blue_node_maps; |
1663 |
1696 |
1664 typedef std::vector<std::pair<std::string, |
1697 typedef std::vector<std::pair<std::string, |
1665 _writer_bits::MapStorageBase<Edge>* > >EdgeMaps; |
1698 _writer_bits::MapStorageBase<Edge>* > >EdgeMaps; |
1666 EdgeMaps _edge_maps; |
1699 EdgeMaps _edge_maps; |
1667 |
1700 |
1777 /// |
1811 /// |
1778 /// Add a node map writing rule to the writer. |
1812 /// Add a node map writing rule to the writer. |
1779 template <typename Map> |
1813 template <typename Map> |
1780 BpGraphWriter& nodeMap(const std::string& caption, const Map& map) { |
1814 BpGraphWriter& nodeMap(const std::string& caption, const Map& map) { |
1781 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); |
1815 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); |
1782 _writer_bits::MapStorageBase<Node>* red_storage = |
1816 _writer_bits::MapStorageBase<RedNode>* red_storage = |
1783 new _writer_bits::MapStorage<Node, Map>(map); |
1817 new _writer_bits::MapStorage<RedNode, Map>(map); |
1784 _red_maps.push_back(std::make_pair(caption, red_storage)); |
1818 _red_node_maps.push_back(std::make_pair(caption, red_storage)); |
1785 _writer_bits::MapStorageBase<Node>* blue_storage = |
1819 _writer_bits::MapStorageBase<BlueNode>* blue_storage = |
1786 new _writer_bits::MapStorage<Node, Map>(map); |
1820 new _writer_bits::MapStorage<BlueNode, Map>(map); |
1787 _blue_maps.push_back(std::make_pair(caption, blue_storage)); |
1821 _blue_node_maps.push_back(std::make_pair(caption, blue_storage)); |
1788 return *this; |
1822 return *this; |
1789 } |
1823 } |
1790 |
1824 |
1791 /// \brief Node map writing rule |
1825 /// \brief Node map writing rule |
1792 /// |
1826 /// |
1794 /// writer. |
1828 /// writer. |
1795 template <typename Map, typename Converter> |
1829 template <typename Map, typename Converter> |
1796 BpGraphWriter& nodeMap(const std::string& caption, const Map& map, |
1830 BpGraphWriter& nodeMap(const std::string& caption, const Map& map, |
1797 const Converter& converter = Converter()) { |
1831 const Converter& converter = Converter()) { |
1798 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); |
1832 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); |
1799 _writer_bits::MapStorageBase<Node>* red_storage = |
1833 _writer_bits::MapStorageBase<RedNode>* red_storage = |
1800 new _writer_bits::MapStorage<Node, Map, Converter>(map, converter); |
1834 new _writer_bits::MapStorage<RedNode, Map, Converter>(map, converter); |
1801 _red_maps.push_back(std::make_pair(caption, red_storage)); |
1835 _red_node_maps.push_back(std::make_pair(caption, red_storage)); |
1802 _writer_bits::MapStorageBase<Node>* blue_storage = |
1836 _writer_bits::MapStorageBase<BlueNode>* blue_storage = |
1803 new _writer_bits::MapStorage<Node, Map, Converter>(map, converter); |
1837 new _writer_bits::MapStorage<BlueNode, Map, Converter>(map, converter); |
1804 _blue_maps.push_back(std::make_pair(caption, blue_storage)); |
1838 _blue_node_maps.push_back(std::make_pair(caption, blue_storage)); |
1805 return *this; |
1839 return *this; |
1806 } |
1840 } |
1807 |
1841 |
1808 /// \brief Red node map writing rule |
1842 /// \brief Red node map writing rule |
1809 /// |
1843 /// |
1810 /// Add a red node map writing rule to the writer. |
1844 /// Add a red node map writing rule to the writer. |
1811 template <typename Map> |
1845 template <typename Map> |
1812 BpGraphWriter& redNodeMap(const std::string& caption, const Map& map) { |
1846 BpGraphWriter& redNodeMap(const std::string& caption, const Map& map) { |
1813 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); |
1847 checkConcept<concepts::ReadMap<RedNode, typename Map::Value>, Map>(); |
1814 _writer_bits::MapStorageBase<Node>* storage = |
1848 _writer_bits::MapStorageBase<RedNode>* storage = |
1815 new _writer_bits::MapStorage<Node, Map>(map); |
1849 new _writer_bits::MapStorage<RedNode, Map>(map); |
1816 _red_maps.push_back(std::make_pair(caption, storage)); |
1850 _red_node_maps.push_back(std::make_pair(caption, storage)); |
1817 return *this; |
1851 return *this; |
1818 } |
1852 } |
1819 |
1853 |
1820 /// \brief Red node map writing rule |
1854 /// \brief Red node map writing rule |
1821 /// |
1855 /// |
1822 /// Add a red node map writing rule with specialized converter to the |
1856 /// Add a red node map writing rule with specialized converter to the |
1823 /// writer. |
1857 /// writer. |
1824 template <typename Map, typename Converter> |
1858 template <typename Map, typename Converter> |
1825 BpGraphWriter& redNodeMap(const std::string& caption, const Map& map, |
1859 BpGraphWriter& redNodeMap(const std::string& caption, const Map& map, |
1826 const Converter& converter = Converter()) { |
1860 const Converter& converter = Converter()) { |
1827 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); |
1861 checkConcept<concepts::ReadMap<RedNode, typename Map::Value>, Map>(); |
1828 _writer_bits::MapStorageBase<Node>* storage = |
1862 _writer_bits::MapStorageBase<RedNode>* storage = |
1829 new _writer_bits::MapStorage<Node, Map, Converter>(map, converter); |
1863 new _writer_bits::MapStorage<RedNode, Map, Converter>(map, converter); |
1830 _red_maps.push_back(std::make_pair(caption, storage)); |
1864 _red_node_maps.push_back(std::make_pair(caption, storage)); |
1831 return *this; |
1865 return *this; |
1832 } |
1866 } |
1833 |
1867 |
1834 /// \brief Blue node map writing rule |
1868 /// \brief Blue node map writing rule |
1835 /// |
1869 /// |
1836 /// Add a blue node map writing rule to the writer. |
1870 /// Add a blue node map writing rule to the writer. |
1837 template <typename Map> |
1871 template <typename Map> |
1838 BpGraphWriter& blueNodeMap(const std::string& caption, const Map& map) { |
1872 BpGraphWriter& blueNodeMap(const std::string& caption, const Map& map) { |
1839 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); |
1873 checkConcept<concepts::ReadMap<BlueNode, typename Map::Value>, Map>(); |
1840 _writer_bits::MapStorageBase<Node>* storage = |
1874 _writer_bits::MapStorageBase<BlueNode>* storage = |
1841 new _writer_bits::MapStorage<Node, Map>(map); |
1875 new _writer_bits::MapStorage<BlueNode, Map>(map); |
1842 _blue_maps.push_back(std::make_pair(caption, storage)); |
1876 _blue_node_maps.push_back(std::make_pair(caption, storage)); |
1843 return *this; |
1877 return *this; |
1844 } |
1878 } |
1845 |
1879 |
1846 /// \brief Blue node map writing rule |
1880 /// \brief Blue node map writing rule |
1847 /// |
1881 /// |
1848 /// Add a blue node map writing rule with specialized converter to the |
1882 /// Add a blue node map writing rule with specialized converter to the |
1849 /// writer. |
1883 /// writer. |
1850 template <typename Map, typename Converter> |
1884 template <typename Map, typename Converter> |
1851 BpGraphWriter& blueNodeMap(const std::string& caption, const Map& map, |
1885 BpGraphWriter& blueNodeMap(const std::string& caption, const Map& map, |
1852 const Converter& converter = Converter()) { |
1886 const Converter& converter = Converter()) { |
1853 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); |
1887 checkConcept<concepts::ReadMap<BlueNode, typename Map::Value>, Map>(); |
1854 _writer_bits::MapStorageBase<Node>* storage = |
1888 _writer_bits::MapStorageBase<BlueNode>* storage = |
1855 new _writer_bits::MapStorage<Node, Map, Converter>(map, converter); |
1889 new _writer_bits::MapStorage<BlueNode, Map, Converter>(map, converter); |
1856 _blue_maps.push_back(std::make_pair(caption, storage)); |
1890 _blue_node_maps.push_back(std::make_pair(caption, storage)); |
1857 return *this; |
1891 return *this; |
1858 } |
1892 } |
1859 |
1893 |
1860 /// \brief Edge map writing rule |
1894 /// \brief Edge map writing rule |
1861 /// |
1895 /// |
1943 |
1977 |
1944 /// \brief Node writing rule |
1978 /// \brief Node writing rule |
1945 /// |
1979 /// |
1946 /// Add a node writing rule to the writer. |
1980 /// Add a node writing rule to the writer. |
1947 BpGraphWriter& node(const std::string& caption, const Node& node) { |
1981 BpGraphWriter& node(const std::string& caption, const Node& node) { |
|
1982 typedef _writer_bits::DoubleMapLookUpConverter< |
|
1983 Node, RedNodeIndex, BlueNodeIndex> Converter; |
|
1984 Converter converter(_red_node_index, _blue_node_index); |
|
1985 _writer_bits::ValueStorageBase* storage = |
|
1986 new _writer_bits::ValueStorage<Node, Converter>(node, converter); |
|
1987 _attributes.push_back(std::make_pair(caption, storage)); |
|
1988 return *this; |
|
1989 } |
|
1990 |
|
1991 /// \brief Red node writing rule |
|
1992 /// |
|
1993 /// Add a red node writing rule to the writer. |
|
1994 BpGraphWriter& redNode(const std::string& caption, const RedNode& node) { |
1948 typedef _writer_bits::MapLookUpConverter<Node> Converter; |
1995 typedef _writer_bits::MapLookUpConverter<Node> Converter; |
1949 Converter converter(_node_index); |
1996 Converter converter(_red_node_index); |
|
1997 _writer_bits::ValueStorageBase* storage = |
|
1998 new _writer_bits::ValueStorage<Node, Converter>(node, converter); |
|
1999 _attributes.push_back(std::make_pair(caption, storage)); |
|
2000 return *this; |
|
2001 } |
|
2002 |
|
2003 /// \brief Blue node writing rule |
|
2004 /// |
|
2005 /// Add a blue node writing rule to the writer. |
|
2006 BpGraphWriter& blueNode(const std::string& caption, const BlueNode& node) { |
|
2007 typedef _writer_bits::MapLookUpConverter<Node> Converter; |
|
2008 Converter converter(_blue_node_index); |
1950 _writer_bits::ValueStorageBase* storage = |
2009 _writer_bits::ValueStorageBase* storage = |
1951 new _writer_bits::ValueStorage<Node, Converter>(node, converter); |
2010 new _writer_bits::ValueStorage<Node, Converter>(node, converter); |
1952 _attributes.push_back(std::make_pair(caption, storage)); |
2011 _attributes.push_back(std::make_pair(caption, storage)); |
1953 return *this; |
2012 return *this; |
1954 } |
2013 } |
2069 } else { |
2128 } else { |
2070 label->sort(nodes); |
2129 label->sort(nodes); |
2071 } |
2130 } |
2072 |
2131 |
2073 for (int i = 0; i < static_cast<int>(nodes.size()); ++i) { |
2132 for (int i = 0; i < static_cast<int>(nodes.size()); ++i) { |
2074 Node n = nodes[i]; |
2133 RedNode n = nodes[i]; |
2075 if (label == 0) { |
2134 if (label == 0) { |
2076 std::ostringstream os; |
2135 std::ostringstream os; |
2077 os << _graph.id(n); |
2136 os << _graph.id(static_cast<Node>(n)); |
2078 _writer_bits::writeToken(*_os, os.str()); |
2137 _writer_bits::writeToken(*_os, os.str()); |
2079 *_os << '\t'; |
2138 *_os << '\t'; |
2080 _node_index.insert(std::make_pair(n, os.str())); |
2139 _red_node_index.insert(std::make_pair(n, os.str())); |
2081 } |
2140 } |
2082 for (typename NodeMaps::iterator it = _red_maps.begin(); |
2141 for (typename RedNodeMaps::iterator it = _red_node_maps.begin(); |
2083 it != _red_maps.end(); ++it) { |
2142 it != _red_node_maps.end(); ++it) { |
2084 std::string value = it->second->get(n); |
2143 std::string value = it->second->get(n); |
2085 _writer_bits::writeToken(*_os, value); |
2144 _writer_bits::writeToken(*_os, value); |
2086 if (it->first == "label") { |
2145 if (it->first == "label") { |
2087 _node_index.insert(std::make_pair(n, value)); |
2146 _red_node_index.insert(std::make_pair(n, value)); |
2088 } |
2147 } |
2089 *_os << '\t'; |
2148 *_os << '\t'; |
2090 } |
2149 } |
2091 *_os << std::endl; |
2150 *_os << std::endl; |
2092 } |
2151 } |
2093 } |
2152 } |
2094 |
2153 |
2095 void writeBlueNodes() { |
2154 void writeBlueNodes() { |
2096 _writer_bits::MapStorageBase<Node>* label = 0; |
2155 _writer_bits::MapStorageBase<BlueNode>* label = 0; |
2097 for (typename NodeMaps::iterator it = _blue_maps.begin(); |
2156 for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin(); |
2098 it != _blue_maps.end(); ++it) { |
2157 it != _blue_node_maps.end(); ++it) { |
2099 if (it->first == "label") { |
2158 if (it->first == "label") { |
2100 label = it->second; |
2159 label = it->second; |
2101 break; |
2160 break; |
2102 } |
2161 } |
2103 } |
2162 } |
2129 } else { |
2188 } else { |
2130 label->sort(nodes); |
2189 label->sort(nodes); |
2131 } |
2190 } |
2132 |
2191 |
2133 for (int i = 0; i < static_cast<int>(nodes.size()); ++i) { |
2192 for (int i = 0; i < static_cast<int>(nodes.size()); ++i) { |
2134 Node n = nodes[i]; |
2193 BlueNode n = nodes[i]; |
2135 if (label == 0) { |
2194 if (label == 0) { |
2136 std::ostringstream os; |
2195 std::ostringstream os; |
2137 os << _graph.id(n); |
2196 os << _graph.id(static_cast<Node>(n)); |
2138 _writer_bits::writeToken(*_os, os.str()); |
2197 _writer_bits::writeToken(*_os, os.str()); |
2139 *_os << '\t'; |
2198 *_os << '\t'; |
2140 _node_index.insert(std::make_pair(n, os.str())); |
2199 _blue_node_index.insert(std::make_pair(n, os.str())); |
2141 } |
2200 } |
2142 for (typename NodeMaps::iterator it = _blue_maps.begin(); |
2201 for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin(); |
2143 it != _blue_maps.end(); ++it) { |
2202 it != _blue_node_maps.end(); ++it) { |
2144 std::string value = it->second->get(n); |
2203 std::string value = it->second->get(n); |
2145 _writer_bits::writeToken(*_os, value); |
2204 _writer_bits::writeToken(*_os, value); |
2146 if (it->first == "label") { |
2205 if (it->first == "label") { |
2147 _node_index.insert(std::make_pair(n, value)); |
2206 _blue_node_index.insert(std::make_pair(n, value)); |
2148 } |
2207 } |
2149 *_os << '\t'; |
2208 *_os << '\t'; |
2150 } |
2209 } |
2151 *_os << std::endl; |
2210 *_os << std::endl; |
2152 } |
2211 } |
2153 } |
2212 } |
2154 |
2213 |
2155 void createRedNodeIndex() { |
2214 void createRedNodeIndex() { |
2156 _writer_bits::MapStorageBase<Node>* label = 0; |
2215 _writer_bits::MapStorageBase<RedNode>* label = 0; |
2157 for (typename NodeMaps::iterator it = _red_maps.begin(); |
2216 for (typename RedNodeMaps::iterator it = _red_node_maps.begin(); |
2158 it != _red_maps.end(); ++it) { |
2217 it != _red_node_maps.end(); ++it) { |
2159 if (it->first == "label") { |
2218 if (it->first == "label") { |
2160 label = it->second; |
2219 label = it->second; |
2161 break; |
2220 break; |
2162 } |
2221 } |
2163 } |
2222 } |
2164 |
2223 |
2165 if (label == 0) { |
2224 if (label == 0) { |
2166 for (NodeIt n(_graph); n != INVALID; ++n) { |
2225 for (RedNodeIt n(_graph); n != INVALID; ++n) { |
2167 std::ostringstream os; |
2226 std::ostringstream os; |
2168 os << _graph.id(n); |
2227 os << _graph.id(n); |
2169 _node_index.insert(std::make_pair(n, os.str())); |
2228 _red_node_index.insert(std::make_pair(n, os.str())); |
2170 } |
2229 } |
2171 } else { |
2230 } else { |
2172 for (NodeIt n(_graph); n != INVALID; ++n) { |
2231 for (RedNodeIt n(_graph); n != INVALID; ++n) { |
2173 std::string value = label->get(n); |
2232 std::string value = label->get(n); |
2174 _node_index.insert(std::make_pair(n, value)); |
2233 _red_node_index.insert(std::make_pair(n, value)); |
2175 } |
2234 } |
2176 } |
2235 } |
2177 } |
2236 } |
2178 |
2237 |
2179 void createBlueNodeIndex() { |
2238 void createBlueNodeIndex() { |
2180 _writer_bits::MapStorageBase<Node>* label = 0; |
2239 _writer_bits::MapStorageBase<BlueNode>* label = 0; |
2181 for (typename NodeMaps::iterator it = _blue_maps.begin(); |
2240 for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin(); |
2182 it != _blue_maps.end(); ++it) { |
2241 it != _blue_node_maps.end(); ++it) { |
2183 if (it->first == "label") { |
2242 if (it->first == "label") { |
2184 label = it->second; |
2243 label = it->second; |
2185 break; |
2244 break; |
2186 } |
2245 } |
2187 } |
2246 } |
2188 |
2247 |
2189 if (label == 0) { |
2248 if (label == 0) { |
2190 for (NodeIt n(_graph); n != INVALID; ++n) { |
2249 for (BlueNodeIt n(_graph); n != INVALID; ++n) { |
2191 std::ostringstream os; |
2250 std::ostringstream os; |
2192 os << _graph.id(n); |
2251 os << _graph.id(n); |
2193 _node_index.insert(std::make_pair(n, os.str())); |
2252 _blue_node_index.insert(std::make_pair(n, os.str())); |
2194 } |
2253 } |
2195 } else { |
2254 } else { |
2196 for (NodeIt n(_graph); n != INVALID; ++n) { |
2255 for (BlueNodeIt n(_graph); n != INVALID; ++n) { |
2197 std::string value = label->get(n); |
2256 std::string value = label->get(n); |
2198 _node_index.insert(std::make_pair(n, value)); |
2257 _blue_node_index.insert(std::make_pair(n, value)); |
2199 } |
2258 } |
2200 } |
2259 } |
2201 } |
2260 } |
2202 |
2261 |
2203 void writeEdges() { |
2262 void writeEdges() { |