00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef STRING_COMPOSE_H
00034 #define STRING_COMPOSE_H
00035
00036 #include <sstream>
00037 #include <string>
00038 #include <list>
00039 #include <map>
00040
00041 namespace StringPrivate
00042 {
00043
00044
00045 class Composition
00046 {
00047 public:
00048
00049 explicit Composition(std::string fmt);
00050
00051
00052 template <typename T>
00053 Composition &arg(const T &obj);
00054
00055
00056 std::string str() const;
00057
00058 private:
00059 std::ostringstream os;
00060 int arg_no;
00061
00062
00063
00064
00065
00066 typedef std::list<std::string> output_list;
00067 output_list output;
00068
00069
00070
00071 typedef std::multimap<int, output_list::iterator> specification_map;
00072 specification_map specs;
00073 };
00074
00075
00076 inline int char_to_int(char c)
00077 {
00078 switch (c) {
00079 case '0': return 0;
00080 case '1': return 1;
00081 case '2': return 2;
00082 case '3': return 3;
00083 case '4': return 4;
00084 case '5': return 5;
00085 case '6': return 6;
00086 case '7': return 7;
00087 case '8': return 8;
00088 case '9': return 9;
00089 default: return -1000;
00090 }
00091 }
00092
00093 inline bool is_number(int n)
00094 {
00095 switch (n) {
00096 case '0':
00097 case '1':
00098 case '2':
00099 case '3':
00100 case '4':
00101 case '5':
00102 case '6':
00103 case '7':
00104 case '8':
00105 case '9':
00106 return true;
00107
00108 default:
00109 return false;
00110 }
00111 }
00112
00113
00114
00115 template <typename T>
00116 inline Composition &Composition::arg(const T &obj)
00117 {
00118 os << obj;
00119
00120 std::string rep = os.str();
00121
00122 if (!rep.empty())
00123 {
00124 for (specification_map::const_iterator i = specs.lower_bound(arg_no),
00125 end = specs.upper_bound(arg_no); i != end; ++i)
00126 {
00127 output_list::iterator pos = i->second;
00128 ++pos;
00129 output.insert(pos, rep);
00130 }
00131
00132 os.str(std::string());
00133
00134 ++arg_no;
00135 }
00136
00137 return *this;
00138 }
00139
00140 inline Composition::Composition(std::string fmt)
00141 : arg_no(1)
00142 {
00143 std::string::size_type b = 0, i = 0;
00144
00145
00146
00147 while (i < fmt.length()) {
00148 if (fmt[i] == '%' && i + 1 < fmt.length()) {
00149 if (fmt[i + 1] == '%') {
00150 fmt.replace(i, 2, "%");
00151 ++i;
00152 }
00153 else if (is_number(fmt[i + 1])) {
00154
00155 output.push_back(fmt.substr(b, i - b));
00156
00157 int n = 1;
00158 int spec_no = 0;
00159
00160 do {
00161 spec_no += char_to_int(fmt[i + n]);
00162 spec_no *= 10;
00163 ++n;
00164 } while (i + n < fmt.length() && is_number(fmt[i + n]));
00165
00166 spec_no /= 10;
00167 output_list::iterator pos = output.end();
00168 --pos;
00169
00170 specs.insert(specification_map::value_type(spec_no, pos));
00171
00172
00173 i += n;
00174 b = i;
00175 }
00176 else
00177 ++i;
00178 }
00179 else
00180 ++i;
00181 }
00182
00183 if (i - b > 0)
00184 output.push_back(fmt.substr(b, i - b));
00185 }
00186
00187 inline std::string Composition::str() const
00188 {
00189
00190 std::string str;
00191
00192 for (output_list::const_iterator i = output.begin(), end = output.end();
00193 i != end; ++i)
00194 str += *i;
00195
00196 return str;
00197 }
00198 }
00199
00200
00201 namespace String
00202 {
00203 inline std::string compose(const std::string &fmt)
00204 {
00205 StringPrivate::Composition c(fmt);
00206 return c.str();
00207 }
00208
00209
00210
00211 template <typename T1>
00212 inline std::string compose(const std::string &fmt, const T1 &o1)
00213 {
00214 StringPrivate::Composition c(fmt);
00215 c.arg(o1);
00216 return c.str();
00217 }
00218
00219 template <typename T1, typename T2>
00220 inline std::string compose(const std::string &fmt,
00221 const T1 &o1, const T2 &o2)
00222 {
00223 StringPrivate::Composition c(fmt);
00224 c.arg(o1).arg(o2);
00225 return c.str();
00226 }
00227
00228 template <typename T1, typename T2, typename T3>
00229 inline std::string compose(const std::string &fmt,
00230 const T1 &o1, const T2 &o2, const T3 &o3)
00231 {
00232 StringPrivate::Composition c(fmt);
00233 c.arg(o1).arg(o2).arg(o3);
00234 return c.str();
00235 }
00236
00237 template <typename T1, typename T2, typename T3, typename T4>
00238 inline std::string compose(const std::string &fmt,
00239 const T1 &o1, const T2 &o2, const T3 &o3,
00240 const T4 &o4)
00241 {
00242 StringPrivate::Composition c(fmt);
00243 c.arg(o1).arg(o2).arg(o3).arg(o4);
00244 return c.str();
00245 }
00246
00247 template <typename T1, typename T2, typename T3, typename T4, typename T5>
00248 inline std::string compose(const std::string &fmt,
00249 const T1 &o1, const T2 &o2, const T3 &o3,
00250 const T4 &o4, const T5 &o5)
00251 {
00252 StringPrivate::Composition c(fmt);
00253 c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5);
00254 return c.str();
00255 }
00256
00257 template <typename T1, typename T2, typename T3, typename T4, typename T5,
00258 typename T6>
00259 inline std::string compose(const std::string &fmt,
00260 const T1 &o1, const T2 &o2, const T3 &o3,
00261 const T4 &o4, const T5 &o5, const T6 &o6)
00262 {
00263 StringPrivate::Composition c(fmt);
00264 c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6);
00265 return c.str();
00266 }
00267
00268 template <typename T1, typename T2, typename T3, typename T4, typename T5,
00269 typename T6, typename T7>
00270 inline std::string compose(const std::string &fmt,
00271 const T1 &o1, const T2 &o2, const T3 &o3,
00272 const T4 &o4, const T5 &o5, const T6 &o6,
00273 const T7 &o7)
00274 {
00275 StringPrivate::Composition c(fmt);
00276 c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7);
00277 return c.str();
00278 }
00279
00280 template <typename T1, typename T2, typename T3, typename T4, typename T5,
00281 typename T6, typename T7, typename T8>
00282 inline std::string compose(const std::string &fmt,
00283 const T1 &o1, const T2 &o2, const T3 &o3,
00284 const T4 &o4, const T5 &o5, const T6 &o6,
00285 const T7 &o7, const T8 &o8)
00286 {
00287 StringPrivate::Composition c(fmt);
00288 c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8);
00289 return c.str();
00290 }
00291
00292 template <typename T1, typename T2, typename T3, typename T4, typename T5,
00293 typename T6, typename T7, typename T8, typename T9>
00294 inline std::string compose(const std::string &fmt,
00295 const T1 &o1, const T2 &o2, const T3 &o3,
00296 const T4 &o4, const T5 &o5, const T6 &o6,
00297 const T7 &o7, const T8 &o8, const T9 &o9)
00298 {
00299 StringPrivate::Composition c(fmt);
00300 c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8).arg(o9);
00301 return c.str();
00302 }
00303
00304 template <typename T1, typename T2, typename T3, typename T4, typename T5,
00305 typename T6, typename T7, typename T8, typename T9, typename T10>
00306 inline std::string compose(const std::string &fmt,
00307 const T1 &o1, const T2 &o2, const T3 &o3,
00308 const T4 &o4, const T5 &o5, const T6 &o6,
00309 const T7 &o7, const T8 &o8, const T9 &o9,
00310 const T10 &o10)
00311 {
00312 StringPrivate::Composition c(fmt);
00313 c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8).arg(o9)
00314 .arg(o10);
00315 return c.str();
00316 }
00317
00318 template <typename T1, typename T2, typename T3, typename T4, typename T5,
00319 typename T6, typename T7, typename T8, typename T9, typename T10,
00320 typename T11>
00321 inline std::string compose(const std::string &fmt,
00322 const T1 &o1, const T2 &o2, const T3 &o3,
00323 const T4 &o4, const T5 &o5, const T6 &o6,
00324 const T7 &o7, const T8 &o8, const T9 &o9,
00325 const T10 &o10, const T11 &o11)
00326 {
00327 StringPrivate::Composition c(fmt);
00328 c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8).arg(o9)
00329 .arg(o10).arg(o11);
00330 return c.str();
00331 }
00332
00333 template <typename T1, typename T2, typename T3, typename T4, typename T5,
00334 typename T6, typename T7, typename T8, typename T9, typename T10,
00335 typename T11, typename T12>
00336 inline std::string compose(const std::string &fmt,
00337 const T1 &o1, const T2 &o2, const T3 &o3,
00338 const T4 &o4, const T5 &o5, const T6 &o6,
00339 const T7 &o7, const T8 &o8, const T9 &o9,
00340 const T10 &o10, const T11 &o11, const T12 &o12)
00341 {
00342 StringPrivate::Composition c(fmt);
00343 c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8).arg(o9)
00344 .arg(o10).arg(o11).arg(o12);
00345 return c.str();
00346 }
00347
00348 template <typename T1, typename T2, typename T3, typename T4, typename T5,
00349 typename T6, typename T7, typename T8, typename T9, typename T10,
00350 typename T11, typename T12, typename T13>
00351 inline std::string compose(const std::string &fmt,
00352 const T1 &o1, const T2 &o2, const T3 &o3,
00353 const T4 &o4, const T5 &o5, const T6 &o6,
00354 const T7 &o7, const T8 &o8, const T9 &o9,
00355 const T10 &o10, const T11 &o11, const T12 &o12,
00356 const T13 &o13)
00357 {
00358 StringPrivate::Composition c(fmt);
00359 c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8).arg(o9)
00360 .arg(o10).arg(o11).arg(o12).arg(o13);
00361 return c.str();
00362 }
00363
00364 template <typename T1, typename T2, typename T3, typename T4, typename T5,
00365 typename T6, typename T7, typename T8, typename T9, typename T10,
00366 typename T11, typename T12, typename T13, typename T14>
00367 inline std::string compose(const std::string &fmt,
00368 const T1 &o1, const T2 &o2, const T3 &o3,
00369 const T4 &o4, const T5 &o5, const T6 &o6,
00370 const T7 &o7, const T8 &o8, const T9 &o9,
00371 const T10 &o10, const T11 &o11, const T12 &o12,
00372 const T13 &o13, const T14 &o14)
00373 {
00374 StringPrivate::Composition c(fmt);
00375 c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8).arg(o9)
00376 .arg(o10).arg(o11).arg(o12).arg(o13).arg(o14);
00377 return c.str();
00378 }
00379
00380 template <typename T1, typename T2, typename T3, typename T4, typename T5,
00381 typename T6, typename T7, typename T8, typename T9, typename T10,
00382 typename T11, typename T12, typename T13, typename T14,
00383 typename T15>
00384 inline std::string compose(const std::string &fmt,
00385 const T1 &o1, const T2 &o2, const T3 &o3,
00386 const T4 &o4, const T5 &o5, const T6 &o6,
00387 const T7 &o7, const T8 &o8, const T9 &o9,
00388 const T10 &o10, const T11 &o11, const T12 &o12,
00389 const T13 &o13, const T14 &o14, const T15 &o15)
00390 {
00391 StringPrivate::Composition c(fmt);
00392 c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8).arg(o9)
00393 .arg(o10).arg(o11).arg(o12).arg(o13).arg(o14).arg(o15);
00394 return c.str();
00395 }
00396 }
00397
00398
00399 #endif // STRING_COMPOSE_H