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
36 template <typename Value>
41 /// \brief Reader class for unformatted strings.
43 /// Reader class for unformatted strings. This class want to be
44 /// a general reader type which can read the most
46 /// \author Balazs Dezso
47 class UnformattedReader {
49 /// \brief The value type of reader.
51 /// The value type of reader.
52 typedef std::string Value;
54 /// \brief Constructor for the reader.
56 /// Constructor for the reader.
57 UnformattedReader() {}
59 /// \brief Reads an unformatted string from the given stream.
61 /// Reads an unformatted string from the given stream.
62 void read(std::istream& is, std::string& value) const {
66 while (is.get(c) && !whiteSpace(c)) {
67 processChar(c, is, value);
73 void processChar(char c, std::istream& is, Value& value) const {
77 readParsed('(', ')', is, value);
81 readParsed('[', ']', is, value);
85 readParsed('{', '}', is, value);
89 readParsed('/', '/', is, value);
93 readQuoted('\"', is, value);
97 readQuoted('\'', is, value);
105 void readParsed(char open, char close,
106 std::istream& is, Value& value) const {
108 if (!is.get(c) || c != open)
109 throw DataFormatError("Unformatted string format error");
111 while (is.get(c) && c != close) {
112 processChar(c, is, value);
115 throw DataFormatError("Unformatted string format error");
119 void readQuoted(char quote, std::istream& is, Value& value) const {
122 if (!is.get(c) || c != quote)
123 throw DataFormatError("Unformatted string format error");
125 while (is.get(c) && (c != quote || esc)) {
126 if (c == '\\') esc = !esc;
131 throw DataFormatError("Unformatted string format error");
137 static bool whiteSpace(char c) {
138 return c == ' ' || c == '\t' || c == '\v' ||
139 c == '\n' || c == '\r' || c == '\f';
147 /// \brief Reader class for quoted strings.
149 /// Reader class for quoted strings. It can process the escape
150 /// sequences in the string.
152 /// \author Balazs Dezso
153 class QuotedStringReader {
154 friend class QuotedCharReader;
156 /// \brief The value type of reader.
158 /// The value type of reader.
159 typedef std::string Value;
161 /// \brief Constructor for the reader.
163 /// Constructor for the reader. If the given parameter is true
164 /// the reader processes the escape sequences.
165 QuotedStringReader(bool _escaped = true)
166 : escaped(_escaped) {}
168 /// \brief Reads a quoted string from the given stream.
170 /// Reads a quoted string from the given stream.
171 void read(std::istream& is, std::string& value) const {
175 if (!is.get(c) || c != '\"')
176 throw DataFormatError("Quoted format error");
177 while (is.get(c) && c != '\"') {
178 if (escaped && c == '\\') {
179 value += readEscape(is);
184 if (!is) throw DataFormatError("Quoted format error");
189 static char readEscape(std::istream& is) {
191 switch (is.get(c), c) {
217 if (!is.get(c) || !isHex(c))
218 throw DataFormatError("Escape format error");
219 else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
220 else code = code * 16 + valueHex(c);
227 throw DataFormatError("Escape format error");
228 else if (code = valueOct(c), !is.get(c) || !isOct(c))
230 else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c))
232 else code = code * 8 + valueOct(c);
238 static bool isOct(char c) {
239 return '0' <= c && c <='7';
242 static int valueOct(char c) {
246 static bool isHex(char c) {
247 return ('0' <= c && c <= '9') ||
248 ('a' <= c && c <= 'z') ||
249 ('A' <= c && c <= 'Z');
252 static int valueHex(char c) {
253 if ('0' <= c && c <= '9') return c - '0';
254 if ('a' <= c && c <= 'z') return c - 'a' + 10;
263 /// \brief Reader class for quoted strings.
265 /// Reader class for quoted strings. It can process the escape
266 /// sequences in the string.
268 /// \author Balazs Dezso
269 class QuotedCharReader {
271 /// \brief The value type of reader.
273 /// The value type of reader.
276 /// \brief Constructor for the reader.
278 /// Constructor for the reader. If the given parameter is true
279 /// the reader processes the escape sequences.
280 QuotedCharReader(bool _escaped = true)
281 : escaped(_escaped) {}
283 /// \brief Reads a quoted string from the given stream.
285 /// Reads a quoted string from the given stream.
286 void read(std::istream& is, char& value) const {
289 if (!is.get(c) || c != '\'')
290 throw DataFormatError("Quoted format error");
292 throw DataFormatError("Quoted format error");
293 if (escaped && c == '\\') {
294 value = QuotedStringReader::readEscape(is);
298 if (!is.get(c) || c != '\'')
299 throw DataFormatError("Quoted format error");
307 /// \brief Reader for standard containers.
309 /// Reader for back insertable standard containers. The representation
310 /// of the container is the values enumerated between an open and a
313 /// \author Balazs Dezso
316 typename _ItemReader = DefaultReader<typename _Container::value_type>
318 class PushBackReader {
320 typedef _Container Value;
321 typedef _ItemReader ItemReader;
325 ItemReader item_reader;
329 /// \brief Constructor for InsertReader
331 /// Constructor for InsertReader
332 PushBackReader(const ItemReader& _item_reader = ItemReader())
333 : item_reader(_item_reader) {}
335 /// \brief Reads the values into the container from the given stream.
337 /// Reads the values into the container from the given stream.
338 void read(std::istream& is, Value& value) const {
340 if (!(is >> c) || c != '(')
341 throw DataFormatError("PushBackReader format error");
342 while (is >> c && c != ')') {
344 typename ItemReader::Value item;
345 item_reader.read(is, item);
346 value.push_back(item);
348 if (!is) throw DataFormatError("PushBackReader format error");
355 /// \brief Reader for standard containers.
357 /// Reader for insertable standard containers. The representation
358 /// of the container is the values enumerated between an open and a
361 /// \author Balazs Dezso
364 typename _ItemReader = DefaultReader<typename _Container::value_type>
368 typedef _Container Value;
369 typedef _ItemReader ItemReader;
373 ItemReader item_reader;
377 /// \brief Constructor for InsertReader
379 /// Constructor for InsertReader
380 InsertReader(const ItemReader& _item_reader = ItemReader())
381 : item_reader(_item_reader) {}
383 /// \brief Reads the values into the container from the given stream.
385 /// Reads the values into the container from the given stream.
386 void read(std::istream& is, Value& value) const {
388 if (!(is >> c) || c != '(')
389 throw DataFormatError("InsertReader format error");
390 while (is >> c && c != ')') {
392 typename ItemReader::Value item;
393 item_reader.read(is, item);
396 if (!is) throw DataFormatError("PushBackReader format error");
402 /// \brief Reader for parsed string.
404 /// Reader for parsed strings. You can define the open and close
405 /// parse characters. It reads from the input a character sequence
406 /// which is right parsed.
408 /// \author Balazs Dezso
409 class ParsedStringReader {
411 typedef std::string Value;
413 /// \brief Constructor.
415 /// Constructor for ParsedStringReader. You can give as parameter
416 /// the open and close parse characters.
417 ParsedStringReader(char _open = '(', char _close = ')')
418 : open(_open), close(_close) {}
421 /// \brief Reads the parsed string from the given stream.
423 /// Reads the parsed string from the given stream.
424 void read(std::istream& is, Value& value) const {
427 if (!(is >> c) || c != open) {
428 throw DataFormatError("ParsedStringReader format error");
432 while (counter > 0 && is >> c) {
435 } else if (c == open) {
441 throw DataFormatError("ParsedStrinReader format error");
451 /// \brief Reader for read the whole line.
453 /// Reader for read the whole line.
455 /// \author Balazs Dezso
458 typedef std::string Value;
460 /// \brief Constructor.
462 /// Constructor for the LineReader. If the given parameter is
463 /// true then the spaces before the first not space character are
465 LineReader(bool _skipSpaces = true) : skipSpaces(_skipSpaces) {}
467 /// \brief Reads the line from the given stream.
469 /// Reads the line from the given stream.
470 void read(std::istream& is, Value& value) const {
471 if (skipSpaces) is >> std::ws;
472 if (!getline(is, value)) {
473 throw DataFormatError("LineReader format error");
481 /// \brief Reader for std::pair.
483 /// Reader for std::pair.
485 /// \author Balazs Dezso
486 template <typename _Pair,
487 typename _FirstReader =
488 DefaultReader<typename _Pair::first_type>,
489 typename _SecondReader =
490 DefaultReader<typename _Pair::second_type> >
495 typedef _FirstReader FirstReader;
496 typedef _SecondReader SecondReader;
500 FirstReader first_reader;
501 SecondReader second_reader;
505 /// \brief Constructor.
507 /// Constructor for the PairReader.
508 PairReader(const FirstReader& _first_reader = FirstReader(),
509 const SecondReader& _second_reader = SecondReader())
510 : first_reader(_first_reader), second_reader(_second_reader) {}
512 /// \brief Reads the pair from the given stream.
514 /// Reads the pair from the given stream.
515 void read(std::istream& is, Value& value) const {
517 if (!(is >> c) || c != '(') {
518 throw DataFormatError("PairReader format error");
520 first_reader.read(is, value.first);
521 if (!(is >> c) || c != '=') {
522 throw DataFormatError("PairReader format error");
524 if (!(is >> c) || c != '>') {
525 throw DataFormatError("PairReader format error");
527 second_reader.read(is, value.second);
528 if (!(is >> c) || c != ')') {
529 throw DataFormatError("PairReader format error");
536 /// \brief The default item reader template class.
538 /// The default item reader template class. If some section reader
539 /// needs to read a value from a stream it will give the default way for it.
541 /// \author Balazs Dezso
542 template <typename _Value>
543 class DefaultReader {
546 typedef _Value Value;
547 /// \brief Reads a value from the given stream.
549 /// Reads a value from the given stream.
550 void read(std::istream& is, Value& value) const {
552 throw DataFormatError("DefaultReader format error");
557 class DefaultReader<std::string> {
559 typedef std::string Value;
561 void read(std::istream& is, Value& value) const {
563 if (!(is >> std::ws >> c))
564 throw DataFormatError("DefaultReader<string> format error");
568 QuotedStringReader().read(is, value);
571 UnformattedReader().read(is, value);
579 class DefaultReader<char> {
583 void read(std::istream& is, Value& value) const {
585 if (!(is >> std::ws >> c))
586 throw DataFormatError("DefaultReader<char> format error");
590 QuotedCharReader().read(is, value);
596 throw DataFormatError("DefaultReader<char> format error");
597 value = static_cast<char>(temp);
605 class DefaultReader<bool> {
609 void read(std::istream& is, Value& value) const {
612 throw DataFormatError("DefaultReader<bool> format error");
613 if (rep == "true" || rep == "t" || rep == "1") {
615 } else if (rep == "false" || rep == "f" || rep == "0") {
617 } else throw DataFormatError("DefaultReader<bool> format error");
621 template <typename Item>
622 class DefaultReader<std::vector<Item> >
623 : public PushBackReader<std::vector<Item> > {};
625 template <typename Item>
626 class DefaultReader<std::deque<Item> >
627 : public PushBackReader<std::deque<Item> > {};
629 template <typename Item>
630 class DefaultReader<std::list<Item> >
631 : public PushBackReader<std::list<Item> > {};
633 template <typename Item>
634 class DefaultReader<std::set<Item> >
635 : public InsertReader<std::set<Item> > {};
637 template <typename Key, typename Value>
638 class DefaultReader<std::map<Key, Value> >
639 : public InsertReader<std::map<Key, Value>,
640 DefaultReader<std::pair<Key, Value> > > {};
642 template <typename Item>
643 class DefaultReader<std::multiset<Item> >
644 : public InsertReader<std::multiset<Item> > {};
646 template <typename Key, typename Value>
647 class DefaultReader<std::multimap<Key, Value> >
648 : public InsertReader<std::multimap<Key, Value>,
649 DefaultReader<std::pair<Key, Value> > > {};
651 template <typename First, typename Second>
652 class DefaultReader<std::pair<First, Second> >
653 : public PairReader<std::pair<First, Second> > {};
657 /// \brief The default item reader for skipping a value in the stream.
659 /// The default item reader for skipping a value in the stream.
661 /// \author Balazs Dezso
662 class DefaultSkipper : public UnformattedReader {};
665 /// \brief Standard ReaderTraits for the GraphReader class.
667 /// Standard ReaderTraits for the GraphReader class.
668 /// It defines standard reading method for all type of value.
669 /// \author Balazs Dezso
670 struct DefaultReaderTraits {
672 template <typename _Value>
673 struct Reader : DefaultReader<_Value> {};
675 typedef DefaultSkipper Skipper;