1 // This is mul/mbl/mbl_parse_tuple.h
2 #ifndef mbl_parse_tuple_h_
3 #define mbl_parse_tuple_h_
4 //:
5 // \file
6 // \author Ian Scott
7 // \date  6-Feb-2008
8 // \brief Convenience function a tuple of PODs from a config file.
9 
10 #include <iostream>
11 #include <istream>
12 #include <sstream>
13 #ifdef _MSC_VER
14 #  include <vcl_msvc_warnings.h>
15 #endif
16 #include <mbl/mbl_exception.h>
17 
18 //: Read a 2-tuple of PODs from a config file.
19 // This function will read through a stream, and store the text found to a string.
20 // The function reads 2 elements. If there was an opening brace it will also consume the closing brace.
21 // Other conditions will cause an exception to be thrown, and the stream's fail bit to be set
22 //
23 // \throws mbl_exception_parse_error if unrecoverable parse error.
24 //
25 // Example:
26 // \code
27 //   std::istringstream ss("{ 1.0 4 }");
28 //   float a;
29 //   int b;
30 //   mbl_parse_tuple(ss, a, b)
31 // \endcode
32 //
33 template <class T, class U>
mbl_parse_tuple(std::istream & afs,T & a,U & b)34 inline void mbl_parse_tuple(std::istream &afs, T& a, U& b)
35 {
36   if (!afs) return;
37   char brace1, brace2;
38   afs >> std::ws >> brace1;
39   if (afs.eof())
40     throw mbl_exception_parse_error("mbl_parse_tuple failed unexpected eof");
41   if ( brace1 == '{')
42   {
43     afs >> std::ws >> a >> std::ws >> b >> std::ws >> brace2;
44     if (!afs)
45       throw mbl_exception_parse_error("mbl_parse_tuple failed with stream error");
46     if (brace2 != '}')
47     {
48       afs.putback(brace2);
49       afs.clear(std::ios::failbit); // Set a recoverable IO error on stream
50 
51       throw mbl_exception_parse_error("mbl_parse_tuple failed to find closing brace");
52     }
53   }
54   else
55   {
56     afs.putback(brace1);
57     afs >> std::ws >> a >> std::ws >> b;
58     if (!afs)
59       throw mbl_exception_parse_error("mbl_parse_tuple failed with stream error");
60   }
61 }
62 
63 //: Read a 3-tuple of PODs from a config file.
64 // This function will read through a stream, and store the text found to a string.
65 // The function reads 3 elements. If there was an opening brace it will also consume the closing brace.
66 // Other conditions will cause an exception to be thrown, and the stream's fail bit to be set
67 //
68 // \throws mbl_exception_parse_error if unrecoverable parse error.
69 //
70 // \verbatim
71 // Example:
72 // std::istringstream ss("{ 1.0 -5 4 }");
73 // float a;
74 // int b;
75 // unsigned c;
76 // mbl_parse_tuple(ss, a, b, c)
77 // \endverbatim
78 template <class T, class U, class V>
mbl_parse_tuple(std::istream & afs,T & a,U & b,V & c)79 inline void mbl_parse_tuple(std::istream &afs, T& a, U& b, V& c)
80 {
81   if (!afs) return;
82   char brace1, brace2;
83   afs >> std::ws >> brace1;
84   if (afs.eof())
85     throw mbl_exception_parse_error("mbl_parse_tuple failed unexpected eof");
86   if ( brace1 == '{')
87   {
88     afs >> std::ws >> a >> std::ws >> b >> std::ws >> c >> std::ws >> brace2;
89     if (!afs)
90       throw mbl_exception_parse_error("mbl_parse_tuple failed with stream error");
91     if (brace2 != '}')
92     {
93       afs.putback(brace2);
94       afs.clear(std::ios::failbit); // Set a recoverable IO error on stream
95 
96       throw mbl_exception_parse_error("mbl_parse_tuple failed to find closing brace");
97     }
98   }
99   else
100   {
101     afs.putback(brace1);
102     afs >> std::ws >> a >> std::ws >> b >> std::ws >> c;
103     if (!afs)
104       throw mbl_exception_parse_error("mbl_parse_tuple failed with stream error");
105   }
106 }
107 
108 
109 //: Read a 4-tuple of PODs from a config file.
110 // This function will read through a stream, and store the text found to a string.
111 // The function reads 4 elements. If there was an opening brace it will also consume the closing brace.
112 // Other conditions will cause an exception to be thrown, and the stream's fail bit to be set
113 //
114 // \throws mbl_exception_parse_error if unrecoverable parse error.
115 //
116 // \verbatim
117 // Example:
118 // std::istringstream ss("{ 1.0 -5 4 a }");
119 // float a;
120 // int b;
121 // unsigned c;
122 // char d;
123 // mbl_parse_tuple(ss, a, b, c, d)
124 // \endverbatim
125 template <class T, class U, class V, class W>
mbl_parse_tuple(std::istream & afs,T & a,U & b,V & c,W & d)126 inline void mbl_parse_tuple(std::istream &afs, T& a, U& b, V& c, W& d)
127 {
128   if (!afs) return;
129   char brace1, brace2;
130   afs >> std::ws >> brace1;
131   if (afs.eof())
132     throw mbl_exception_parse_error("mbl_parse_tuple failed unexpected eof");
133   if ( brace1 == '{')
134   {
135     afs >> std::ws >> a >> std::ws >> b >> std::ws >> c >> std::ws >> d >> std::ws >> brace2;
136     if (!afs)
137       throw mbl_exception_parse_error("mbl_parse_tuple failed with stream error");
138     if (brace2 != '}')
139     {
140       afs.putback(brace2);
141       afs.clear(std::ios::failbit); // Set a recoverable IO error on stream
142 
143       throw mbl_exception_parse_error("mbl_parse_tuple failed to find closing brace");
144     }
145   }
146   else
147   {
148     afs.putback(brace1);
149     afs >> std::ws >> a >> std::ws >> b >> std::ws >> c >> std::ws >> d;
150     if (!afs)
151       throw mbl_exception_parse_error("mbl_parse_tuple failed with stream error");
152   }
153 }
154 
155 
156 //: Read a 5-tuple of PODs from a config file.
157 // This function will read through a stream, and store the text found to a string.
158 // The function reads 5 elements. If there was an opening brace it will also consume the closing brace.
159 // Other conditions will cause an exception to be thrown, and the stream's fail bit to be set
160 //
161 // \throws mbl_exception_parse_error if unrecoverable parse error.
162 //
163 // \verbatim
164 // Example:
165 // std::istringstream ss("{ 1.0 -5 4 k l }");
166 // float a;
167 // int b;
168 // unsigned c;
169 // char d, e;
170 // mbl_parse_tuple(ss, a, b, c, d, e)
171 // \endverbatim
172 template <class T, class U, class V, class W, class X>
mbl_parse_tuple(std::istream & afs,T & a,U & b,V & c,W & d,X & e)173 inline void mbl_parse_tuple(std::istream &afs, T& a, U& b, V& c, W& d, X& e)
174 {
175   if (!afs) return;
176   char brace1, brace2;
177   afs >> std::ws >> brace1;
178   if (afs.eof())
179     throw mbl_exception_parse_error("mbl_parse_tuple failed unexpected eof");
180   if ( brace1 == '{')
181   {
182     afs >> std::ws >> a >> std::ws >> b >> std::ws >> c >> std::ws >> d >> std::ws >> e >> std::ws >> brace2;
183     if (!afs)
184       throw mbl_exception_parse_error("mbl_parse_tuple failed with stream error");
185     if (brace2 != '}')
186     {
187       afs.putback(brace2);
188       afs.clear(std::ios::failbit); // Set a recoverable IO error on stream
189 
190       throw mbl_exception_parse_error("mbl_parse_tuple failed to find closing brace");
191     }
192   }
193   else
194   {
195     afs.putback(brace1);
196     afs >> std::ws >> a >> std::ws >> b >> std::ws >> c >> std::ws >> d >> std::ws >> e;
197     if (!afs)
198       throw mbl_exception_parse_error("mbl_parse_tuple failed with stream error");
199   }
200 }
201 
202 
203 //: Read a 6-tuple of PODs from a config file.
204 // This function will read through a stream, and store the text found to a string.
205 // The function reads 6 elements. If there was an opening brace it will also consume the closing brace.
206 // Other conditions will cause an exception to be thrown, and the stream's fail bit to be set
207 //
208 // \throws mbl_exception_parse_error if unrecoverable parse error.
209 //
210 // \verbatim
211 // Example:
212 // std::istringstream ss("{ 1.0 -3.4 -5 4 k l }");
213 // float a;
214 // double b;
215 // int c;
216 // unsigned d;
217 // char e, f;
218 // mbl_parse_tuple(ss, a, b, c, d, e, f)
219 // \endverbatim
220 template <class T, class U, class V, class W, class X, class Y>
mbl_parse_tuple(std::istream & afs,T & a,U & b,V & c,W & d,X & e,Y & f)221 inline void mbl_parse_tuple(std::istream &afs, T& a, U& b, V& c, W& d, X& e, Y& f)
222 {
223   if (!afs) return;
224   char brace1, brace2;
225   afs >> std::ws >> brace1;
226   if (afs.eof())
227     throw mbl_exception_parse_error("mbl_parse_tuple failed unexpected eof");
228   if ( brace1 == '{')
229   {
230     afs >> std::ws >> a >> std::ws >> b >> std::ws >> c >> std::ws >> d >> std::ws >>
231       e >> std::ws >> f >> std::ws >> brace2;
232     if (!afs)
233       throw mbl_exception_parse_error("mbl_parse_tuple failed with stream error");
234     if (brace2 != '}')
235     {
236       afs.putback(brace2);
237       afs.clear(std::ios::failbit); // Set a recoverable IO error on stream
238 
239       throw mbl_exception_parse_error("mbl_parse_tuple failed to find closing brace");
240     }
241   }
242   else
243   {
244     afs.putback(brace1);
245     afs >> std::ws >> a >> std::ws >> b >> std::ws >> c >> std::ws >> d >>
246       std::ws >> e >> std::ws >> f;
247     if (!afs)
248       throw mbl_exception_parse_error("mbl_parse_tuple failed with stream error");
249   }
250 }
251 #endif // mbl_parse_tuple_h_
252