diff --git a/include/loki/SafeFormat.h b/include/loki/SafeFormat.h index bf3bb1d..7fd211b 100644 --- a/include/loki/SafeFormat.h +++ b/include/loki/SafeFormat.h @@ -100,6 +100,21 @@ namespace Loki template struct PrintfState { + + /** This constructor exists only to convert a PrintfState for one device type into a + PrintfState for another device type. It is not for public use. + */ + template < class Device2 > + PrintfState( Device2 & dev, const Char * format, size_t width, size_t prec, + unsigned int flags, LOKI_SAFEFORMAT_SIGNED_LONG result ) + : device_( dev ) + , format_( format ) + , width_( width ) + , prec_( prec ) + , flags_( flags ) + , result_( result ) { + } + PrintfState(Device dev, const Char * format) : device_(dev) , format_(format) @@ -113,6 +128,15 @@ namespace Loki ~PrintfState() { } + /** This function converts a PrintfState for one device type into a PrintfState for + another device type. It is not for public use. + */ + template < class Device2 > + PrintfState< Device2, Char > ChangeDevice( Device2 & device ) const + { + return PrintfState< Device2, Char >( device, format_, width_, prec_, flags_, result_ ); + } + #define LOKI_PRINTF_STATE_FORWARD(type) \ PrintfState& operator()(type par) {\ return (*this)(static_cast< LOKI_SAFEFORMAT_UNSIGNED_LONG >(par)); \ diff --git a/src/SafeFormat.cpp b/src/SafeFormat.cpp index 582ebfd..0d6ddff 100644 --- a/src/SafeFormat.cpp +++ b/src/SafeFormat.cpp @@ -66,27 +66,51 @@ namespace Loki PrintfState Printf(const char* format) { - return PrintfState(stdout, format); + ::std::string buffer; + const PrintfState< ::std::string &, char > state1( buffer, format ); + ::std::fwrite( buffer.c_str(), 1, buffer.size(), stdout ); + PrintfState< std::FILE *, char > printState2 = state1.ChangeDevice( stdout ); + return printState2; } PrintfState Printf(const std::string& format) { - return PrintfState(stdout, format.c_str()); + ::std::string buffer; + const PrintfState< ::std::string &, char > state1( buffer, format.c_str() ); + ::std::fwrite( buffer.c_str(), 1, buffer.size(), stdout ); + PrintfState< std::FILE *, char > printState2 = state1.ChangeDevice( stdout ); + return printState2; } PrintfState FPrintf(std::FILE* f, const char* format) { - return PrintfState(f, format); + ::std::string buffer; + const PrintfState< ::std::string &, char > state1( buffer, format ); + ::std::fwrite( buffer.c_str(), 1, buffer.size(), f ); + PrintfState< std::FILE *, char > printState2 = state1.ChangeDevice( f ); + return printState2; } PrintfState FPrintf(std::FILE* f, const std::string& format) { - return PrintfState(f, format.c_str()); + ::std::string buffer; + const PrintfState< ::std::string &, char > state1( buffer, format.c_str() ); + ::std::fwrite( buffer.c_str(), 1, buffer.size(), f ); + PrintfState< std::FILE *, char > printState2 = state1.ChangeDevice( f ); + return printState2; } PrintfState FPrintf(std::ostream& f, const char* format) { - return PrintfState(f, format); + ::std::string buffer; + const PrintfState< ::std::string &, char > state1( buffer, format ); + f.write( buffer.c_str(), buffer.size() ); + PrintfState< ::std::ostream &, char > printState2 = state1.ChangeDevice< ::std::ostream & >( f ); + return printState2; } PrintfState FPrintf(std::ostream& f, const std::string& format) { - return PrintfState(f, format.c_str()); + ::std::string buffer; + const PrintfState< ::std::string &, char > state1( buffer, format.c_str() ); + f.write( buffer.c_str(), buffer.size() ); + PrintfState< std::ostream &, char > printState2 = state1.ChangeDevice< ::std::ostream & >( f ); + return printState2; } PrintfState SPrintf(std::string& s, const char* format) {