Compose.hh

00001 /* Defines String::compose(fmt, arg...) for easy, i18n-friendly
00002  * composition of strings.
00003  *
00004  * Version 1.0.
00005  *
00006  * Copyright (c) 2002 Ole Laursen <olau@hardworking.dk>.
00007  *
00008  * This library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public License
00010  * as published by the Free Software Foundation; either version 2.1 of
00011  * the License, or (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with this library; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00021  * USA.
00022  */
00023 
00024 //
00025 // Basic usage is like
00026 //
00027 //   std::cout << String::compose("This is a %1x%2 matrix.", rows, cols);
00028 //
00029 // See http://www.cs.aau.dk/~olau/compose/ or the included README.compose for
00030 // more details.
00031 //
00032 
00033 //
00034 // The original implementation was too slow for our need, and
00035 // as I supected some segv in this code, I rewrote most of the code.
00036 // Basically, it does not have the same feature as before, but it is a lot
00037 // faster...
00038 // Victor, 2007.
00039 //
00040 
00041 #ifndef STRING_COMPOSE_H
00042 # define STRING_COMPOSE_H
00043 
00044 # include <iostream>
00045 # include <sstream>
00046 # include <string>
00047 # include <deque>
00048 
00049 namespace StringPrivate
00050 {
00051   // Hide the mess in a obscur namespace... Yes, really.
00052 
00053   class Composition
00054   {
00055   public:
00056     // initialize and prepare format string on the form "text %1 text %2 etc."
00057     explicit Composition(std::ostream& os, std::string fmt);
00058     ~Composition();
00059 
00060     // supply an replacement argument starting from %1
00061     template <typename T>
00062     Composition &arg(const T &obj);
00063 
00064   private:
00065     std::ostringstream os;
00066     std::ostream& os_;
00067     typedef std::deque<std::pair<int, std::string> > SpecList;
00068     SpecList spec;
00069   };
00070 
00071   inline Composition::Composition(std::ostream& os, std::string fmt)
00072     : os_(os)
00073   {
00074     std::string::size_type fmt_size = fmt.length();
00075     std::string::size_type last = 0;
00076     std::string::size_type i;
00077     bool next_m = false;
00078     std::string current;
00079     int spec_no = 0;
00080     int spec_size;
00081 
00082     for (i = 0; i < fmt_size; i++)
00083       {
00084     if (fmt[i] == '%')
00085       {
00086         if (next_m)
00087           {
00088         current += fmt.substr(last, i - last - 1);
00089         last = i;
00090         next_m = false;
00091           }
00092         else
00093           next_m = true;
00094         continue;
00095       }
00096 
00097     if (next_m && fmt[i] >= '0' && fmt[i] <= '9')
00098       {
00099         spec_no = fmt[i] - '0';
00100         spec_size = 1;
00101         if (i + 1 < fmt_size && fmt[i + 1] >= '0' && fmt[i + 1] <= '9') {
00102           spec_no = spec_no * 10 + (fmt[i + 1] - '0');
00103           spec_size = 2;
00104           i += 1;
00105         }
00106 
00107         spec.push_back(std::make_pair(spec_no, current + fmt.substr(last, i - last - spec_size)));
00108         last = i + 1;
00109         next_m = false;
00110         current = "";
00111       }
00112       }
00113     spec.push_back(std::make_pair(spec_no, current + fmt.substr(last, i - last)));
00114   }
00115 
00116   // Print remainings data in format string
00117   inline Composition::~Composition()
00118   {
00119     for (SpecList::iterator it = spec.begin(); it != spec.end(); ++it)
00120       {
00121     os_ << it->second;
00122       }
00123     os_ << std::endl;
00124   }
00125 
00126   // implementation of class Composition
00127   template <typename T>
00128   inline Composition &Composition::arg(const T &obj)
00129   {
00130     os_ << spec.front().second;
00131     spec.pop_front();
00132     os_ << obj;
00133     os.str("");
00134 
00135     return *this;
00136   }
00137 
00138 }
00139 
00140 
00141 
00142 
00143 
00144 inline void tlog(std::ostream& os, const std::string &fmt)
00145 {
00146   os << fmt << std::endl;
00147 }
00148 
00149 // a series of functions which accept a format string on the form "text %1
00150 // more %2 less %3" and a number of templated parameters and spits out the
00151 // composited string
00152 template <typename T1>
00153 inline void tlog(std::ostream& os, const std::string &fmt, const T1 &o1)
00154 {
00155   StringPrivate::Composition c(os, fmt);
00156   c.arg(o1);
00157 }
00158 
00159 template <typename T1, typename T2>
00160 inline void tlog(std::ostream& os, const std::string &fmt,
00161             const T1 &o1, const T2 &o2)
00162 {
00163   StringPrivate::Composition c(os, fmt);
00164   c.arg(o1).arg(o2);
00165 }
00166 
00167 template <typename T1, typename T2, typename T3>
00168 inline void tlog(std::ostream& os, const std::string &fmt,
00169             const T1 &o1, const T2 &o2, const T3 &o3)
00170 {
00171   StringPrivate::Composition c(os, fmt);
00172   c.arg(o1).arg(o2).arg(o3);
00173 }
00174 
00175 template <typename T1, typename T2, typename T3, typename T4>
00176 inline void tlog(std::ostream& os, const std::string &fmt,
00177             const T1 &o1, const T2 &o2, const T3 &o3,
00178             const T4 &o4)
00179 {
00180   StringPrivate::Composition c(os, fmt);
00181   c.arg(o1).arg(o2).arg(o3).arg(o4);
00182 }
00183 
00184 template <typename T1, typename T2, typename T3, typename T4, typename T5>
00185 inline void tlog(std::ostream& os, const std::string &fmt,
00186             const T1 &o1, const T2 &o2, const T3 &o3,
00187             const T4 &o4, const T5 &o5)
00188 {
00189   StringPrivate::Composition c(os, fmt);
00190   c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5);
00191 }
00192 
00193 template <typename T1, typename T2, typename T3, typename T4, typename T5,
00194       typename T6>
00195 inline void tlog(std::ostream& os, const std::string &fmt,
00196             const T1 &o1, const T2 &o2, const T3 &o3,
00197             const T4 &o4, const T5 &o5, const T6 &o6)
00198 {
00199   StringPrivate::Composition c(os, fmt);
00200   c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6);
00201 }
00202 
00203 template <typename T1, typename T2, typename T3, typename T4, typename T5,
00204       typename T6, typename T7>
00205 inline void tlog(std::ostream& os, const std::string &fmt,
00206             const T1 &o1, const T2 &o2, const T3 &o3,
00207             const T4 &o4, const T5 &o5, const T6 &o6,
00208             const T7 &o7)
00209 {
00210   StringPrivate::Composition c(os, fmt);
00211   c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7);
00212 }
00213 
00214 template <typename T1, typename T2, typename T3, typename T4, typename T5,
00215       typename T6, typename T7, typename T8>
00216 inline void tlog(std::ostream& os, const std::string &fmt,
00217             const T1 &o1, const T2 &o2, const T3 &o3,
00218             const T4 &o4, const T5 &o5, const T6 &o6,
00219             const T7 &o7, const T8 &o8)
00220 {
00221   StringPrivate::Composition c(os, fmt);
00222   c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8);
00223 }
00224 
00225 template <typename T1, typename T2, typename T3, typename T4, typename T5,
00226       typename T6, typename T7, typename T8, typename T9>
00227 inline void tlog(std::ostream& os, const std::string &fmt,
00228             const T1 &o1, const T2 &o2, const T3 &o3,
00229             const T4 &o4, const T5 &o5, const T6 &o6,
00230             const T7 &o7, const T8 &o8, const T9 &o9)
00231 {
00232   StringPrivate::Composition c(os, fmt);
00233   c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8).arg(o9);
00234 }
00235 
00236 template <typename T1, typename T2, typename T3, typename T4, typename T5,
00237       typename T6, typename T7, typename T8, typename T9, typename T10>
00238 inline void tlog(std::ostream& os, const std::string &fmt,
00239             const T1 &o1, const T2 &o2, const T3 &o3,
00240             const T4 &o4, const T5 &o5, const T6 &o6,
00241             const T7 &o7, const T8 &o8, const T9 &o9,
00242             const T10 &o10)
00243 {
00244   StringPrivate::Composition c(os, fmt);
00245   c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8).arg(o9)
00246     .arg(o10);
00247 }
00248 
00249 template <typename T1, typename T2, typename T3, typename T4, typename T5,
00250       typename T6, typename T7, typename T8, typename T9, typename T10,
00251       typename T11>
00252 inline void tlog(std::ostream& os, const std::string &fmt,
00253             const T1 &o1, const T2 &o2, const T3 &o3,
00254             const T4 &o4, const T5 &o5, const T6 &o6,
00255             const T7 &o7, const T8 &o8, const T9 &o9,
00256             const T10 &o10, const T11 &o11)
00257 {
00258   StringPrivate::Composition c(os, fmt);
00259   c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8).arg(o9)
00260     .arg(o10).arg(o11);
00261 }
00262 
00263 template <typename T1, typename T2, typename T3, typename T4, typename T5,
00264       typename T6, typename T7, typename T8, typename T9, typename T10,
00265       typename T11, typename T12>
00266 inline void tlog(std::ostream& os, const std::string &fmt,
00267             const T1 &o1, const T2 &o2, const T3 &o3,
00268             const T4 &o4, const T5 &o5, const T6 &o6,
00269             const T7 &o7, const T8 &o8, const T9 &o9,
00270             const T10 &o10, const T11 &o11, const T12 &o12)
00271 {
00272   StringPrivate::Composition c(os, fmt);
00273   c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8).arg(o9)
00274     .arg(o10).arg(o11).arg(o12);
00275 }
00276 
00277 template <typename T1, typename T2, typename T3, typename T4, typename T5,
00278       typename T6, typename T7, typename T8, typename T9, typename T10,
00279       typename T11, typename T12, typename T13>
00280 inline void tlog(std::ostream& os, const std::string &fmt,
00281             const T1 &o1, const T2 &o2, const T3 &o3,
00282             const T4 &o4, const T5 &o5, const T6 &o6,
00283             const T7 &o7, const T8 &o8, const T9 &o9,
00284             const T10 &o10, const T11 &o11, const T12 &o12,
00285             const T13 &o13)
00286 {
00287   StringPrivate::Composition c(os, fmt);
00288   c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8).arg(o9)
00289     .arg(o10).arg(o11).arg(o12).arg(o13);
00290 }
00291 
00292 template <typename T1, typename T2, typename T3, typename T4, typename T5,
00293       typename T6, typename T7, typename T8, typename T9, typename T10,
00294       typename T11, typename T12, typename T13, typename T14>
00295 inline void tlog(std::ostream& os, const std::string &fmt,
00296             const T1 &o1, const T2 &o2, const T3 &o3,
00297             const T4 &o4, const T5 &o5, const T6 &o6,
00298             const T7 &o7, const T8 &o8, const T9 &o9,
00299             const T10 &o10, const T11 &o11, const T12 &o12,
00300             const T13 &o13, const T14 &o14)
00301 {
00302   StringPrivate::Composition c(os, fmt);
00303   c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8).arg(o9)
00304     .arg(o10).arg(o11).arg(o12).arg(o13).arg(o14);
00305 }
00306 
00307 template <typename T1, typename T2, typename T3, typename T4, typename T5,
00308       typename T6, typename T7, typename T8, typename T9, typename T10,
00309       typename T11, typename T12, typename T13, typename T14,
00310       typename T15>
00311 inline void tlog(std::ostream& os, const std::string &fmt,
00312             const T1 &o1, const T2 &o2, const T3 &o3,
00313             const T4 &o4, const T5 &o5, const T6 &o6,
00314             const T7 &o7, const T8 &o8, const T9 &o9,
00315             const T10 &o10, const T11 &o11, const T12 &o12,
00316             const T13 &o13, const T14 &o14, const T15 &o15)
00317 {
00318   StringPrivate::Composition c(os, fmt);
00319   c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8).arg(o9)
00320     .arg(o10).arg(o11).arg(o12).arg(o13).arg(o14).arg(o15);
00321 }
00322 
00323 
00324 #endif // STRING_COMPOSE_H
Generated on Mon Apr 5 21:17:11 2010 for Stechec/TBT by  doxygen 1.6.3