format_wrap.hpp

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