New graph reader interface.
2 * src/lemon/bits/item_reader.h - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Research Group on Combinatorial Optimization, EGRES).
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
19 /// \brief Item reader bits for lemon input.
21 #ifndef LEMON_BITS_ITEM_READER_H
22 #define LEMON_BITS_ITEM_READER_H
34 template <typename Value>
39 /// \brief Reader class for quoted strings.
41 /// Reader class for quoted strings. It can process the escape
42 /// sequences in the string.
44 /// \author Balazs Dezso
45 class QuotedStringReader {
47 /// \brief The value type of reader.
49 /// The value type of reader.
50 typedef std::string Value;
52 /// \brief Constructor for the reader.
54 /// Constructor for the reader. If the given parameter is true
55 /// the reader processes the escape sequences.
56 QuotedStringReader(bool _escaped = true)
57 : escaped(_escaped) {}
59 /// \brief Reads a quoted string from the given stream.
61 /// Reads a quoted string from the given stream.
62 void read(std::istream& is, std::string& value) const {
66 if (!is.get(c) || c != '\"')
67 throw DataFormatError("Quoted string format error");
68 while (is.get(c) && c != '\"') {
69 if (escaped && c == '\\') {
70 value += readEscape(is);
75 if (!is) throw DataFormatError("Quoted string format error");
80 static char readEscape(std::istream& is) {
82 switch (is.get(c), c) {
108 if (!is.get(c) || !isHex(c))
109 throw DataFormatError("Escape format error");
110 else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
111 else code = code * 16 + valueHex(c);
118 throw DataFormatError("Escape format error");
119 else if (code = valueOct(c), !is.get(c) || !isOct(c))
121 else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c))
123 else code = code * 8 + valueOct(c);
129 static bool isOct(char c) {
130 return '0' <= c && c <='7';
133 static int valueOct(char c) {
137 static bool isHex(char c) {
138 return ('0' <= c && c <= '9') ||
139 ('a' <= c && c <= 'z') ||
140 ('A' <= c && c <= 'Z');
143 static int valueHex(char c) {
144 if ('0' <= c && c <= '9') return c - '0';
145 if ('a' <= c && c <= 'z') return c - 'a' + 10;
152 /// \ingroup io_group
153 /// \brief Reader for standard containers.
155 /// Reader for back insertable standard containers. The representation
156 /// of the container is the values enumerated between an open and a
159 /// \author Balazs Dezso
162 typename _ItemReader = DefaultReader<typename _Container::value_type>
164 class PushBackReader {
166 typedef _Container Value;
167 typedef _ItemReader ItemReader;
171 ItemReader item_reader;
175 /// \brief Reads the values into the container from the given stream.
177 /// Reads the values into the container from the given stream.
178 void read(std::istream& is, Value& value) const {
180 if (!(is >> c) || c != '(')
181 throw DataFormatError("PushBackReader format error");
182 while (is >> c && c != ')') {
184 typename ItemReader::Value item;
185 item_reader.read(is, item);
186 value.push_back(item);
188 if (!is) throw DataFormatError("PushBackReader format error");
194 /// \ingroup io_group
196 /// \brief Reader for standard containers.
198 /// Reader for insertable standard containers. The representation
199 /// of the container is the values enumerated between an open and a
202 /// \author Balazs Dezso
205 typename _ItemReader = DefaultReader<typename _Container::value_type>
209 typedef _Container Value;
210 typedef _ItemReader ItemReader;
214 ItemReader item_reader;
218 /// \brief Reads the values into the container from the given stream.
220 /// Reads the values into the container from the given stream.
221 void read(std::istream& is, Value& value) const {
223 if (!(is >> c) || c != '(')
224 throw DataFormatError("InsertReader format error");
225 while (is >> c && c != ')') {
227 typename ItemReader::Value item;
228 item_reader.read(is, item);
231 if (!is) throw DataFormatError("PushBackReader format error");
237 /// \ingroup io_group
238 /// \brief Reader for parsed string.
240 /// Reader for parsed strings. You can give the open and close
241 /// parse characters.
243 /// \author Balazs Dezso
244 class ParsedStringReader {
246 typedef std::string Value;
248 /// \brief Constructor.
250 /// Constructor for ParsedStringReader. You can give as parameter
251 /// the open and close parse characters.
252 ParsedStringReader(char _open = '(', char _close = ')')
253 : open(_open), close(_close) {}
256 /// \brief Reads the parsed string from the given stream.
258 /// Reads the parsed string from the given stream.
259 void read(std::istream& is, Value& value) const {
261 if (!(is >> c) || c != open) {
262 throw DataFormatError("ParsedStringReader format error");
266 while (counter > 0 && is >> c) {
269 } else if (c == open) {
275 throw DataFormatError("ParsedStrinReader format error");
284 /// \ingroup io_group
285 /// \brief Reader for read the whole line.
287 /// Reader for read the whole line.
289 /// \author Balazs Dezso
292 typedef std::string Value;
294 /// \brief Constructor.
296 /// Constructor for the LineReader. If the given parameter is
297 /// true then the spaces before the first not space character are
299 LineReader(bool _skipSpaces = true) : skipSpaces(_skipSpaces) {}
301 /// \brief Reads the line from the given stream.
303 /// Reads the line from the given stream.
304 void read(std::istream& is, Value& value) {
305 if (skipSpaces) is >> std::ws;
306 if (!getline(is, value)) {
307 throw DataFormatError("LineReader forma error");
314 /// \ingroup io_group
316 /// \brief The default item reader template class.
318 /// The default item reader template class. If some section reader
319 /// needs to read a value from a stream it will give the default way for it.
321 /// \author Balazs Dezso
322 template <typename _Value>
323 class DefaultReader {
326 typedef _Value Value;
327 /// \brief Reads a value from the given stream.
329 /// Reads a value from the given stream.
330 void read(std::istream& is, Value& value) const {
332 throw DataFormatError("DefaultReader format error");
336 template <typename Item>
337 class DefaultReader<std::vector<Item> >
338 : public PushBackReader<std::vector<Item> > {};
340 template <typename Item>
341 class DefaultReader<std::deque<Item> >
342 : public PushBackReader<std::deque<Item> > {};
344 template <typename Item>
345 class DefaultReader<std::list<Item> >
346 : public PushBackReader<std::list<Item> > {};
348 template <typename Item>
349 class DefaultReader<std::set<Item> >
350 : public InsertReader<std::set<Item> > {};
352 template <typename Item>
353 class DefaultReader<std::multiset<Item> >
354 : public InsertReader<std::multiset<Item> > {};
356 /// \ingroup io_group
357 class DefaultSkipper {
359 typedef std::string Value;
361 void read(std::istream& is, Value& value) const {
363 if (!(is >> c)) return;
367 QuotedStringReader().read(is, value);
370 ParsedStringReader().read(is, value);
373 DefaultReader<std::string>().read(is, value);
379 /// \brief Standard ReaderTraits for the GraphReader class.
381 /// Standard ReaderTraits for the GraphReader class.
382 /// It defines standard reading method for all type of value.
383 /// \author Balazs Dezso
384 struct DefaultReaderTraits {
386 template <typename _Value>
387 struct Reader : DefaultReader<_Value> {};
389 typedef DefaultSkipper Skipper;