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 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
// This is mul/mbl/mbl_parse_int_list.h
#ifndef mbl_parse_int_list_h_
#define mbl_parse_int_list_h_
//:
// \file
// \author Ian Scott
// \date 7-Aug-2007
// \brief Load an int_list of PODs/objects from a config file.
#include <mbl/mbl_exception.h>
#include <vcl_istream.h>
#include <vcl_cctype.h>
//: Read a list of integers from a stream.
// This integer list should be space-separated.
// Lists of the form "{ 1 2 5 : 10 }" a la matlab are accepted. Note that "a : b"
// will include b rather than following normal C++ convention.
// Failed parsing 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_int_list(vcl_cin, vcl_back_inserter(v), unsigned());
// \endverbatim
template <class ITER, class T>
inline void mbl_parse_int_list(vcl_istream &afs, ITER insert_iter, T)
{
if (!afs) return;
char c;
afs >> vcl_ws >> c;
if (!afs) return;
bool openbrace = false;
if (c == '{')
openbrace = true;
else
afs.putback(c);
while (true)
{
char c;
afs >> vcl_ws >> c;
if (afs.eof() || (c =='}' && openbrace))
{
afs.clear();
return;
}
else if (!afs)
{
afs.clear(vcl_ios::failbit);
mbl_exception_warning(mbl_exception_parse_error(
"mbl_parse_int_list: Unknown stream failure") );
return;
}
else if (! (vcl_isdigit(c) || c== '-') )
{
afs.clear(vcl_ios::failbit);
mbl_exception_warning(mbl_exception_parse_error(
vcl_string("mbl_parse_int_list: unexpected character '") + c + "'") );
return;
}
afs.putback(c);
T current;
afs >> current >> vcl_ws >> c;
if (afs.eof() && openbrace)
{
afs.clear(vcl_ios::failbit);
mbl_exception_warning(mbl_exception_parse_error(
"mbl_parse_int_list: unexpected EOF" ) );
return;
}
if (afs.eof() || (c =='}' && openbrace) )
{
*insert_iter++ = current;
afs.clear();
return;
}
else if (!afs)
{
mbl_exception_warning(mbl_exception_parse_error(
"mbl_parse_int_list: non-integer detected") );
return;
}
else if (vcl_isdigit(c) || c== '-')
{
afs.putback(c);
*insert_iter++ = current;
continue;
}
else if (c!=':')
{
afs.clear(vcl_ios::failbit);
mbl_exception_warning(mbl_exception_parse_error(
vcl_string("mbl_parse_int_list: unexpected character '") + c + "'") );
return;
}
else
{
T last;
afs >> vcl_ws >> last;
if (afs.eof())
{
mbl_exception_warning(mbl_exception_parse_error(
"mbl_parse_int_list: unexpected EOF") );
return;
}
if (!afs)
{
mbl_exception_warning(mbl_exception_parse_error(
"mbl_parse_int_list: Unknown stream error") );
return;
}
if (current > last)
{
// Count down to last
// Note: Do in two steps to avoid -- problems when last==0
while (current > last)
*insert_iter++ = current--;
*insert_iter++ = last;
#if 0
afs.clear(vcl_ios::failbit);
mbl_exception_warning(mbl_exception_parse_error(
vcl_string("mbl_parse_int_list: unbounded sequence") ));
return;
#endif
}
else
{
// Count up to last
while (current <= last)
*insert_iter++ = current++;
}
}
}
}
#endif // mbl_parse_int_list_h_
|