$search
00001 // Copyright (C) 2008-2010 NICTA (www.nicta.com.au) 00002 // Copyright (C) 2008-2010 Conrad Sanderson 00003 // 00004 // This file is part of the Armadillo C++ library. 00005 // It is provided without any warranty of fitness 00006 // for any purpose. You can redistribute this file 00007 // and/or modify it under the terms of the GNU 00008 // Lesser General Public License (LGPL) as published 00009 // by the Free Software Foundation, either version 3 00010 // of the License or (at your option) any later version. 00011 // (see http://www.opensource.org/licenses for more info) 00012 00013 00016 00017 00019 namespace arma_boost 00020 { 00021 00022 #if defined(ARMA_USE_BOOST_FORMAT) 00023 00024 using boost::format; 00025 using boost::basic_format; 00026 using boost::str; 00027 00028 #else 00029 00030 #if defined(ARMA_HAVE_STD_SNPRINTF) 00031 00032 #define arma_snprintf std::snprintf 00033 00034 #else 00035 00036 // better-than-nothing emulation of C99 snprintf(), 00037 // with correct return value and null-terminated output string. 00038 // note that _snprintf() provided by MS is not a good substitute for snprintf() 00039 00040 inline 00041 int 00042 arma_snprintf(char* out, size_t size, const char* fmt, ...) 00043 { 00044 size_t i; 00045 00046 for(i=0; i<size; ++i) 00047 { 00048 out[i] = fmt[i]; 00049 if(fmt[i] == char(0)) 00050 break; 00051 } 00052 00053 if(size > 0) 00054 out[size-1] = char(0); 00055 00056 return int(i); 00057 } 00058 00059 #endif 00060 00061 class format 00062 { 00063 public: 00064 00065 format(const char* in_fmt) 00066 : A(in_fmt) 00067 { 00068 } 00069 00070 format(const std::string& in_fmt) 00071 : A(in_fmt) 00072 { 00073 } 00074 00075 00076 const std::string A; 00077 00078 private: 00079 format(); 00080 }; 00081 00082 00083 00084 template<typename T1, typename T2> 00085 class basic_format 00086 { 00087 public: 00088 00089 basic_format(const T1& in_A, const T2& in_B) 00090 : A(in_A) 00091 , B(in_B) 00092 { 00093 } 00094 00095 const T1& A; 00096 const T2& B; 00097 00098 private: 00099 basic_format(); 00100 }; 00101 00102 00103 00104 template<typename T2> 00105 inline 00106 basic_format< format, T2 > 00107 operator% (const format& X, const T2& arg) 00108 { 00109 return basic_format< format, T2 >(X, arg); 00110 } 00111 00112 00113 00114 template<typename T1, typename T2, typename T3> 00115 inline 00116 basic_format< basic_format<T1,T2>, T3 > 00117 operator% (const basic_format<T1,T2>& X, const T3& arg) 00118 { 00119 return basic_format< basic_format<T1,T2>, T3 >(X, arg); 00120 } 00121 00122 00123 00124 template<typename T2> 00125 inline 00126 std::string 00127 str(const basic_format< format, T2>& X) 00128 { 00129 char local_buffer[1024]; 00130 char* buffer = local_buffer; 00131 00132 int buffer_size = 1024; 00133 int required_size = buffer_size; 00134 00135 bool using_local_buffer = true; 00136 00137 std::string out; 00138 00139 do 00140 { 00141 if(using_local_buffer == false) 00142 { 00143 buffer = new char[buffer_size]; 00144 } 00145 00146 required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.c_str(), X.B); 00147 00148 if(required_size < buffer_size) 00149 { 00150 if(required_size > 0) 00151 { 00152 out = buffer; 00153 } 00154 } 00155 else 00156 { 00157 buffer_size *= 2; 00158 } 00159 00160 if(using_local_buffer == true) 00161 { 00162 using_local_buffer = false; 00163 } 00164 else 00165 { 00166 delete[] buffer; 00167 } 00168 00169 } while( (required_size >= buffer_size) ); 00170 00171 return out; 00172 } 00173 00174 00175 00176 template<typename T2, typename T3> 00177 inline 00178 std::string 00179 str(const basic_format< basic_format< format, T2>, T3>& X) 00180 { 00181 char local_buffer[1024]; 00182 char* buffer = local_buffer; 00183 00184 int buffer_size = 1024; 00185 int required_size = buffer_size; 00186 00187 bool using_local_buffer = true; 00188 00189 std::string out; 00190 00191 do 00192 { 00193 if(using_local_buffer == false) 00194 { 00195 buffer = new char[buffer_size]; 00196 } 00197 00198 required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.A.c_str(), X.A.B, X.B); 00199 00200 if(required_size < buffer_size) 00201 { 00202 if(required_size > 0) 00203 { 00204 out = buffer; 00205 } 00206 } 00207 else 00208 { 00209 buffer_size *= 2; 00210 } 00211 00212 if(using_local_buffer == true) 00213 { 00214 using_local_buffer = false; 00215 } 00216 else 00217 { 00218 delete[] buffer; 00219 } 00220 00221 } while( (required_size >= buffer_size) ); 00222 00223 return out; 00224 } 00225 00226 00227 00228 template<typename T2, typename T3, typename T4> 00229 inline 00230 std::string 00231 str(const basic_format< basic_format< basic_format< format, T2>, T3>, T4>& X) 00232 { 00233 char local_buffer[1024]; 00234 char* buffer = local_buffer; 00235 00236 int buffer_size = 1024; 00237 int required_size = buffer_size; 00238 00239 bool using_local_buffer = true; 00240 00241 std::string out; 00242 00243 do 00244 { 00245 if(using_local_buffer == false) 00246 { 00247 buffer = new char[buffer_size]; 00248 } 00249 00250 required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.A.A.c_str(), X.A.A.B, X.A.B, X.B); 00251 00252 if(required_size < buffer_size) 00253 { 00254 if(required_size > 0) 00255 { 00256 out = buffer; 00257 } 00258 } 00259 else 00260 { 00261 buffer_size *= 2; 00262 } 00263 00264 if(using_local_buffer == true) 00265 { 00266 using_local_buffer = false; 00267 } 00268 else 00269 { 00270 delete[] buffer; 00271 } 00272 00273 } while( (required_size >= buffer_size) ); 00274 00275 return out; 00276 } 00277 00278 00279 00280 template<typename T2, typename T3, typename T4, typename T5> 00281 inline 00282 std::string 00283 str(const basic_format< basic_format< basic_format< basic_format< format, T2>, T3>, T4>, T5>& X) 00284 { 00285 char local_buffer[1024]; 00286 char* buffer = local_buffer; 00287 00288 int buffer_size = 1024; 00289 int required_size = buffer_size; 00290 00291 bool using_local_buffer = true; 00292 00293 std::string out; 00294 00295 do 00296 { 00297 if(using_local_buffer == false) 00298 { 00299 buffer = new char[buffer_size]; 00300 } 00301 00302 required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.A.A.A.c_str(), X.A.A.A.B, X.A.A.B, X.A.B, X.B); 00303 00304 if(required_size < buffer_size) 00305 { 00306 if(required_size > 0) 00307 { 00308 out = buffer; 00309 } 00310 } 00311 else 00312 { 00313 buffer_size *= 2; 00314 } 00315 00316 if(using_local_buffer == true) 00317 { 00318 using_local_buffer = false; 00319 } 00320 else 00321 { 00322 delete[] buffer; 00323 } 00324 00325 } while( (required_size >= buffer_size) ); 00326 00327 return out; 00328 } 00329 00330 00331 00332 template<typename T2, typename T3, typename T4, typename T5, typename T6> 00333 inline 00334 std::string 00335 str(const basic_format< basic_format< basic_format< basic_format< basic_format< format, T2>, T3>, T4>, T5>, T6>& X) 00336 { 00337 char local_buffer[1024]; 00338 char* buffer = local_buffer; 00339 00340 int buffer_size = 1024; 00341 int required_size = buffer_size; 00342 00343 bool using_local_buffer = true; 00344 00345 std::string out; 00346 00347 do 00348 { 00349 if(using_local_buffer == false) 00350 { 00351 buffer = new char[buffer_size]; 00352 } 00353 00354 required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.A.A.A.A.c_str(), X.A.A.A.A.B, X.A.A.A.B, X.A.A.B, X.A.B, X.B); 00355 00356 if(required_size < buffer_size) 00357 { 00358 if(required_size > 0) 00359 { 00360 out = buffer; 00361 } 00362 } 00363 else 00364 { 00365 buffer_size *= 2; 00366 } 00367 00368 if(using_local_buffer == true) 00369 { 00370 using_local_buffer = false; 00371 } 00372 else 00373 { 00374 delete[] buffer; 00375 } 00376 00377 } while( (required_size >= buffer_size) ); 00378 00379 return out; 00380 } 00381 00382 00383 00384 template<typename T2, typename T3, typename T4, typename T5, typename T6, typename T7> 00385 inline 00386 std::string 00387 str(const basic_format< basic_format< basic_format< basic_format< basic_format< basic_format< format, T2>, T3>, T4>, T5>, T6>, T7>& X) 00388 { 00389 char local_buffer[1024]; 00390 char* buffer = local_buffer; 00391 00392 int buffer_size = 1024; 00393 int required_size = buffer_size; 00394 00395 bool using_local_buffer = true; 00396 00397 std::string out; 00398 00399 do 00400 { 00401 if(using_local_buffer == false) 00402 { 00403 buffer = new char[buffer_size]; 00404 } 00405 00406 required_size = arma_snprintf(buffer, size_t(buffer_size), X.A.A.A.A.A.A.A.c_str(), X.A.A.A.A.A.B, X.A.A.A.A.B, X.A.A.A.B, X.A.A.B, X.A.B, X.B); 00407 00408 if(required_size < buffer_size) 00409 { 00410 if(required_size > 0) 00411 { 00412 out = buffer; 00413 } 00414 } 00415 else 00416 { 00417 buffer_size *= 2; 00418 } 00419 00420 if(using_local_buffer == true) 00421 { 00422 using_local_buffer = false; 00423 } 00424 else 00425 { 00426 delete[] buffer; 00427 } 00428 00429 } while( (required_size >= buffer_size) ); 00430 00431 return out; 00432 } 00433 00434 00435 00436 template<typename T1> 00437 struct format_metaprog 00438 { 00439 static const uword depth = 0; 00440 00441 inline 00442 static 00443 const std::string& 00444 get_fmt(const T1& X) 00445 { 00446 return X.A; 00447 } 00448 }; 00449 00450 00451 00452 //template<> 00453 template<typename T1, typename T2> 00454 struct format_metaprog< basic_format<T1,T2> > 00455 { 00456 static const uword depth = 1 + format_metaprog<T1>::depth; 00457 00458 inline 00459 static 00460 const std::string& 00461 get_fmt(const T1& X) 00462 { 00463 return format_metaprog<T1>::get_fmt(X.A); 00464 } 00465 00466 }; 00467 00468 00469 00470 template<typename T1, typename T2> 00471 inline 00472 std::string 00473 str(const basic_format<T1,T2>& X) 00474 { 00475 return format_metaprog< basic_format<T1,T2> >::get_fmt(X.A); 00476 } 00477 00478 00479 00480 template<typename T1, typename T2> 00481 inline 00482 std::ostream& 00483 operator<< (std::ostream& o, const basic_format<T1,T2>& X) 00484 { 00485 o << str(X); 00486 return o; 00487 } 00488 00489 00490 #endif 00491 00492 00493 template<typename T> struct string_only { }; 00494 template<> struct string_only<std::string> { typedef std::string result; }; 00495 00496 template<typename T> struct char_only { }; 00497 template<> struct char_only<char > { typedef char result; }; 00498 00499 template<typename T> 00500 struct basic_format_only { }; 00501 00502 #if defined(ARMA_USE_BOOST_FORMAT) 00503 template<typename T> 00504 struct basic_format_only< basic_format<T> > { typedef basic_format<T> result; }; 00505 #else 00506 template<typename T1, typename T2> 00507 struct basic_format_only< basic_format<T1, T2> > { typedef basic_format<T1,T2> result; }; 00508 #endif 00509 00510 00511 00512 template<typename T1> 00513 inline 00514 static 00515 const T1& 00516 str_wrapper(const T1& x, const typename string_only<T1>::result* junk = 0) 00517 { 00518 arma_ignore(junk); 00519 00520 return x; 00521 } 00522 00523 00524 00525 template<typename T1> 00526 inline 00527 static 00528 const T1* 00529 str_wrapper(const T1* x, const typename char_only<T1>::result* junk = 0) 00530 { 00531 arma_ignore(junk); 00532 00533 return x; 00534 } 00535 00536 00537 00538 template<typename T1> 00539 inline 00540 static 00541 std::string 00542 str_wrapper(const T1& x, const typename basic_format_only<T1>::result* junk = 0) 00543 { 00544 arma_ignore(junk); 00545 00546 return str(x); 00547 } 00548 00549 } 00550