libshevek

- Main Page
- Classes
- Files

- File List

src/iostring.hh

    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