Small bug fixes and changes in the documentation.
3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2007
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
21 /// \brief Item reader bits for lemon input.
23 #ifndef LEMON_BITS_ITEM_READER_H
24 #define LEMON_BITS_ITEM_READER_H
35 #include <lemon/error.h>
39 template <typename Value>
44 /// \brief Reader class for unformatted strings.
46 /// Reader class for unformatted strings. This class want to be
47 /// a general reader type which can read the most
49 /// \author Balazs Dezso
50 class UnformattedReader {
52 /// \brief The value type of reader.
54 /// The value type of reader.
55 typedef std::string Value;
57 /// \brief Constructor for the reader.
59 /// Constructor for the reader.
60 UnformattedReader() {}
62 /// \brief Reads an unformatted string from the given stream.
64 /// Reads an unformatted string from the given stream.
65 void read(std::istream& is, std::string& value) const {
69 while (is.get(c) && !whiteSpace(c)) {
70 processChar(c, is, value);
76 void processChar(char c, std::istream& is, Value& value) const {
80 readParsed('(', ')', is, value);
84 readParsed('[', ']', is, value);
88 readParsed('{', '}', is, value);
92 readParsed('/', '/', is, value);
96 readQuoted('\"', is, value);
100 readQuoted('\'', is, value);
108 void readParsed(char open, char close,
109 std::istream& is, Value& value) const {
111 if (!is.get(c) || c != open)
112 throw DataFormatError("Unformatted string format error");
114 while (is.get(c) && c != close) {
115 processChar(c, is, value);
118 throw DataFormatError("Unformatted string format error");
122 void readQuoted(char quote, std::istream& is, Value& value) const {
125 if (!is.get(c) || c != quote)
126 throw DataFormatError("Unformatted string format error");
128 while (is.get(c) && (c != quote || esc)) {
129 if (c == '\\') esc = !esc;
134 throw DataFormatError("Unformatted string format error");
140 static bool whiteSpace(char c) {
141 return c == ' ' || c == '\t' || c == '\v' ||
142 c == '\n' || c == '\r' || c == '\f';
150 /// \brief Reader class for quoted strings.
152 /// Reader class for quoted strings. It can process the escape
153 /// sequences in the string.
155 /// \author Balazs Dezso
156 class QuotedStringReader {
157 friend class QuotedCharReader;
159 /// \brief The value type of reader.
161 /// The value type of reader.
162 typedef std::string Value;
164 /// \brief Constructor for the reader.
166 /// Constructor for the reader. If the given parameter is true
167 /// the reader processes the escape sequences.
168 QuotedStringReader(bool _escaped = true)
169 : escaped(_escaped) {}
171 /// \brief Reads a quoted string from the given stream.
173 /// Reads a quoted string from the given stream.
174 void read(std::istream& is, std::string& value) const {
178 if (!is.get(c) || (c != '\"' && c != '\''))
179 throw DataFormatError("Quoted format error");
181 while (is.get(c) && c != quote) {
182 if (escaped && c == '\\') {
183 value += readEscape(is);
188 if (!is) throw DataFormatError("Quoted format error");
193 static char readEscape(std::istream& is) {
195 switch (is.get(c), c) {
221 if (!is.get(c) || !isHex(c))
222 throw DataFormatError("Escape format error");
223 else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
224 else code = code * 16 + valueHex(c);
231 throw DataFormatError("Escape format error");
232 else if (code = valueOct(c), !is.get(c) || !isOct(c))
234 else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c))
236 else code = code * 8 + valueOct(c);
242 static bool isOct(char c) {
243 return '0' <= c && c <='7';
246 static int valueOct(char c) {
250 static bool isHex(char c) {
251 return ('0' <= c && c <= '9') ||
252 ('a' <= c && c <= 'z') ||
253 ('A' <= c && c <= 'Z');
256 static int valueHex(char c) {
257 if ('0' <= c && c <= '9') return c - '0';
258 if ('a' <= c && c <= 'z') return c - 'a' + 10;
267 /// \brief Reader class for quoted strings.
269 /// Reader class for quoted strings. It can process the escape
270 /// sequences in the string.
272 /// \author Balazs Dezso
273 class QuotedCharReader {
275 /// \brief The value type of reader.
277 /// The value type of reader.
280 /// \brief Constructor for the reader.
282 /// Constructor for the reader. If the given parameter is true
283 /// the reader processes the escape sequences.
284 QuotedCharReader(bool _escaped = true)
285 : escaped(_escaped) {}
287 /// \brief Reads a quoted string from the given stream.
289 /// Reads a quoted string from the given stream.
290 void read(std::istream& is, char& value) const {
293 if (!is.get(c) || c != '\'')
294 throw DataFormatError("Quoted format error");
296 throw DataFormatError("Quoted format error");
297 if (escaped && c == '\\') {
298 value = QuotedStringReader::readEscape(is);
302 if (!is.get(c) || c != '\'')
303 throw DataFormatError("Quoted format error");
311 /// \brief Reader for standard containers.
313 /// Reader for back insertable standard containers. The representation
314 /// of the container is the values enumerated between an open and a
317 /// \author Balazs Dezso
320 typename _ItemReader = DefaultReader<typename _Container::value_type>
322 class PushBackReader {
324 typedef _Container Value;
325 typedef _ItemReader ItemReader;
329 ItemReader item_reader;
333 /// \brief Constructor for InsertReader
335 /// Constructor for InsertReader
336 PushBackReader(const ItemReader& _item_reader = ItemReader())
337 : item_reader(_item_reader) {}
339 /// \brief Reads the values into the container from the given stream.
341 /// Reads the values into the container from the given stream.
342 void read(std::istream& is, Value& value) const {
344 if (!(is >> c) || c != '(')
345 throw DataFormatError("PushBackReader format error");
346 while (is >> c && c != ')') {
348 typename ItemReader::Value item;
349 item_reader.read(is, item);
350 value.push_back(item);
352 if (!is) throw DataFormatError("PushBackReader format error");
359 /// \brief Reader for standard containers.
361 /// Reader for insertable standard containers. The representation
362 /// of the container is the values enumerated between an open and a
365 /// \author Balazs Dezso
368 typename _ItemReader = DefaultReader<typename _Container::value_type>
372 typedef _Container Value;
373 typedef _ItemReader ItemReader;
377 ItemReader item_reader;
381 /// \brief Constructor for InsertReader
383 /// Constructor for InsertReader
384 InsertReader(const ItemReader& _item_reader = ItemReader())
385 : item_reader(_item_reader) {}
387 /// \brief Reads the values into the container from the given stream.
389 /// Reads the values into the container from the given stream.
390 void read(std::istream& is, Value& value) const {
392 if (!(is >> c) || c != '(')
393 throw DataFormatError("InsertReader format error");
394 while (is >> c && c != ')') {
396 typename ItemReader::Value item;
397 item_reader.read(is, item);
400 if (!is) throw DataFormatError("PushBackReader format error");
406 /// \brief Reader for parsed string.
408 /// Reader for parsed strings. You can define the open and close
409 /// parse characters. It reads from the input a character sequence
410 /// which is right parsed.
412 /// \author Balazs Dezso
413 class ParsedStringReader {
415 typedef std::string Value;
417 /// \brief Constructor.
419 /// Constructor for ParsedStringReader. You can give as parameter
420 /// the open and close parse characters.
421 ParsedStringReader(char _open = '(', char _close = ')')
422 : open(_open), close(_close) {}
425 /// \brief Reads the parsed string from the given stream.
427 /// Reads the parsed string from the given stream.
428 void read(std::istream& is, Value& value) const {
431 if (!(is >> c) || c != open) {
432 throw DataFormatError("ParsedStringReader format error");
436 while (counter > 0 && is >> c) {
439 } else if (c == open) {
445 throw DataFormatError("ParsedStrinReader format error");
455 /// \brief Reader for read the whole line.
457 /// Reader for read the whole line.
459 /// \author Balazs Dezso
462 typedef std::string Value;
464 /// \brief Constructor.
466 /// Constructor for the LineReader. If the given parameter is
467 /// true then the spaces before the first not space character are
469 LineReader(bool _skipSpaces = true) : skipSpaces(_skipSpaces) {}
471 /// \brief Reads the line from the given stream.
473 /// Reads the line from the given stream.
474 void read(std::istream& is, Value& value) const {
475 if (skipSpaces) is >> std::ws;
476 if (!getline(is, value)) {
477 throw DataFormatError("LineReader format error");
485 /// \brief Reader for std::pair.
487 /// Reader for std::pair.
489 /// \author Balazs Dezso
490 template <typename _Pair,
491 typename _FirstReader =
492 DefaultReader<typename _Pair::first_type>,
493 typename _SecondReader =
494 DefaultReader<typename _Pair::second_type> >
499 typedef _FirstReader FirstReader;
500 typedef _SecondReader SecondReader;
504 FirstReader first_reader;
505 SecondReader second_reader;
509 /// \brief Constructor.
511 /// Constructor for the PairReader.
512 PairReader(const FirstReader& _first_reader = FirstReader(),
513 const SecondReader& _second_reader = SecondReader())
514 : first_reader(_first_reader), second_reader(_second_reader) {}
516 /// \brief Reads the pair from the given stream.
518 /// Reads the pair from the given stream.
519 void read(std::istream& is, Value& value) const {
521 if (!(is >> c) || c != '(') {
522 throw DataFormatError("PairReader format error");
524 first_reader.read(is, value.first);
525 if (!(is >> c) || c != '=') {
526 throw DataFormatError("PairReader format error");
528 if (!(is >> c) || c != '>') {
529 throw DataFormatError("PairReader format error");
531 second_reader.read(is, value.second);
532 if (!(is >> c) || c != ')') {
533 throw DataFormatError("PairReader format error");
540 /// \brief The default item reader template class.
542 /// The default item reader template class. If some section reader
543 /// needs to read a value from a stream it will give the default way for it.
545 /// \author Balazs Dezso
546 template <typename _Value>
547 class DefaultReader {
550 typedef _Value Value;
551 /// \brief Reads a value from the given stream.
553 /// Reads a value from the given stream.
554 void read(std::istream& is, Value& value) const {
556 throw DataFormatError("DefaultReader format error");
561 class DefaultReader<std::string> {
563 typedef std::string Value;
565 void read(std::istream& is, Value& value) const {
567 if (!(is >> std::ws >> c))
568 throw DataFormatError("DefaultReader<string> format error");
572 QuotedStringReader().read(is, value);
575 UnformattedReader().read(is, value);
583 class DefaultReader<char> {
587 void read(std::istream& is, Value& value) const {
589 if (!(is >> std::ws >> c))
590 throw DataFormatError("DefaultReader<char> format error");
594 QuotedCharReader().read(is, value);
600 throw DataFormatError("DefaultReader<char> format error");
601 value = static_cast<char>(temp);
609 class DefaultReader<bool> {
613 void read(std::istream& is, Value& value) const {
616 throw DataFormatError("DefaultReader<bool> format error");
617 if (rep == "true" || rep == "t" || rep == "1") {
619 } else if (rep == "false" || rep == "f" || rep == "0") {
621 } else throw DataFormatError("DefaultReader<bool> format error");
625 template <typename Item>
626 class DefaultReader<std::vector<Item> >
627 : public PushBackReader<std::vector<Item> > {};
629 template <typename Item>
630 class DefaultReader<std::deque<Item> >
631 : public PushBackReader<std::deque<Item> > {};
633 template <typename Item>
634 class DefaultReader<std::list<Item> >
635 : public PushBackReader<std::list<Item> > {};
637 template <typename Item>
638 class DefaultReader<std::set<Item> >
639 : public InsertReader<std::set<Item> > {};
641 template <typename Key, typename Value>
642 class DefaultReader<std::map<Key, Value> >
643 : public InsertReader<std::map<Key, Value>,
644 DefaultReader<std::pair<Key, Value> > > {};
646 template <typename Item>
647 class DefaultReader<std::multiset<Item> >
648 : public InsertReader<std::multiset<Item> > {};
650 template <typename Key, typename Value>
651 class DefaultReader<std::multimap<Key, Value> >
652 : public InsertReader<std::multimap<Key, Value>,
653 DefaultReader<std::pair<Key, Value> > > {};
655 template <typename First, typename Second>
656 class DefaultReader<std::pair<First, Second> >
657 : public PairReader<std::pair<First, Second> > {};
661 /// \brief The default item reader for skipping a value in the stream.
663 /// The default item reader for skipping a value in the stream.
665 /// \author Balazs Dezso
666 class DefaultSkipper : public UnformattedReader {};
669 /// \brief Standard ReaderTraits for the GraphReader class.
671 /// Standard ReaderTraits for the GraphReader class.
672 /// It defines standard reading method for all type of value.
673 /// \author Balazs Dezso
674 struct DefaultReaderTraits {
676 template <typename _Value>
677 struct Reader : DefaultReader<_Value> {};
679 typedef DefaultSkipper Skipper;