libshevek
|
00001 /* iostring.hh - Read and write strings in parts. 00002 * Copyright 2007-2008 Bas Wijnen <wijnen@debian.org> 00003 * 00004 * This program is free software: you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation, either version 3 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00016 */ 00017 00018 #ifndef SHEVEK_IOSTRING_HH 00019 #define SHEVEK_IOSTRING_HH 00020 00021 #include <string> 00022 #include <stack> 00023 #include <sstream> 00024 #include <glibmm.h> 00025 00026 namespace shevek 00027 { 00029 00032 class istring 00033 { 00034 // The data to parse. 00035 Glib::ustring data; 00036 // Pointer to data still to be parsed. 00037 std::stack <Glib::ustring::size_type> pos; 00038 00039 // Read a variable. 00040 template <typename T> 00041 bool read_var (Glib::ustring const &format, T &ret, Glib::ustring::size_type &inpos); 00042 00043 // Read away whitespace. 00044 void del_whitespace (); 00045 00046 // Check for a constant. 00047 bool read_const (Glib::ustring const &format, Glib::ustring::size_type &inpos); 00048 public: 00049 // Constructors: fill data and make one stack level. 00051 istring () { pos.push (0); } 00053 istring (Glib::ustring const &str) { init (str); } 00055 void init (Glib::ustring const &str) 00056 { data = str; while (!pos.empty ()) pos.pop (); pos.push (0); } 00057 00058 // Stack functions. 00060 void push () { pos.push (pos.top ()); } 00062 00065 int pop (bool keep = false); 00067 void reset () { pos.top () = 0; } 00068 00070 Glib::ustring rest () const { return data.substr (pos.top ()); } 00071 00073 void skip (Glib::ustring::size_type p) { pos.top () += p; } 00074 00076 bool operator() (Glib::ustring const &format) 00077 { 00078 push (); 00079 Glib::ustring::size_type inpos = 0; 00080 bool ret = read_const (format, inpos) 00081 && inpos == format.size (); 00082 pop (ret); 00083 return ret; 00084 } 00085 00087 template <typename T1> 00088 bool operator() (Glib::ustring const &format, T1 &arg1) 00089 { 00090 push (); 00091 Glib::ustring::size_type inpos = 0; 00092 bool ret = read_const (format, inpos) 00093 && read_var (format, arg1, inpos) 00094 && read_const (format, inpos) 00095 && inpos == format.size (); 00096 pop (ret); 00097 return ret; 00098 } 00099 00101 template <typename T1, typename T2> 00102 bool operator() (Glib::ustring const &format, T1 &arg1, 00103 T2 &arg2) 00104 { 00105 push (); 00106 Glib::ustring::size_type inpos = 0; 00107 bool ret = read_const (format, inpos) 00108 && read_var (format, arg1, inpos) 00109 && read_const (format, inpos) 00110 && read_var (format, arg2, inpos) 00111 && read_const (format, inpos) 00112 && inpos == format.size (); 00113 pop (ret); 00114 return ret; 00115 } 00116 00118 template <typename T1, typename T2, typename T3> 00119 bool operator() (Glib::ustring const &format, T1 &arg1, 00120 T2 &arg2, T3 &arg3) 00121 { 00122 push (); 00123 Glib::ustring::size_type inpos = 0; 00124 bool ret = read_const (format, inpos) 00125 && read_var (format, arg1, inpos) 00126 && read_const (format, inpos) 00127 && read_var (format, arg2, inpos) 00128 && read_const (format, inpos) 00129 && read_var (format, arg3, inpos) 00130 && read_const (format, inpos) 00131 && inpos == format.size (); 00132 pop (ret); 00133 return ret; 00134 } 00135 00137 template <typename T1, typename T2, typename T3, typename T4> 00138 bool operator() (Glib::ustring const &format, T1 &arg1, 00139 T2 &arg2, T3 &arg3, T4 &arg4) 00140 { 00141 push (); 00142 Glib::ustring::size_type inpos = 0; 00143 bool ret = read_const (format, inpos) 00144 && read_var (format, arg1, inpos) 00145 && read_const (format, inpos) 00146 && read_var (format, arg2, inpos) 00147 && read_const (format, inpos) 00148 && read_var (format, arg3, inpos) 00149 && read_const (format, inpos) 00150 && read_var (format, arg4, inpos) 00151 && read_const (format, inpos) 00152 && inpos == format.size (); 00153 pop (ret); 00154 return ret; 00155 } 00156 00158 template <typename T1, typename T2, typename T3, typename T4, 00159 typename T5> 00160 bool operator() (Glib::ustring const &format, T1 &arg1, 00161 T2 &arg2, T3 &arg3, T4 &arg4, T5 &arg5) 00162 { 00163 push (); 00164 Glib::ustring::size_type inpos = 0; 00165 bool ret = read_const (format, inpos) 00166 && read_var (format, arg1, inpos) 00167 && read_const (format, inpos) 00168 && read_var (format, arg2, inpos) 00169 && read_const (format, inpos) 00170 && read_var (format, arg3, inpos) 00171 && read_const (format, inpos) 00172 && read_var (format, arg4, inpos) 00173 && read_const (format, inpos) 00174 && read_var (format, arg5, inpos) 00175 && read_const (format, inpos) 00176 && inpos == format.size (); 00177 pop (ret); 00178 return ret; 00179 } 00180 00182 template <typename T1, typename T2, typename T3, typename T4, 00183 typename T5, typename T6> 00184 bool operator() (Glib::ustring const &format, T1 &arg1, 00185 T2 &arg2, T3 &arg3, T4 &arg4, T5 &arg5, 00186 T6 &arg6) 00187 { 00188 push (); 00189 Glib::ustring::size_type inpos = 0; 00190 bool ret = read_const (format, inpos) 00191 && read_var (format, arg1, inpos) 00192 && read_const (format, inpos) 00193 && read_var (format, arg2, inpos) 00194 && read_const (format, inpos) 00195 && read_var (format, arg3, inpos) 00196 && read_const (format, inpos) 00197 && read_var (format, arg4, inpos) 00198 && read_const (format, inpos) 00199 && read_var (format, arg5, inpos) 00200 && read_const (format, inpos) 00201 && read_var (format, arg6, inpos) 00202 && read_const (format, inpos) 00203 && inpos == format.size (); 00204 pop (ret); 00205 return ret; 00206 } 00207 00209 template <typename T1, typename T2, typename T3, typename T4, 00210 typename T5, typename T6, typename T7> 00211 bool operator() (Glib::ustring const &format, T1 &arg1, 00212 T2 &arg2, T3 &arg3, T4 &arg4, T5 &arg5, 00213 T6 &arg6, T7 &arg7) 00214 { 00215 push (); 00216 Glib::ustring::size_type inpos = 0; 00217 bool ret = read_const (format, inpos) 00218 && read_var (format, arg1, inpos) 00219 && read_const (format, inpos) 00220 && read_var (format, arg2, inpos) 00221 && read_const (format, inpos) 00222 && read_var (format, arg3, inpos) 00223 && read_const (format, inpos) 00224 && read_var (format, arg4, inpos) 00225 && read_const (format, inpos) 00226 && read_var (format, arg5, inpos) 00227 && read_const (format, inpos) 00228 && read_var (format, arg6, inpos) 00229 && read_const (format, inpos) 00230 && read_var (format, arg7, inpos) 00231 && read_const (format, inpos) 00232 && inpos == format.size (); 00233 pop (ret); 00234 return ret; 00235 } 00236 00238 template <typename T1, typename T2, typename T3, typename T4, 00239 typename T5, typename T6, typename T7, typename T8> 00240 bool operator() (Glib::ustring const &format, T1 &arg1, 00241 T2 &arg2, T3 &arg3, T4 &arg4, T5 &arg5, 00242 T6 &arg6, T7 &arg7, T8 &arg8) 00243 { 00244 push (); 00245 Glib::ustring::size_type inpos = 0; 00246 bool ret = read_const (format, inpos) 00247 && read_var (format, arg1, inpos) 00248 && read_const (format, inpos) 00249 && read_var (format, arg2, inpos) 00250 && read_const (format, inpos) 00251 && read_var (format, arg3, inpos) 00252 && read_const (format, inpos) 00253 && read_var (format, arg4, inpos) 00254 && read_const (format, inpos) 00255 && read_var (format, arg5, inpos) 00256 && read_const (format, inpos) 00257 && read_var (format, arg6, inpos) 00258 && read_const (format, inpos) 00259 && read_var (format, arg7, inpos) 00260 && read_const (format, inpos) 00261 && read_var (format, arg8, inpos) 00262 && read_const (format, inpos) 00263 && inpos == format.size (); 00264 pop (ret); 00265 return ret; 00266 } 00267 00269 00272 template <typename T> 00273 static T direct (Glib::ustring const &data, 00274 Glib::ustring const &format, 00275 T def = T ()) 00276 { 00277 T ret; 00278 istring tmp (data); 00279 if (!tmp (format, ret)) 00280 ret = def; 00281 return ret; 00282 } 00283 }; 00284 00286 00289 template <typename T> 00290 bool istring::read_var (Glib::ustring const &format, T &ret, 00291 Glib::ustring::size_type &inpos) 00292 { 00293 ++inpos; 00294 std::istringstream s (data.substr (pos.top ())); 00295 s >> ret; 00296 std::streampos p = s.tellg (); 00297 if (!s || p < 0) 00298 return false; 00299 pos.top () += p; 00300 return true; 00301 } 00302 00304 template <> bool istring::read_var <double> (Glib::ustring const &format, double &ret, Glib::ustring::size_type &inpos); 00305 00307 template <> bool istring::read_var <float> (Glib::ustring const &format, float &ret, Glib::ustring::size_type &inpos); 00308 00310 template <> bool istring::read_var <Glib::ustring> (Glib::ustring const &format, Glib::ustring &ret, Glib::ustring::size_type &inpos); 00311 00313 template <> bool istring::read_var <int> (Glib::ustring const &format, int &ret, Glib::ustring::size_type &inpos); 00314 00316 template <> bool istring::read_var <unsigned> (Glib::ustring const &format, unsigned &ret, Glib::ustring::size_type &inpos); 00317 00319 00322 class ostring 00323 { 00324 Glib::ustring data; 00325 Glib::ustring format; 00326 Glib::ustring::size_type pos; 00327 void write_const (); 00328 template <typename T> void write_var (T const &a, 00329 Glib::ustring const &flags, 00330 unsigned width, unsigned precision); 00331 template <typename T> void write_var_raw (T const &a); 00332 ostring &init (Glib::ustring const &f); 00333 // If you get a linker error to this line, you have tried to insert a std::string into a shevek::ostring. 00334 // Fix the program by turning it into a Glib::ustring first, or by using a shevek::rostring instead. 00335 template <typename T> ostring &operator ()(T const &a) { write_const (); write_var_raw (a); return *this; } 00336 ostring &operator ()(); 00337 public: 00339 operator Glib::ustring () const { return data; } 00341 Glib::ustring operator+ (Glib::ustring const &that) const { return data + that; } 00343 friend std::ostream &operator<< (std::ostream &s, ostring const &o) { return s << o.data; } 00345 ostring (Glib::ustring const &fmt) { init (fmt)(); } 00347 template <typename T1> 00348 ostring (Glib::ustring const &fmt, T1 const &a1) 00349 { init (fmt)(a1)(); } 00351 template <typename T1, typename T2> 00352 ostring (Glib::ustring const &fmt, T1 const &a1, T2 const &a2) 00353 { init (fmt)(a1)(a2)(); } 00355 template <typename T1, typename T2, typename T3> 00356 ostring (Glib::ustring const &fmt, T1 const &a1, T2 const &a2, 00357 T3 const &a3) 00358 { init (fmt)(a1)(a2)(a3)(); } 00360 template <typename T1, typename T2, typename T3, typename T4> 00361 ostring (Glib::ustring const &fmt, T1 const &a1, T2 const &a2, 00362 T3 const &a3, T4 const &a4) 00363 { init (fmt)(a1)(a2)(a3)(a4)(); } 00365 template <typename T1, typename T2, typename T3, typename T4, 00366 typename T5> 00367 ostring (Glib::ustring const &fmt, T1 const &a1, T2 const &a2, 00368 T3 const &a3, T4 const &a4, T5 const &a5) 00369 { init (fmt)(a1)(a2)(a3)(a4)(a5)(); } 00371 template <typename T1, typename T2, typename T3, typename T4, 00372 typename T5, typename T6> 00373 ostring (Glib::ustring const &fmt, T1 const &a1, T2 const &a2, 00374 T3 const &a3, T4 const &a4, T5 const &a5, 00375 T6 const &a6) 00376 { init (fmt)(a1)(a2)(a3)(a4)(a5)(a6)(); } 00378 template <typename T1, typename T2, typename T3, typename T4, 00379 typename T5, typename T6, typename T7> 00380 ostring (Glib::ustring const &fmt, T1 const &a1, T2 const &a2, 00381 T3 const &a3, T4 const &a4, T5 const &a5, 00382 T6 const &a6, T7 const &a7) 00383 { init (fmt)(a1)(a2)(a3)(a4)(a5)(a6)(a7)(); } 00385 template <typename T1, typename T2, typename T3, typename T4, 00386 typename T5, typename T6, typename T7 ,typename T8> 00387 ostring (Glib::ustring const &fmt, T1 const &a1, T2 const &a2, 00388 T3 const &a3, T4 const &a4, T5 const &a5, 00389 T6 const &a6, T7 const &a7, T8 const &a8) 00390 { init (fmt)(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(); } 00392 template <typename T1, typename T2, typename T3, typename T4, 00393 typename T5, typename T6, typename T7 ,typename T8, 00394 typename T9> 00395 ostring (Glib::ustring const &fmt, T1 const &a1, T2 const &a2, 00396 T3 const &a3, T4 const &a4, T5 const &a5, 00397 T6 const &a6, T7 const &a7, T8 const &a8, 00398 T9 const &a9) 00399 { init (fmt)(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(a9)(); } 00400 }; 00401 00403 00405 template <typename T> void ostring::write_var_raw (T const &a) 00406 { 00407 unsigned width = 0, precision = 0; 00408 Glib::ustring flags; 00409 while (pos < format.size () 00410 && (format[pos] < 'a' || format[pos] > 'z') 00411 && (format[pos] < 'A' || format[pos] > 'Z') 00412 && (format[pos] < '1' || format[pos] > '9')) 00413 flags += format[pos++]; 00414 while (pos < format.size () && format[pos] >= '0' 00415 && format[pos] <= '9') 00416 { 00417 width *= 10; 00418 width += format[pos++] - '0'; 00419 } 00420 if (pos < format.size () && format[pos] == '.') 00421 { 00422 ++pos; 00423 while (pos < format.size () && format[pos] >= '0' 00424 && format[pos] <= '9') 00425 { 00426 precision *= 10; 00427 precision += format[pos++] - '0'; 00428 } 00429 } 00430 return write_var (a, flags, width, precision); 00431 } 00432 00434 00436 template <typename T> void ostring::write_var (T const &a, 00437 Glib::ustring const &flags, 00438 unsigned width, unsigned precision) 00439 { 00440 (void)flags; 00441 (void)width; 00442 (void)precision; 00443 if (pos < format.size ()) 00444 ++pos; 00445 std::ostringstream s; 00446 s << a; 00447 data += s.str (); 00448 } 00449 00451 template <> void ostring::write_var <unsigned short> (unsigned short const &a, Glib::ustring const &flags, unsigned width, unsigned precision); 00453 template <> void ostring::write_var <short> (short const &a, Glib::ustring const &flags, unsigned width, unsigned precision); 00455 template <> void ostring::write_var <unsigned> (unsigned const &a, Glib::ustring const &flags, unsigned width, unsigned precision); 00457 template <> void ostring::write_var <int> (int const &a, Glib::ustring const &flags, unsigned width, unsigned precision); 00459 template <> void ostring::write_var <Glib::ustring> (Glib::ustring const &a, Glib::ustring const &flags, unsigned width, unsigned precision); 00460 00462 00465 template <> void ostring::write_var_raw <std::string> (std::string const &a); 00466 template <> bool istring::read_var <std::string> (Glib::ustring const &format, std::string &ret, Glib::ustring::size_type &inpos); 00467 00469 class ristring 00470 { 00471 // The data to parse. 00472 std::string data; 00473 // Pointer to data still to be parsed. 00474 std::stack <std::string::size_type> pos; 00475 00476 // Read a variable. 00477 template <typename T> 00478 bool read_var (std::string const &format, T &ret, std::string::size_type &inpos); 00479 00480 // Read away whitespace. 00481 void del_whitespace (); 00482 00483 // Check for a constant. 00484 bool read_const (std::string const &format, std::string::size_type &inpos); 00485 public: 00486 // Constructors: fill data and make one stack level. 00488 ristring () { pos.push (0); } 00490 ristring (std::string const &str) { init (str); } 00492 void init (std::string const &str) { data = str; while (!pos.empty ()) pos.pop (); pos.push (0); } 00493 00494 // Stack functions. 00496 void push () { pos.push (pos.top ()); } 00498 00501 int pop (bool keep = false); 00503 void reset () { pos.top () = 0; } 00504 00506 std::string rest () const { return data.substr (pos.top ()); } 00507 00509 void skip (std::string::size_type p) { pos.top () += p; } 00510 00512 bool operator() (std::string const &format) 00513 { 00514 push (); 00515 std::string::size_type inpos = 0; 00516 bool ret = read_const (format, inpos) 00517 && inpos == format.size (); 00518 pop (ret); 00519 return ret; 00520 } 00521 00523 template <typename T1> 00524 bool operator() (std::string const &format, T1 &arg1) 00525 { 00526 push (); 00527 std::string::size_type inpos = 0; 00528 bool ret = read_const (format, inpos) 00529 && read_var (format, arg1, inpos) 00530 && read_const (format, inpos) 00531 && inpos == format.size (); 00532 pop (ret); 00533 return ret; 00534 } 00535 00537 template <typename T1, typename T2> 00538 bool operator() (std::string const &format, T1 &arg1, 00539 T2 &arg2) 00540 { 00541 push (); 00542 std::string::size_type inpos = 0; 00543 bool ret = read_const (format, inpos) 00544 && read_var (format, arg1, inpos) 00545 && read_const (format, inpos) 00546 && read_var (format, arg2, inpos) 00547 && read_const (format, inpos) 00548 && inpos == format.size (); 00549 pop (ret); 00550 return ret; 00551 } 00552 00554 template <typename T1, typename T2, typename T3> 00555 bool operator() (std::string const &format, T1 &arg1, 00556 T2 &arg2, T3 &arg3) 00557 { 00558 push (); 00559 std::string::size_type inpos = 0; 00560 bool ret = read_const (format, inpos) 00561 && read_var (format, arg1, inpos) 00562 && read_const (format, inpos) 00563 && read_var (format, arg2, inpos) 00564 && read_const (format, inpos) 00565 && read_var (format, arg3, inpos) 00566 && read_const (format, inpos) 00567 && inpos == format.size (); 00568 pop (ret); 00569 return ret; 00570 } 00571 00573 template <typename T1, typename T2, typename T3, typename T4> 00574 bool operator() (std::string const &format, T1 &arg1, 00575 T2 &arg2, T3 &arg3, T4 &arg4) 00576 { 00577 push (); 00578 std::string::size_type inpos = 0; 00579 bool ret = read_const (format, inpos) 00580 && read_var (format, arg1, inpos) 00581 && read_const (format, inpos) 00582 && read_var (format, arg2, inpos) 00583 && read_const (format, inpos) 00584 && read_var (format, arg3, inpos) 00585 && read_const (format, inpos) 00586 && read_var (format, arg4, inpos) 00587 && read_const (format, inpos) 00588 && inpos == format.size (); 00589 pop (ret); 00590 return ret; 00591 } 00592 00594 template <typename T1, typename T2, typename T3, typename T4, 00595 typename T5> 00596 bool operator() (std::string const &format, T1 &arg1, 00597 T2 &arg2, T3 &arg3, T4 &arg4, T5 &arg5) 00598 { 00599 push (); 00600 std::string::size_type inpos = 0; 00601 bool ret = read_const (format, inpos) 00602 && read_var (format, arg1, inpos) 00603 && read_const (format, inpos) 00604 && read_var (format, arg2, inpos) 00605 && read_const (format, inpos) 00606 && read_var (format, arg3, inpos) 00607 && read_const (format, inpos) 00608 && read_var (format, arg4, inpos) 00609 && read_const (format, inpos) 00610 && read_var (format, arg5, inpos) 00611 && read_const (format, inpos) 00612 && inpos == format.size (); 00613 pop (ret); 00614 return ret; 00615 } 00616 00618 template <typename T1, typename T2, typename T3, typename T4, 00619 typename T5, typename T6> 00620 bool operator() (std::string const &format, T1 &arg1, 00621 T2 &arg2, T3 &arg3, T4 &arg4, T5 &arg5, 00622 T6 &arg6) 00623 { 00624 push (); 00625 std::string::size_type inpos = 0; 00626 bool ret = read_const (format, inpos) 00627 && read_var (format, arg1, inpos) 00628 && read_const (format, inpos) 00629 && read_var (format, arg2, inpos) 00630 && read_const (format, inpos) 00631 && read_var (format, arg3, inpos) 00632 && read_const (format, inpos) 00633 && read_var (format, arg4, inpos) 00634 && read_const (format, inpos) 00635 && read_var (format, arg5, inpos) 00636 && read_const (format, inpos) 00637 && read_var (format, arg6, inpos) 00638 && read_const (format, inpos) 00639 && inpos == format.size (); 00640 pop (ret); 00641 return ret; 00642 } 00643 00645 template <typename T1, typename T2, typename T3, typename T4, 00646 typename T5, typename T6, typename T7> 00647 bool operator() (std::string const &format, T1 &arg1, 00648 T2 &arg2, T3 &arg3, T4 &arg4, T5 &arg5, 00649 T6 &arg6, T7 &arg7) 00650 { 00651 push (); 00652 std::string::size_type inpos = 0; 00653 bool ret = read_const (format, inpos) 00654 && read_var (format, arg1, inpos) 00655 && read_const (format, inpos) 00656 && read_var (format, arg2, inpos) 00657 && read_const (format, inpos) 00658 && read_var (format, arg3, inpos) 00659 && read_const (format, inpos) 00660 && read_var (format, arg4, inpos) 00661 && read_const (format, inpos) 00662 && read_var (format, arg5, inpos) 00663 && read_const (format, inpos) 00664 && read_var (format, arg6, inpos) 00665 && read_const (format, inpos) 00666 && read_var (format, arg7, inpos) 00667 && read_const (format, inpos) 00668 && inpos == format.size (); 00669 pop (ret); 00670 return ret; 00671 } 00672 00674 template <typename T1, typename T2, typename T3, typename T4, 00675 typename T5, typename T6, typename T7, typename T8> 00676 bool operator() (std::string const &format, T1 &arg1, 00677 T2 &arg2, T3 &arg3, T4 &arg4, T5 &arg5, 00678 T6 &arg6, T7 &arg7, T8 &arg8) 00679 { 00680 push (); 00681 std::string::size_type inpos = 0; 00682 bool ret = read_const (format, inpos) 00683 && read_var (format, arg1, inpos) 00684 && read_const (format, inpos) 00685 && read_var (format, arg2, inpos) 00686 && read_const (format, inpos) 00687 && read_var (format, arg3, inpos) 00688 && read_const (format, inpos) 00689 && read_var (format, arg4, inpos) 00690 && read_const (format, inpos) 00691 && read_var (format, arg5, inpos) 00692 && read_const (format, inpos) 00693 && read_var (format, arg6, inpos) 00694 && read_const (format, inpos) 00695 && read_var (format, arg7, inpos) 00696 && read_const (format, inpos) 00697 && read_var (format, arg8, inpos) 00698 && read_const (format, inpos) 00699 && inpos == format.size (); 00700 pop (ret); 00701 return ret; 00702 } 00703 00705 00708 template <typename T> 00709 static T direct (std::string const &data, 00710 std::string const &format, 00711 T def = T ()) 00712 { 00713 T ret; 00714 istring tmp (data); 00715 if (!tmp (format, ret)) 00716 ret = def; 00717 return ret; 00718 } 00719 }; 00720 00722 00725 template <typename T> 00726 bool ristring::read_var (std::string const &format, T &ret, 00727 std::string::size_type &inpos) 00728 { 00729 ++inpos; 00730 std::istringstream s (data.substr (pos.top ())); 00731 s >> ret; 00732 std::streampos p = s.tellg (); 00733 if (!s || p < 0) 00734 return false; 00735 pos.top () += p; 00736 return true; 00737 } 00738 00740 template <> 00741 bool ristring::read_var <double> (std::string const &format, 00742 double &ret, std::string::size_type &inpos); 00743 00745 template <> 00746 bool ristring::read_var <float> (std::string const &format, 00747 float &ret, std::string::size_type &inpos); 00748 00750 template <> 00751 bool ristring::read_var <std::string> (std::string const &format, 00752 std::string &ret, std::string::size_type &inpos); 00753 00755 template <> 00756 bool ristring::read_var <int> (std::string const &format, 00757 int &ret, std::string::size_type &inpos); 00758 00760 template <> 00761 bool ristring::read_var <unsigned> (std::string const &format, 00762 unsigned &ret, std::string::size_type &inpos); 00763 00765 class rostring 00766 { 00767 std::string data; 00768 std::string format; 00769 std::string::size_type pos; 00770 void write_const (); 00771 template <typename T> void write_var (T const &a, 00772 std::string const &flags, 00773 unsigned width, unsigned precision); 00774 template <typename T> void write_var_raw (T const &a); 00775 rostring &init (std::string const &f); 00776 template <typename T> rostring &operator ()(T const &a) 00777 { write_const (); write_var_raw (a); return *this; } 00778 rostring &operator ()(); 00779 public: 00781 operator std::string () const { return data; } 00783 std::string operator+ (std::string const &that) const { return data + that; } 00785 friend std::ostream &operator<< (std::ostream &s, rostring const &o) { return s << o.data; } 00787 rostring (std::string const &fmt) 00788 { init (fmt)(); } 00790 template <typename T1> 00791 rostring (std::string const &fmt, T1 const &a1) 00792 { init (fmt)(a1)(); } 00794 template <typename T1, typename T2> 00795 rostring (std::string const &fmt, T1 const &a1, T2 const &a2) 00796 { init (fmt)(a1)(a2)(); } 00798 template <typename T1, typename T2, typename T3> 00799 rostring (std::string const &fmt, T1 const &a1, T2 const &a2, T3 const &a3) 00800 { init (fmt)(a1)(a2)(a3)(); } 00802 template <typename T1, typename T2, typename T3, typename T4> 00803 rostring (std::string const &fmt, T1 const &a1, T2 const &a2, T3 const &a3, T4 const &a4) 00804 { init (fmt)(a1)(a2)(a3)(a4)(); } 00806 template <typename T1, typename T2, typename T3, typename T4, typename T5> 00807 rostring (std::string const &fmt, T1 const &a1, T2 const &a2, T3 const &a3, T4 const &a4, T5 const &a5) 00808 { init (fmt)(a1)(a2)(a3)(a4)(a5)(); } 00810 template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> 00811 rostring (std::string const &fmt, T1 const &a1, T2 const &a2, T3 const &a3, T4 const &a4, T5 const &a5, T6 const &a6) 00812 { init (fmt)(a1)(a2)(a3)(a4)(a5)(a6)(); } 00814 template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7> 00815 rostring (std::string const &fmt, T1 const &a1, T2 const &a2, T3 const &a3, T4 const &a4, T5 const &a5, T6 const &a6, T7 const &a7) 00816 { init (fmt)(a1)(a2)(a3)(a4)(a5)(a6)(a7)(); } 00818 template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7 ,typename T8> 00819 rostring (std::string const &fmt, T1 const &a1, T2 const &a2, T3 const &a3, T4 const &a4, T5 const &a5, T6 const &a6, T7 const &a7, T8 const &a8) 00820 { init (fmt)(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(); } 00822 template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7 ,typename T8, typename T9> 00823 rostring (std::string const &fmt, T1 const &a1, T2 const &a2, T3 const &a3, T4 const &a4, T5 const &a5, T6 const &a6, T7 const &a7, T8 const &a8, T9 const &a9) 00824 { init (fmt)(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(a9)(); } 00825 }; 00826 00828 00830 template <typename T> void rostring::write_var_raw (T const &a) 00831 { 00832 unsigned width = 0, precision = 0; 00833 std::string flags; 00834 while (pos < format.size () 00835 && (format[pos] < 'a' || format[pos] > 'z') 00836 && (format[pos] < 'A' || format[pos] > 'Z') 00837 && (format[pos] < '1' || format[pos] > '9')) 00838 flags += format[pos++]; 00839 while (pos < format.size () && format[pos] >= '0' 00840 && format[pos] <= '9') 00841 { 00842 width *= 10; 00843 width += format[pos++] - '0'; 00844 } 00845 if (pos < format.size () && format[pos] == '.') 00846 { 00847 ++pos; 00848 while (pos < format.size () && format[pos] >= '0' 00849 && format[pos] <= '9') 00850 { 00851 precision *= 10; 00852 precision += format[pos++] - '0'; 00853 } 00854 } 00855 return write_var (a, flags, width, precision); 00856 } 00857 00859 00861 template <typename T> void rostring::write_var (T const &a, std::string const &flags, unsigned width, unsigned precision) 00862 { 00863 (void)flags; 00864 (void)width; 00865 (void)precision; 00866 if (pos < format.size ()) 00867 ++pos; 00868 std::ostringstream s; 00869 s << a; 00870 data += s.str (); 00871 } 00872 00874 00876 template <> void rostring::write_var <unsigned> (unsigned const &a, std::string const &flags, unsigned width, unsigned precision); 00878 00880 template <> void rostring::write_var <int> (int const &a, std::string const &flags, unsigned width, unsigned precision); 00881 00883 00886 template <> void rostring::write_var_raw <Glib::ustring> (Glib::ustring const &a); 00887 template <> bool ristring::read_var <Glib::ustring> (std::string const &format, Glib::ustring &ret, std::string::size_type &inpos); 00888 } 00889 00890 #endif