2049 private: |
2053 private: |
2050 std::string name; |
2054 std::string name; |
2051 |
2055 |
2052 typedef std::map<std::string, _reader_bits::ValueReaderBase*> Readers; |
2056 typedef std::map<std::string, _reader_bits::ValueReaderBase*> Readers; |
2053 Readers readers; |
2057 Readers readers; |
|
2058 }; |
|
2059 |
|
2060 /// \ingroup section_io |
|
2061 /// \brief SectionReader for reading extra node maps. |
|
2062 /// |
|
2063 /// The lemon format can store maps in the nodeset sections. This |
|
2064 /// class let you make distinict section to store maps. The main |
|
2065 /// purpose of this class is a logical separation of some maps. The |
|
2066 /// other useful application could be to store paths in node maps. |
|
2067 /// |
|
2068 /// The first line of the section contains the names of the maps |
|
2069 /// separated with white spaces. Each next line describes an item |
|
2070 /// in the itemset, and contains in the first column the label of |
|
2071 /// the item and then the mapped values for each map. |
|
2072 /// |
|
2073 /// \relates LemonReader |
|
2074 template <typename _Graph, typename _Traits = DefaultReaderTraits> |
|
2075 class NodeMapReader : public LemonReader::SectionReader { |
|
2076 typedef LemonReader::SectionReader Parent; |
|
2077 public: |
|
2078 |
|
2079 typedef _Graph Graph; |
|
2080 typedef typename Graph::Node Node; |
|
2081 typedef _Traits Traits; |
|
2082 typedef typename Traits::Skipper DefaultSkipper; |
|
2083 |
|
2084 /// \brief Constructor. |
|
2085 /// |
|
2086 /// Constructor for NodeMapReader. It creates the NodeMapReader and |
|
2087 /// attach it into the given LemonReader. The reader will read |
|
2088 /// the section when the \c section_name and the \c _name are the same. |
|
2089 template <typename _LabelReader> |
|
2090 NodeMapReader(LemonReader& _reader, |
|
2091 const Graph& _graph, |
|
2092 const _LabelReader& _labelReader, |
|
2093 const std::string& _name = std::string(), |
|
2094 const DefaultSkipper& _skipper = DefaultSkipper()) |
|
2095 : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) { |
|
2096 labelReader.reset(new _reader_bits:: |
|
2097 LabelReader<Node, _LabelReader>(_labelReader)); |
|
2098 } |
|
2099 |
|
2100 |
|
2101 /// \brief Destructor. |
|
2102 /// |
|
2103 /// Destructor for NodeMapReader. |
|
2104 virtual ~NodeMapReader() { |
|
2105 for (typename MapReaders::iterator it = readers.begin(); |
|
2106 it != readers.end(); ++it) { |
|
2107 delete it->second; |
|
2108 } |
|
2109 } |
|
2110 |
|
2111 private: |
|
2112 NodeMapReader(const NodeMapReader&); |
|
2113 void operator=(const NodeMapReader&); |
|
2114 |
|
2115 public: |
|
2116 |
|
2117 /// \brief Add a new node map reader command for the reader. |
|
2118 /// |
|
2119 /// Add a new node map reader command for the reader. |
|
2120 template <typename Map> |
|
2121 NodeMapReader& readNodeMap(std::string label, Map& map) { |
|
2122 return _readMap< |
|
2123 typename Traits::template Reader<typename Map::Value>, Map, |
|
2124 typename _reader_bits::Arg<Map>::Type>(label, map); |
|
2125 } |
|
2126 |
|
2127 template <typename Map> |
|
2128 NodeMapReader& readNodeMap(std::string label, const Map& map) { |
|
2129 return _readMap< |
|
2130 typename Traits::template Reader<typename Map::Value>, Map, |
|
2131 typename _reader_bits::Arg<Map>::Type>(label, map); |
|
2132 } |
|
2133 |
|
2134 /// \brief Add a new node map reader command for the reader. |
|
2135 /// |
|
2136 /// Add a new node map reader command for the reader. |
|
2137 template <typename ItemReader, typename Map> |
|
2138 NodeMapReader& readNodeMap(std::string label, Map& map, |
|
2139 const ItemReader& ir = ItemReader()) { |
|
2140 return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type> |
|
2141 (label, map, ir); |
|
2142 } |
|
2143 |
|
2144 template <typename ItemReader, typename Map> |
|
2145 NodeMapReader& readNodeMap(std::string label, const Map& map, |
|
2146 const ItemReader& ir = ItemReader()) { |
|
2147 return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type> |
|
2148 (label, map, ir); |
|
2149 } |
|
2150 |
|
2151 private: |
|
2152 |
|
2153 template <typename ItemReader, typename Map, typename MapParameter> |
|
2154 NodeMapReader& _readMap(std::string label, MapParameter map, |
|
2155 const ItemReader& ir = ItemReader()) { |
|
2156 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); |
|
2157 checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>(); |
|
2158 if (readers.find(label) != readers.end()) { |
|
2159 ErrorMessage msg; |
|
2160 msg << "Multiple read rule for map: " << label; |
|
2161 throw IoParameterError(msg.message()); |
|
2162 } |
|
2163 readers.insert( |
|
2164 make_pair(label, new _reader_bits:: |
|
2165 MapReader<Node, Map, ItemReader>(map, ir))); |
|
2166 return *this; |
|
2167 } |
|
2168 |
|
2169 public: |
|
2170 |
|
2171 /// \brief Add a new node map skipper command for the reader. |
|
2172 /// |
|
2173 /// Add a new node map skipper command for the reader. |
|
2174 template <typename ItemReader> |
|
2175 NodeMapReader& skipNodeMap(std::string label, |
|
2176 const ItemReader& ir = ItemReader()) { |
|
2177 if (readers.find(label) != readers.end()) { |
|
2178 ErrorMessage msg; |
|
2179 msg << "Multiple read rule for map: " << label; |
|
2180 throw IoParameterError(msg.message()); |
|
2181 } |
|
2182 readers.insert(make_pair(label, new _reader_bits:: |
|
2183 SkipReader<Node, ItemReader>(ir))); |
|
2184 return *this; |
|
2185 } |
|
2186 |
|
2187 protected: |
|
2188 |
|
2189 /// \brief Gives back true when the SectionReader can process |
|
2190 /// the section with the given header line. |
|
2191 /// |
|
2192 /// It gives back true when the header line starts with \c \@mapset, |
|
2193 /// and the header line's name and the mapset's name are the same. |
|
2194 virtual bool header(const std::string& line) { |
|
2195 std::istringstream ls(line); |
|
2196 std::string command; |
|
2197 std::string id; |
|
2198 ls >> command >> id; |
|
2199 return command == "@nodemaps" && name == id; |
|
2200 } |
|
2201 |
|
2202 /// \brief Reader function of the section. |
|
2203 /// |
|
2204 /// It reads the content of the section. |
|
2205 virtual void read(std::istream& is) { |
|
2206 std::vector<_reader_bits::MapReaderBase<Node>* > index; |
|
2207 std::string line; |
|
2208 |
|
2209 { |
|
2210 getline(is, line); |
|
2211 std::istringstream ls(line); |
|
2212 std::string id; |
|
2213 while (ls >> id) { |
|
2214 typename MapReaders::iterator it = readers.find(id); |
|
2215 if (it != readers.end()) { |
|
2216 it->second->touch(); |
|
2217 index.push_back(it->second); |
|
2218 } else { |
|
2219 index.push_back(&skipper); |
|
2220 } |
|
2221 } |
|
2222 } |
|
2223 for (typename MapReaders::iterator it = readers.begin(); |
|
2224 it != readers.end(); ++it) { |
|
2225 if (!it->second->touched()) { |
|
2226 ErrorMessage msg; |
|
2227 msg << "Map not found in file: " << it->first; |
|
2228 throw IoParameterError(msg.message()); |
|
2229 } |
|
2230 } |
|
2231 while (getline(is, line)) { |
|
2232 std::istringstream ls(line); |
|
2233 Node node = labelReader->read(ls); |
|
2234 for (int i = 0; i < int(index.size()); ++i) { |
|
2235 index[i]->read(ls, node); |
|
2236 } |
|
2237 } |
|
2238 } |
|
2239 |
|
2240 virtual void missing() { |
|
2241 if (readers.empty()) return; |
|
2242 ErrorMessage msg; |
|
2243 msg << "NodeMap section not found in file: @nodemaps " << name; |
|
2244 throw IoParameterError(msg.message()); |
|
2245 } |
|
2246 |
|
2247 private: |
|
2248 |
|
2249 typedef std::map<std::string, _reader_bits::MapReaderBase<Node>*> MapReaders; |
|
2250 MapReaders readers; |
|
2251 |
|
2252 const Graph& graph; |
|
2253 std::string name; |
|
2254 _reader_bits::SkipReader<Node, DefaultSkipper> skipper; |
|
2255 std::auto_ptr<_reader_bits::LabelReaderBase<Node> > labelReader; |
|
2256 |
|
2257 }; |
|
2258 |
|
2259 /// \ingroup section_io |
|
2260 /// \brief SectionReader for reading extra edge maps. |
|
2261 /// |
|
2262 /// The lemon format can store maps in the edgeset sections. This |
|
2263 /// class let you make distinict section to store maps. The main |
|
2264 /// purpose of this class is a logical separation of some maps. The |
|
2265 /// other useful application could be to store paths in edge maps. |
|
2266 /// |
|
2267 /// The first line of the section contains the names of the maps |
|
2268 /// separated with white spaces. Each next line describes an item |
|
2269 /// in the itemset, and contains in the first column the label of |
|
2270 /// the item and then the mapped values for each map. |
|
2271 /// |
|
2272 /// \relates LemonReader |
|
2273 template <typename _Graph, typename _Traits = DefaultReaderTraits> |
|
2274 class EdgeMapReader : public LemonReader::SectionReader { |
|
2275 typedef LemonReader::SectionReader Parent; |
|
2276 public: |
|
2277 |
|
2278 typedef _Graph Graph; |
|
2279 typedef typename Graph::Edge Edge; |
|
2280 typedef _Traits Traits; |
|
2281 typedef typename Traits::Skipper DefaultSkipper; |
|
2282 |
|
2283 /// \brief Constructor. |
|
2284 /// |
|
2285 /// Constructor for EdgeMapReader. It creates the EdgeMapReader and |
|
2286 /// attach it into the given LemonReader. The reader will read |
|
2287 /// the section when the \c section_name and the \c _name are the same. |
|
2288 template <typename _LabelReader> |
|
2289 EdgeMapReader(LemonReader& _reader, |
|
2290 const Graph& _graph, |
|
2291 const _LabelReader& _labelReader, |
|
2292 const std::string& _name = std::string(), |
|
2293 const DefaultSkipper& _skipper = DefaultSkipper()) |
|
2294 : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) { |
|
2295 labelReader.reset(new _reader_bits:: |
|
2296 LabelReader<Edge, _LabelReader>(_labelReader)); |
|
2297 } |
|
2298 |
|
2299 |
|
2300 /// \brief Destructor. |
|
2301 /// |
|
2302 /// Destructor for EdgeMapReader. |
|
2303 virtual ~EdgeMapReader() { |
|
2304 for (typename MapReaders::iterator it = readers.begin(); |
|
2305 it != readers.end(); ++it) { |
|
2306 delete it->second; |
|
2307 } |
|
2308 } |
|
2309 |
|
2310 private: |
|
2311 EdgeMapReader(const EdgeMapReader&); |
|
2312 void operator=(const EdgeMapReader&); |
|
2313 |
|
2314 public: |
|
2315 |
|
2316 /// \brief Add a new edge map reader command for the reader. |
|
2317 /// |
|
2318 /// Add a new edge map reader command for the reader. |
|
2319 template <typename Map> |
|
2320 EdgeMapReader& readEdgeMap(std::string label, Map& map) { |
|
2321 return _readMap< |
|
2322 typename Traits::template Reader<typename Map::Value>, Map, |
|
2323 typename _reader_bits::Arg<Map>::Type>(label, map); |
|
2324 } |
|
2325 |
|
2326 template <typename Map> |
|
2327 EdgeMapReader& readEdgeMap(std::string label, const Map& map) { |
|
2328 return _readMap< |
|
2329 typename Traits::template Reader<typename Map::Value>, Map, |
|
2330 typename _reader_bits::Arg<Map>::Type>(label, map); |
|
2331 } |
|
2332 |
|
2333 /// \brief Add a new edge map reader command for the reader. |
|
2334 /// |
|
2335 /// Add a new edge map reader command for the reader. |
|
2336 template <typename ItemReader, typename Map> |
|
2337 EdgeMapReader& readEdgeMap(std::string label, Map& map, |
|
2338 const ItemReader& ir = ItemReader()) { |
|
2339 return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type> |
|
2340 (label, map, ir); |
|
2341 } |
|
2342 |
|
2343 template <typename ItemReader, typename Map> |
|
2344 EdgeMapReader& readEdgeMap(std::string label, const Map& map, |
|
2345 const ItemReader& ir = ItemReader()) { |
|
2346 return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type> |
|
2347 (label, map, ir); |
|
2348 } |
|
2349 |
|
2350 private: |
|
2351 |
|
2352 template <typename ItemReader, typename Map, typename MapParameter> |
|
2353 EdgeMapReader& _readMap(std::string label, MapParameter map, |
|
2354 const ItemReader& ir = ItemReader()) { |
|
2355 checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>(); |
|
2356 checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>(); |
|
2357 if (readers.find(label) != readers.end()) { |
|
2358 ErrorMessage msg; |
|
2359 msg << "Multiple read rule for map: " << label; |
|
2360 throw IoParameterError(msg.message()); |
|
2361 } |
|
2362 readers.insert( |
|
2363 make_pair(label, new _reader_bits:: |
|
2364 MapReader<Edge, Map, ItemReader>(map, ir))); |
|
2365 return *this; |
|
2366 } |
|
2367 |
|
2368 public: |
|
2369 |
|
2370 /// \brief Add a new edge map skipper command for the reader. |
|
2371 /// |
|
2372 /// Add a new edge map skipper command for the reader. |
|
2373 template <typename ItemReader> |
|
2374 EdgeMapReader& skipEdgeMap(std::string label, |
|
2375 const ItemReader& ir = ItemReader()) { |
|
2376 if (readers.find(label) != readers.end()) { |
|
2377 ErrorMessage msg; |
|
2378 msg << "Multiple read rule for map: " << label; |
|
2379 throw IoParameterError(msg.message()); |
|
2380 } |
|
2381 readers.insert(make_pair(label, new _reader_bits:: |
|
2382 SkipReader<Edge, ItemReader>(ir))); |
|
2383 return *this; |
|
2384 } |
|
2385 |
|
2386 protected: |
|
2387 |
|
2388 /// \brief Gives back true when the SectionReader can process |
|
2389 /// the section with the given header line. |
|
2390 /// |
|
2391 /// It gives back true when the header line starts with \c \@mapset, |
|
2392 /// and the header line's name and the mapset's name are the same. |
|
2393 virtual bool header(const std::string& line) { |
|
2394 std::istringstream ls(line); |
|
2395 std::string command; |
|
2396 std::string id; |
|
2397 ls >> command >> id; |
|
2398 return (command == "@edgemaps" || command == "@uedgemaps") && name == id; |
|
2399 } |
|
2400 |
|
2401 /// \brief Reader function of the section. |
|
2402 /// |
|
2403 /// It reads the content of the section. |
|
2404 virtual void read(std::istream& is) { |
|
2405 std::vector<_reader_bits::MapReaderBase<Edge>* > index; |
|
2406 std::string line; |
|
2407 |
|
2408 { |
|
2409 getline(is, line); |
|
2410 std::istringstream ls(line); |
|
2411 std::string id; |
|
2412 while (ls >> id) { |
|
2413 typename MapReaders::iterator it = readers.find(id); |
|
2414 if (it != readers.end()) { |
|
2415 it->second->touch(); |
|
2416 index.push_back(it->second); |
|
2417 } else { |
|
2418 index.push_back(&skipper); |
|
2419 } |
|
2420 } |
|
2421 } |
|
2422 for (typename MapReaders::iterator it = readers.begin(); |
|
2423 it != readers.end(); ++it) { |
|
2424 if (!it->second->touched()) { |
|
2425 ErrorMessage msg; |
|
2426 msg << "Map not found in file: " << it->first; |
|
2427 throw IoParameterError(msg.message()); |
|
2428 } |
|
2429 } |
|
2430 while (getline(is, line)) { |
|
2431 std::istringstream ls(line); |
|
2432 Edge edge = labelReader->read(ls); |
|
2433 for (int i = 0; i < int(index.size()); ++i) { |
|
2434 index[i]->read(ls, edge); |
|
2435 } |
|
2436 } |
|
2437 } |
|
2438 |
|
2439 virtual void missing() { |
|
2440 if (readers.empty()) return; |
|
2441 ErrorMessage msg; |
|
2442 msg << "EdgeMap section not found in file: @edgemaps " << name; |
|
2443 throw IoParameterError(msg.message()); |
|
2444 } |
|
2445 |
|
2446 private: |
|
2447 |
|
2448 typedef std::map<std::string, _reader_bits::MapReaderBase<Edge>*> MapReaders; |
|
2449 MapReaders readers; |
|
2450 |
|
2451 const Graph& graph; |
|
2452 std::string name; |
|
2453 _reader_bits::SkipReader<Edge, DefaultSkipper> skipper; |
|
2454 std::auto_ptr<_reader_bits::LabelReaderBase<Edge> > labelReader; |
|
2455 |
|
2456 }; |
|
2457 |
|
2458 /// \ingroup section_io |
|
2459 /// \brief SectionReader for reading extra undirected edge maps. |
|
2460 /// |
|
2461 /// The lemon format can store maps in the uedgeset sections. This |
|
2462 /// class let you make distinict section to store maps. The main |
|
2463 /// purpose of this class is a logical separation of some maps. The |
|
2464 /// other useful application could be to store paths in undirected |
|
2465 /// edge maps. |
|
2466 /// |
|
2467 /// The first line of the section contains the names of the maps |
|
2468 /// separated with white spaces. Each next line describes an item |
|
2469 /// in the itemset, and contains in the first column the label of |
|
2470 /// the item and then the mapped values for each map. |
|
2471 /// |
|
2472 /// \relates LemonReader |
|
2473 template <typename _Graph, typename _Traits = DefaultReaderTraits> |
|
2474 class UEdgeMapReader : public LemonReader::SectionReader { |
|
2475 typedef LemonReader::SectionReader Parent; |
|
2476 public: |
|
2477 |
|
2478 typedef _Graph Graph; |
|
2479 typedef typename Graph::Edge Edge; |
|
2480 typedef typename Graph::UEdge UEdge; |
|
2481 typedef _Traits Traits; |
|
2482 typedef typename Traits::Skipper DefaultSkipper; |
|
2483 |
|
2484 /// \brief Constructor. |
|
2485 /// |
|
2486 /// Constructor for UEdgeMapReader. It creates the UEdgeMapReader and |
|
2487 /// attach it into the given LemonReader. The reader will read |
|
2488 /// the section when the \c section_name and the \c _name are the same. |
|
2489 template <typename _LabelReader> |
|
2490 UEdgeMapReader(LemonReader& _reader, const Graph& _graph, |
|
2491 const _LabelReader& _labelReader, |
|
2492 const std::string& _name = std::string(), |
|
2493 const DefaultSkipper& _skipper = DefaultSkipper()) |
|
2494 : Parent(_reader), graph(_graph), name(_name), skipper(_skipper) { |
|
2495 labelReader.reset(new _reader_bits:: |
|
2496 LabelReader<UEdge, _LabelReader>(_labelReader)); |
|
2497 } |
|
2498 |
|
2499 |
|
2500 /// \brief Destructor. |
|
2501 /// |
|
2502 /// Destructor for UEdgeMapReader. |
|
2503 virtual ~UEdgeMapReader() { |
|
2504 for (typename MapReaders::iterator it = readers.begin(); |
|
2505 it != readers.end(); ++it) { |
|
2506 delete it->second; |
|
2507 } |
|
2508 } |
|
2509 |
|
2510 private: |
|
2511 UEdgeMapReader(const UEdgeMapReader&); |
|
2512 void operator=(const UEdgeMapReader&); |
|
2513 |
|
2514 public: |
|
2515 |
|
2516 /// \brief Add a new undirected edge map reader command for the |
|
2517 /// reader. |
|
2518 /// |
|
2519 /// Add a new undirected edge map reader command for the reader. |
|
2520 template <typename Map> |
|
2521 UEdgeMapReader& readUEdgeMap(std::string label, Map& map) { |
|
2522 return _readMap< |
|
2523 typename Traits::template Reader<typename Map::Value>, Map, |
|
2524 typename _reader_bits::Arg<Map>::Type>(label, map); |
|
2525 } |
|
2526 |
|
2527 template <typename Map> |
|
2528 UEdgeMapReader& readUEdgeMap(std::string label, const Map& map) { |
|
2529 return _readMap< |
|
2530 typename Traits::template Reader<typename Map::Value>, Map, |
|
2531 typename _reader_bits::Arg<Map>::Type>(label, map); |
|
2532 } |
|
2533 |
|
2534 /// \brief Add a new undirected edge map reader command for the |
|
2535 /// reader. |
|
2536 /// |
|
2537 /// Add a new undirected edge map reader command for the reader. |
|
2538 template <typename ItemReader, typename Map> |
|
2539 UEdgeMapReader& readUEdgeMap(std::string label, Map& map, |
|
2540 const ItemReader& ir = ItemReader()) { |
|
2541 return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type> |
|
2542 (label, map, ir); |
|
2543 } |
|
2544 |
|
2545 template <typename ItemReader, typename Map> |
|
2546 UEdgeMapReader& readUEdgeMap(std::string label, const Map& map, |
|
2547 const ItemReader& ir = ItemReader()) { |
|
2548 return _readMap<ItemReader, Map, typename _reader_bits::Arg<Map>::Type> |
|
2549 (label, map, ir); |
|
2550 } |
|
2551 |
|
2552 private: |
|
2553 |
|
2554 template <typename ItemReader, typename Map, typename MapParameter> |
|
2555 UEdgeMapReader& _readMap(std::string label, MapParameter map, |
|
2556 const ItemReader& ir = ItemReader()) { |
|
2557 checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>(); |
|
2558 checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>(); |
|
2559 if (readers.find(label) != readers.end()) { |
|
2560 ErrorMessage msg; |
|
2561 msg << "Multiple read rule for map: " << label; |
|
2562 throw IoParameterError(msg.message()); |
|
2563 } |
|
2564 readers.insert( |
|
2565 make_pair(label, new _reader_bits:: |
|
2566 MapReader<UEdge, Map, ItemReader>(map, ir))); |
|
2567 return *this; |
|
2568 } |
|
2569 |
|
2570 public: |
|
2571 |
|
2572 /// \brief Add a new undirected edge map skipper command for the |
|
2573 /// reader. |
|
2574 /// |
|
2575 /// Add a new undirected edge map skipper command for the reader. |
|
2576 template <typename ItemReader> |
|
2577 UEdgeMapReader& skipUEdgeMap(std::string label, |
|
2578 const ItemReader& ir = ItemReader()) { |
|
2579 if (readers.find(label) != readers.end()) { |
|
2580 ErrorMessage msg; |
|
2581 msg << "Multiple read rule for map: " << label; |
|
2582 throw IoParameterError(msg.message()); |
|
2583 } |
|
2584 readers.insert(make_pair(label, new _reader_bits:: |
|
2585 SkipReader<Edge, ItemReader>(ir))); |
|
2586 return *this; |
|
2587 } |
|
2588 |
|
2589 /// \brief Add a new directed edge map reader command for the reader. |
|
2590 /// |
|
2591 /// Add a new directed edge map reader command for the reader. |
|
2592 template <typename Map> |
|
2593 UEdgeMapReader& readEdgeMap(std::string label, Map& map) { |
|
2594 return _readDirMap< |
|
2595 typename Traits::template Reader<typename Map::Value>, Map, |
|
2596 typename _reader_bits::Arg<Map>::Type>(label, map); |
|
2597 } |
|
2598 |
|
2599 template <typename Map> |
|
2600 UEdgeMapReader& readEdgeMap(std::string label, const Map& map) { |
|
2601 return _readDirMap< |
|
2602 typename Traits::template Reader<typename Map::Value>, Map, |
|
2603 typename _reader_bits::Arg<Map>::Type>(label, map); |
|
2604 } |
|
2605 |
|
2606 /// \brief Add a new directed edge map reader command for the reader. |
|
2607 /// |
|
2608 /// Add a new directed edge map reader command for the reader. |
|
2609 template <typename ItemReader, typename Map> |
|
2610 UEdgeMapReader& readEdgeMap(std::string label, Map& map, |
|
2611 const ItemReader& ir = ItemReader()) { |
|
2612 return _readDirMap<ItemReader, Map, |
|
2613 typename _reader_bits::Arg<Map>::Type>(label, map, ir); |
|
2614 } |
|
2615 |
|
2616 template <typename ItemReader, typename Map> |
|
2617 UEdgeMapReader& readEdgeMap(std::string label, const Map& map, |
|
2618 const ItemReader& ir = ItemReader()) { |
|
2619 return _readDirMap<ItemReader, Map, |
|
2620 typename _reader_bits::Arg<Map>::Type>(label, map, ir); |
|
2621 } |
|
2622 |
|
2623 private: |
|
2624 |
|
2625 template <typename ItemReader, typename Map, typename MapParameter> |
|
2626 UEdgeMapReader& _readDirMap(std::string label, MapParameter map, |
|
2627 const ItemReader& ir = ItemReader()) { |
|
2628 checkConcept<_reader_bits::ItemReader<typename Map::Value>, ItemReader>(); |
|
2629 checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>(); |
|
2630 readUEdgeMap("+" + label, |
|
2631 _reader_bits::forwardComposeMap(graph, map), ir); |
|
2632 readUEdgeMap("-" + label, |
|
2633 _reader_bits::backwardComposeMap(graph, map), ir); |
|
2634 return *this; |
|
2635 } |
|
2636 |
|
2637 public: |
|
2638 |
|
2639 /// \brief Add a new directed edge map skipper command for the reader. |
|
2640 /// |
|
2641 /// Add a new directed edge map skipper command for the reader. |
|
2642 template <typename ItemReader> |
|
2643 UEdgeMapReader& skipEdgeMap(std::string label, |
|
2644 const ItemReader& ir = ItemReader()) { |
|
2645 skipUEdgeMap("+" + label, ir); |
|
2646 skipUEdgeMap("-" + label, ir); |
|
2647 return *this; |
|
2648 } |
|
2649 |
|
2650 protected: |
|
2651 |
|
2652 /// \brief Gives back true when the SectionReader can process |
|
2653 /// the section with the given header line. |
|
2654 /// |
|
2655 /// It gives back true when the header line starts with \c \@mapset, |
|
2656 /// and the header line's name and the mapset's name are the same. |
|
2657 virtual bool header(const std::string& line) { |
|
2658 std::istringstream ls(line); |
|
2659 std::string command; |
|
2660 std::string id; |
|
2661 ls >> command >> id; |
|
2662 return (command == "@edgemaps" || command == "@uedgemaps") && name == id; |
|
2663 } |
|
2664 |
|
2665 /// \brief Reader function of the section. |
|
2666 /// |
|
2667 /// It reads the content of the section. |
|
2668 virtual void read(std::istream& is) { |
|
2669 std::vector<_reader_bits::MapReaderBase<UEdge>* > index; |
|
2670 std::string line; |
|
2671 |
|
2672 { |
|
2673 getline(is, line); |
|
2674 std::istringstream ls(line); |
|
2675 std::string id; |
|
2676 while (ls >> id) { |
|
2677 typename MapReaders::iterator it = readers.find(id); |
|
2678 if (it != readers.end()) { |
|
2679 it->second->touch(); |
|
2680 index.push_back(it->second); |
|
2681 } else { |
|
2682 index.push_back(&skipper); |
|
2683 } |
|
2684 } |
|
2685 } |
|
2686 for (typename MapReaders::iterator it = readers.begin(); |
|
2687 it != readers.end(); ++it) { |
|
2688 if (!it->second->touched()) { |
|
2689 ErrorMessage msg; |
|
2690 msg << "Map not found in file: " << it->first; |
|
2691 throw IoParameterError(msg.message()); |
|
2692 } |
|
2693 } |
|
2694 while (getline(is, line)) { |
|
2695 std::istringstream ls(line); |
|
2696 UEdge uedge = labelReader->read(ls); |
|
2697 for (int i = 0; i < int(index.size()); ++i) { |
|
2698 index[i]->read(ls, uedge); |
|
2699 } |
|
2700 } |
|
2701 } |
|
2702 |
|
2703 virtual void missing() { |
|
2704 if (readers.empty()) return; |
|
2705 ErrorMessage msg; |
|
2706 msg << "UEdgeMap section not found in file: @uedgemaps " << name; |
|
2707 throw IoParameterError(msg.message()); |
|
2708 } |
|
2709 |
|
2710 private: |
|
2711 |
|
2712 const Graph& graph; |
|
2713 std::string name; |
|
2714 |
|
2715 typedef std::map<std::string, |
|
2716 _reader_bits::MapReaderBase<UEdge>*> MapReaders; |
|
2717 |
|
2718 MapReaders readers; |
|
2719 _reader_bits::SkipReader<UEdge, DefaultSkipper> skipper; |
|
2720 |
|
2721 std::auto_ptr<_reader_bits::LabelReaderBase<UEdge> > labelReader; |
|
2722 |
2054 }; |
2723 }; |
2055 |
2724 |
2056 /// \ingroup section_io |
2725 /// \ingroup section_io |
2057 /// \brief SectionReader for retrieve what is in the file. |
2726 /// \brief SectionReader for retrieve what is in the file. |
2058 /// |
2727 /// |