1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
|
// This is mul/mbl/mbl_parse_sequence.h
#ifndef mbl_parse_sequence_h_
#define mbl_parse_sequence_h_
//:
// \file
// \author Ian Scott
// \date 7-Aug-2007
// \brief Load a sequence of PODs/objects from a config file.
#include <vcl_algorithm.h>
#include <vcl_istream.h>
#include <vcl_iterator.h>
#include <mbl/mbl_exception.h>
//: Read a sequence of PODs from a stream.
// This function will read through a stream, and store the text found to a string.
// The function terminates correctly when it finds a matched closing brace,
// Alternatively, if there was no opening brace, it will terminate at the end of a stream.
// Other conditions will cause an exception to be thrown, and the stream's fail bit to be set
//
// \throws mbl_exception_parse_error if unrecoverable parse error.
//
// \verbatim
// Example:
// vcl_vector<unsigned> v;
// mbl_parse_sequence(vcl_cin, vcl_back_inserter(v), unsigned());
// \endverbatim
template <class ITER, class T>
inline void mbl_parse_sequence(vcl_istream &afs, ITER insert_iter, T /*dummy*/)
{
// Can't use iterator_traits<ITER>::value_type to infer T,
// because output_iterators may not have a useful value_type
// and are defined by the standard to have value_type void,
// See http://www.adras.com/Why-no-std-back-insert-iterator-value-type.t2639-153.html
if (!afs) return;
char brace1, brace2;
afs >> vcl_ws >> brace1;
if (afs.eof()) return;
if ( brace1 == '{')
{
vcl_copy(vcl_istream_iterator<T>(afs),
vcl_istream_iterator<T>(), insert_iter);
if (afs.fail())
afs.clear();
afs >> vcl_ws >> brace2;
if (!afs || brace2 != '}')
{
afs.putback(brace2);
afs.clear(vcl_ios::failbit); // Set a recoverable IO error on stream
throw mbl_exception_parse_error(
"mbl_parse_sequence failed to find closing brace.");
}
}
else
{
afs.putback(brace1);
vcl_copy(vcl_istream_iterator<T>(afs),
vcl_istream_iterator<T>(), insert_iter);
if (afs.fail())
afs.clear();
char c;
afs >> c;
if (!(!afs))
{
afs.putback(c);
afs.clear(vcl_ios::failbit);
throw mbl_exception_parse_error(
"mbl_parse_sequence failed to find EOF.");
}
afs.clear(vcl_ios::eofbit);
}
}
#endif // mbl_parse_sequence_h_
|