#include #include #include #include #include #include using namespace Bu; class Fmter { public: Fmter( const Bu::String &sSrc ) : sSrc( sSrc ) { } template Fmter &arg( const T &x ) { lParm.append( Pair( x ) ); return *this; } template Fmter &arg( const T &x, Bu::Formatter::Fmt f ) { lParm.append( Pair( x, f ) ); return *this; } operator Bu::String() const { int iCount = lParm.getSize(); ParmList::const_iterator *aParm = new ParmList::const_iterator[iCount]; { int j = 0; for( ParmList::const_iterator i = lParm.begin(); i; i++, j++ ) { aParm[j] = i; } } Bu::MemBuf mbOut; Bu::Formatter f( mbOut ); for( Bu::String::const_iterator s = sSrc.begin(); s; s++ ) { if( *s == '%' ) { s++; if( *s == '%' ) f << *s; else { Bu::String sNum; while( s && *s >= '0' && *s <= '9' ) { sNum += *s; s++; } int iIndex = strtol( sNum.getStr(), 0, 10 )-1; if( iIndex < 0 || iIndex >= iCount ) { delete[] aParm; throw Bu::ExceptionBase( "Argument index %d is outside of " "valid range (1-%d).", iIndex+1, iCount ); } f << (*aParm[iIndex]).format << (*aParm[iIndex]).value; if( s ) f << *s; } } else { f << *s; } } delete[] aParm; return mbOut.getString(); } private: const Bu::String &sSrc; class Pair { public: template Pair( const T &v ) : value( v ) { } template Pair( const T &v, Bu::Formatter::Fmt f ) : value( v ), format( f ) { } Bu::Variant value; Bu::Formatter::Fmt format; }; typedef Bu::List ParmList; ParmList lParm; }; Bu::Formatter &operator<<( Bu::Formatter &f, const Fmter &r ) { return f << (Bu::String)r; } int main() { sio << Fmter("A word is %1 and a number is %2 %1"). arg("Hello").arg(75, Fmt::hex() ).arg(" - ") << sio.nl; }