The graph adadptors can be alteration observed.
In most cases it uses the adapted graph alteration notifiers.
Only special case is now the UndirGraphAdaptor, where
we have to proxy the signals from the graph.
The SubBidirGraphAdaptor is removed, because it doest not
gives more feature than the EdgeSubGraphAdaptor<UndirGraphAdaptor<Graph>>.
The ResGraphAdaptor is based on this composition.
3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2006
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
19 /// @defgroin item_io Item Readers and Writers
21 /// \brief Item Readers and Writers
23 /// The Input-Output classes can handle more data type by example
24 /// as map or attribute value. Each of these should be written and
25 /// read some way. The module make possible to do this.
29 /// \brief Item reader bits for lemon input.
31 #ifndef LEMON_BITS_ITEM_READER_H
32 #define LEMON_BITS_ITEM_READER_H
44 template <typename Value>
49 /// \brief Reader class for quoted strings.
51 /// Reader class for quoted strings. It can process the escape
52 /// sequences in the string.
54 /// \author Balazs Dezso
55 class QuotedStringReader {
57 /// \brief The value type of reader.
59 /// The value type of reader.
60 typedef std::string Value;
62 /// \brief Constructor for the reader.
64 /// Constructor for the reader. If the given parameter is true
65 /// the reader processes the escape sequences.
66 QuotedStringReader(bool _escaped = true)
67 : escaped(_escaped) {}
69 /// \brief Reads a quoted string from the given stream.
71 /// Reads a quoted string from the given stream.
72 void read(std::istream& is, std::string& value) const {
76 if (!is.get(c) || c != '\"')
77 throw DataFormatError("Quoted string format error");
78 while (is.get(c) && c != '\"') {
79 if (escaped && c == '\\') {
80 value += readEscape(is);
85 if (!is) throw DataFormatError("Quoted string format error");
90 static char readEscape(std::istream& is) {
92 switch (is.get(c), c) {
118 if (!is.get(c) || !isHex(c))
119 throw DataFormatError("Escape format error");
120 else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
121 else code = code * 16 + valueHex(c);
128 throw DataFormatError("Escape format error");
129 else if (code = valueOct(c), !is.get(c) || !isOct(c))
131 else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c))
133 else code = code * 8 + valueOct(c);
139 static bool isOct(char c) {
140 return '0' <= c && c <='7';
143 static int valueOct(char c) {
147 static bool isHex(char c) {
148 return ('0' <= c && c <= '9') ||
149 ('a' <= c && c <= 'z') ||
150 ('A' <= c && c <= 'Z');
153 static int valueHex(char c) {
154 if ('0' <= c && c <= '9') return c - '0';
155 if ('a' <= c && c <= 'z') return c - 'a' + 10;
163 /// \brief Reader for standard containers.
165 /// Reader for back insertable standard containers. The representation
166 /// of the container is the values enumerated between an open and a
169 /// \author Balazs Dezso
172 typename _ItemReader = DefaultReader<typename _Container::value_type>
174 class PushBackReader {
176 typedef _Container Value;
177 typedef _ItemReader ItemReader;
181 ItemReader item_reader;
185 /// \brief Constructor for InsertReader
187 /// Constructor for InsertReader
188 PushBackReader(const ItemReader& _item_reader = ItemReader())
189 : item_reader(_item_reader) {}
191 /// \brief Reads the values into the container from the given stream.
193 /// Reads the values into the container from the given stream.
194 void read(std::istream& is, Value& value) const {
196 if (!(is >> c) || c != '(')
197 throw DataFormatError("PushBackReader format error");
198 while (is >> c && c != ')') {
200 typename ItemReader::Value item;
201 item_reader.read(is, item);
202 value.push_back(item);
204 if (!is) throw DataFormatError("PushBackReader format error");
211 /// \brief Reader for standard containers.
213 /// Reader for insertable standard containers. The representation
214 /// of the container is the values enumerated between an open and a
217 /// \author Balazs Dezso
220 typename _ItemReader = DefaultReader<typename _Container::value_type>
224 typedef _Container Value;
225 typedef _ItemReader ItemReader;
229 ItemReader item_reader;
233 /// \brief Constructor for InsertReader
235 /// Constructor for InsertReader
236 InsertReader(const ItemReader& _item_reader = ItemReader())
237 : item_reader(_item_reader) {}
239 /// \brief Reads the values into the container from the given stream.
241 /// Reads the values into the container from the given stream.
242 void read(std::istream& is, Value& value) const {
244 if (!(is >> c) || c != '(')
245 throw DataFormatError("InsertReader format error");
246 while (is >> c && c != ')') {
248 typename ItemReader::Value item;
249 item_reader.read(is, item);
252 if (!is) throw DataFormatError("PushBackReader format error");
258 /// \brief Reader for parsed string.
260 /// Reader for parsed strings. You can define the open and close
261 /// parse characters. It reads from the input a character sequence
262 /// which is right parsed.
264 /// \author Balazs Dezso
265 class ParsedStringReader {
267 typedef std::string Value;
269 /// \brief Constructor.
271 /// Constructor for ParsedStringReader. You can give as parameter
272 /// the open and close parse characters.
273 ParsedStringReader(char _open = '(', char _close = ')')
274 : open(_open), close(_close) {}
277 /// \brief Reads the parsed string from the given stream.
279 /// Reads the parsed string from the given stream.
280 void read(std::istream& is, Value& value) const {
282 if (!(is >> c) || c != open) {
283 throw DataFormatError("ParsedStringReader format error");
287 while (counter > 0 && is >> c) {
290 } else if (c == open) {
296 throw DataFormatError("ParsedStrinReader format error");
306 /// \brief Reader for read the whole line.
308 /// Reader for read the whole line.
310 /// \author Balazs Dezso
313 typedef std::string Value;
315 /// \brief Constructor.
317 /// Constructor for the LineReader. If the given parameter is
318 /// true then the spaces before the first not space character are
320 LineReader(bool _skipSpaces = true) : skipSpaces(_skipSpaces) {}
322 /// \brief Reads the line from the given stream.
324 /// Reads the line from the given stream.
325 void read(std::istream& is, Value& value) const {
326 if (skipSpaces) is >> std::ws;
327 if (!getline(is, value)) {
328 throw DataFormatError("LineReader format error");
336 /// \brief Reader for std::pair.
338 /// Reader for std::pair.
340 /// \author Balazs Dezso
341 template <typename _Pair,
342 typename _FirstReader =
343 DefaultReader<typename _Pair::first_type>,
344 typename _SecondReader =
345 DefaultReader<typename _Pair::second_type> >
350 typedef _FirstReader FirstReader;
351 typedef _SecondReader SecondReader;
355 FirstReader first_reader;
356 SecondReader second_reader;
360 /// \brief Constructor.
362 /// Constructor for the PairReader.
363 PairReader(const FirstReader& _first_reader = FirstReader(),
364 const SecondReader& _second_reader = SecondReader())
365 : first_reader(_first_reader), second_reader(_second_reader) {}
367 /// \brief Reads the pair from the given stream.
369 /// Reads the pair from the given stream.
370 void read(std::istream& is, Value& value) const {
372 if (!(is >> c) || c != '(') {
373 throw DataFormatError("PairReader format error");
375 first_reader.read(is, value.first);
376 if (!(is >> c) || c != '=') {
377 throw DataFormatError("PairReader format error");
379 if (!(is >> c) || c != '>') {
380 throw DataFormatError("PairReader format error");
382 second_reader.read(is, value.second);
383 if (!(is >> c) || c != ')') {
384 throw DataFormatError("PairReader format error");
391 /// \brief The default item reader template class.
393 /// The default item reader template class. If some section reader
394 /// needs to read a value from a stream it will give the default way for it.
396 /// \author Balazs Dezso
397 template <typename _Value>
398 class DefaultReader {
401 typedef _Value Value;
402 /// \brief Reads a value from the given stream.
404 /// Reads a value from the given stream.
405 void read(std::istream& is, Value& value) const {
407 throw DataFormatError("DefaultReader format error");
412 class DefaultReader<std::string> {
414 typedef std::string Value;
416 void read(std::istream& is, Value& value) const {
418 if (!(is >> std::ws >> c)) return;
422 QuotedStringReader().read(is, value);
425 ParsedStringReader().read(is, value);
428 ParsedStringReader('[', ']').read(is, value);
431 ParsedStringReader('/', '/').read(is, value);
435 throw DataFormatError("DefaultReader format error");
442 template <typename Item>
443 class DefaultReader<std::vector<Item> >
444 : public PushBackReader<std::vector<Item> > {};
446 template <typename Item>
447 class DefaultReader<std::deque<Item> >
448 : public PushBackReader<std::deque<Item> > {};
450 template <typename Item>
451 class DefaultReader<std::list<Item> >
452 : public PushBackReader<std::list<Item> > {};
454 template <typename Item>
455 class DefaultReader<std::set<Item> >
456 : public InsertReader<std::set<Item> > {};
458 template <typename Key, typename Value>
459 class DefaultReader<std::map<Key, Value> >
460 : public InsertReader<std::map<Key, Value>,
461 DefaultReader<std::pair<Key, Value> > > {};
463 template <typename Item>
464 class DefaultReader<std::multiset<Item> >
465 : public InsertReader<std::multiset<Item> > {};
467 template <typename Key, typename Value>
468 class DefaultReader<std::multimap<Key, Value> >
469 : public InsertReader<std::multimap<Key, Value>,
470 DefaultReader<std::pair<Key, Value> > > {};
472 template <typename First, typename Second>
473 class DefaultReader<std::pair<First, Second> >
474 : public PairReader<std::pair<First, Second> > {};
478 /// \brief The default item reader for skipping a value in the stream.
480 /// The default item reader for skipping a value in the stream.
482 /// \author Balazs Dezso
483 class DefaultSkipper : public DefaultReader<std::string> {};
486 /// \brief Standard ReaderTraits for the GraphReader class.
488 /// Standard ReaderTraits for the GraphReader class.
489 /// It defines standard reading method for all type of value.
490 /// \author Balazs Dezso
491 struct DefaultReaderTraits {
493 template <typename _Value>
494 struct Reader : DefaultReader<_Value> {};
496 typedef DefaultSkipper Skipper;