#pragma once #include #include #include #include #include #include #ifdef _MSC_VER #define WIN32_LEAN_AND_MEAN #include #define DEBUG_LOG(str) OutputDebugStringA(str) #endif namespace apf { struct apf_exception { } ; #define THROW throw apf_exception() #define TRY try #define CATCH catch(...) #ifdef _MSC_VER #ifdef _WIN64 #define ASSERT_BREAK() __debugbreak() #else #define ASSERT_BREAK() __asm { int 3 } #endif #endif #ifdef _DEBUG #define ASSERT(exp) do { if ( ! (exp) ) { DEBUG_LOG( #exp ); ASSERT_BREAK(); } } while(0) #else #define ASSERT(exp) #endif #ifdef _MSC_VER #define FMT_I64 "I64" #else #define FMT_I64 "ll" #endif #define REFERENCE_TO_VARIABLE(v) v; void strlcpy(char * to, const char * fm, int maxLen); #pragma warning(disable : 4996) //>c:\src\autoprintf\safeprintf.inc(4) : warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. /**** safeprintf 4-12-07 "safeprintf" is an identical drop in for "printf" (similarly safesprintf -> sprintf , safefprintf -> fprintf ). It detects argument errors at run time and makes a nice message (if noisy mode is on). With or without noisy mode, it blocks printf from being called with the bad args. A stronger safe printing template would detect problems at compile time, but you can't do that with a printf drop-in. Drop-in compatibility with printf is crucial to me. --------------------------------------------- DIFFERENCE IN FUNCTIONALITY : Regular printf will take classes in the varargs and convert them to whatever type you try to print as. In some cases people use this benignly, such as with an HWND : printf("Window handle = %08X\n",GetWindow()); if you call that with safeprintf it will generate an error saying an HWND is not an int. You have to explicitly cast that for safeprintf : printf("Window handle = %08X\n",(int)GetWindow()); --------------------------------------------- ADDING TYPES : if you want safeprintf to treat a certain type as a valid int (or float or whatever) arg, you can implement safeprintf_type() on your custom type. Generally it's preferred to explicitly cast when you call, but in some cases if you have types that are drop-in replacements for basic types you may want to do this. eg. you could provide : template <> inline ESafePrintfType safeprintf_type(const HWND arg) { return safeprintf_int32; } --------------------------------------------- You can wrap your own varargs printing functions to make them safe using the "safeprintf.inc" include. See the bottom of this file for examples. ****/ //START_CB //======================================================================================= enum ESafePrintfType { safeprintf_none = 0, safeprintf_unknown, safeprintf_charptr, safeprintf_wcharptr, safeprintf_float, safeprintf_ptrint, safeprintf_ptrvoid, safeprintf_int32, safeprintf___int64, safeprintf_uint32, safeprintf_u__int64 //safeprintf_basetypes_count }; const char * c_safeprintftypenames[]; template < typename t_arg > inline ESafePrintfType safeprintf_type(const t_arg arg) { return safeprintf_unknown; } template <> inline ESafePrintfType safeprintf_type(const int arg) { return safeprintf_int32; } template <> inline ESafePrintfType safeprintf_type(const char arg) { return safeprintf_int32; } template <> inline ESafePrintfType safeprintf_type(const short arg) { return safeprintf_int32; } template <> inline ESafePrintfType safeprintf_type(const long arg) { return safeprintf_int32; } template <> inline ESafePrintfType safeprintf_type(const __int64 arg) { return safeprintf___int64; } template <> inline ESafePrintfType safeprintf_type(const unsigned int arg) { return safeprintf_uint32; } template <> inline ESafePrintfType safeprintf_type(const unsigned char arg) { return safeprintf_int32; } template <> inline ESafePrintfType safeprintf_type(const unsigned short arg) { return safeprintf_int32; } template <> inline ESafePrintfType safeprintf_type(const unsigned long arg) { return safeprintf_uint32; } template <> inline ESafePrintfType safeprintf_type(const unsigned __int64 arg) { return safeprintf_u__int64; } template <> inline ESafePrintfType safeprintf_type(const float arg) { return safeprintf_float; } template <> inline ESafePrintfType safeprintf_type(const double arg) { return safeprintf_float; } template <> inline ESafePrintfType safeprintf_type(const char * arg) { return safeprintf_charptr; } template <> inline ESafePrintfType safeprintf_type(const wchar_t * arg) { return safeprintf_wcharptr; } template <> inline ESafePrintfType safeprintf_type(char * arg) { return safeprintf_charptr; } template <> inline ESafePrintfType safeprintf_type(wchar_t * arg) { return safeprintf_wcharptr; } template <> inline ESafePrintfType safeprintf_type(int * arg) { return safeprintf_ptrint; } template <> inline ESafePrintfType safeprintf_type(void * arg) { return safeprintf_ptrvoid; } //======================================================================================= //default setup is (true,true,false,false) extern void safeprintf_setoptions(bool noisy,bool checkintsize,bool checkintasfloat,bool checkintunsigned); extern ESafePrintfType safeprintf_fmttype(const char fmt, bool wide); extern const char * safeprintf_fmtskipwidth(const char * ptr, bool * pWide); extern ESafePrintfType safeprintf_findfmtandadvance(const char ** ptr); extern void safeprintf_throwerror(const char *fmt_base,const char *fmt,ESafePrintfType fmttype,ESafePrintfType argtype); extern void safeprintf_throwsyntaxerror(const char *fmt_base,const char *fmt); template < typename t_arg > inline const char * checkarg(const char *fmt_base,const char *fmt,const t_arg & arg) { if ( ! fmt ) return NULL; const char * ptr = fmt; ESafePrintfType fmttype = safeprintf_findfmtandadvance(&ptr); // it's perfectly valid to just not have %'s for your args if ( fmttype == safeprintf_none ) { return NULL; } else if ( fmttype == safeprintf_unknown ) { // syntax error failure (failed to parse a type from % in fmt) safeprintf_throwsyntaxerror(fmt_base,fmt); } else { ESafePrintfType argtype = safeprintf_type(arg); if ( fmttype != argtype ) { safeprintf_throwerror(fmt_base,fmt,fmttype,argtype); } } return ptr; } //============================================================================================= //END_CB /** "String" is a COW String, so you can share it easily and not waste memory. String is basically a smart pointer to the char data. WARNING : String is NOT thread safe! Any usage of Strings that may be shared across threads must be manually protected with critical sections. The biggest advantage of COW is that it makes vector< String > much more efficient, due to the many uses of operator= (COW is a huge optimization for operator=) Also you can just pass it around by value and any function in the chain can modify a copy (or not) and it's all fast ----------------- NOTE : using temporary stack Strings as arguments to printf() and such is indeed perfectly safe, because C++ says that temporary returned objects live until the whole line finishes, so you can do printf("%s",TempString().CStr()); ----------------- I specifically do NOT provide operator char * and other such unsafe conversions. ----------------- NOTE : you can hammer on the char data of the string all you want AS LONG AS YOU DONT CHANGE LENGTH. Any adding or removing of nulls must be done through the APIs (Append/Truncate/etc.) **/ //APF_NS_START //template class vector; //typedef vector vector_char; struct StringData; /* namespace std { template class vector; }; */ class String { public: enum EEmpty { eEmpty }; enum EReserve { eReserve }; enum ESubString { eSubString }; enum EConcat { eConcat }; enum EPrintf { ePrintf }; String(); // makes an empty string. String( const String &str ); explicit String( const EEmpty e ); explicit String( const char *const pStr ); //explicit String( const char c ); explicit String( const EReserve e, const int reserve ); // @@ this ePrintf sucks, but if I don't do it it makes the basic char * constructor // ambiguous; I could get rid of that and always go through here, but that's lame too //explicit String( const EPrintf e, const char *format, ... ); String( const EReserve e, const char * const pStr, const int reserve); String( const ESubString e, const char * const pStr, const int len); String( const EConcat e, const char * const pStr1, const char * const pStr2); ~String(); /** Return a reference to an empty String. */ static const String& GetEmpty(); bool IsEmpty() const { return Length() == 0; } // Assigns : void Set( const char *const pStr ); void operator =(const String& str); void operator =( const char * const pStr ) { Set(pStr); } //Appends void Append( const char *const pStr ); void Append( const char c); void Append( const String &str) { Append(str.CStr()); } //Insert : void Insert(const int at, const char *const pStr ); void Insert(const int at, const char c); //void Insert(const int at, const String &str) { Append(str.CStr()); } void operator +=( const char * const pStr ) { Append(pStr); } void operator +=( const String &str ) { Append(str); } void operator +=( const char c ) { Append(c); } // call Printf() or CatPrintf() // they will redirect to these void rawPrintf( const char *format, ... ); // catprintf sticks it on the back void rawCatPrintf( const char *format, ... ); // convert pointer in me to an Index (throws if bad) int Index(const char * ptr) const; char GetChar( const int index ) const; char operator []( const int index ) const; // SetCharProxy handles doing str[i] = 0; class SetCharProxy; SetCharProxy operator []( const int index ); char operator []( const char * ptr ) const; SetCharProxy operator []( const char * ptr ); char PopBack(); void Truncate( const int newLength ); //! SetChar(index,0) truncates to length "index" //! Truncate takes care of truncation. void SetChar( const int index, const char c ); // Split is like SetChar(index,0) - returns the tail that's cut off String Split( const int index ); //Comparisons bool operator ==( const String &str ) const; bool operator !=( const String &str ) const; bool operator < ( const String &str ) const; bool operator ==( const char *const pStr ) const; bool operator !=( const char *const pStr ) const; bool operator < ( const char *const pStr ) const; //! Change the amount reserved for string. //! Does not truncate void Reserve( const int amount ); //! @name Get at the string in a (const char *) kind of way const char *CStr( void ) const; // WriteableCStr : do NOT set nulls ! // eh. actually you CAN set nulls, but if you do, then do not call any String() interfaces // until you call FixLength // eg. : // char * buf = str.WriteableCStr(maxlength); // .. jam on buf but do not touch str ! .. // str.FixLength(); char * WriteableCStr( int size = 0 ); void FixLength(); // CB - try the automatic conversion and see how it works out // this is horrific, it allows conversion of String to bool !! //const char * operator ()() const { return CStr(); } //operator const char * () const { return CStr(); } //! The length in chars till the first 0 or the end of the buffer int Length( void ) const; //! The length of the buffer int Capacity( void ) const; void Clear(); void Release(); bool IsValid() const; // fast swap : //void Swap(String * pOther); //void Swap(String & rhs); /* void WriteBinary(FILE * fp) const; void ReadBinary(FILE * fp); void WriteText(FILE * fp) const; // just writes the string, no delimiters //void ReadText(FILE * fp); */ /* // Printf & CatPrintf : #define SPI_SAFEDECL void Printf #define SPI_CALLRAW rawPrintf #define SPI_PREARG #define SPI_CALLARG fmt #define SPI_BADRETURN #include "safeprintf.inc" #undef SPI_SAFEDECL #undef SPI_CALLRAW #undef SPI_PREARG #undef SPI_CALLARG #undef SPI_BADRETURN #define SPI_SAFEDECL void CatPrintf #define SPI_CALLRAW rawCatPrintf #define SPI_PREARG #define SPI_CALLARG fmt #define SPI_BADRETURN #include "safeprintf.inc" #undef SPI_SAFEDECL #undef SPI_CALLRAW #undef SPI_PREARG #undef SPI_CALLARG #undef SPI_BADRETURN */ private: StringData * m_pData; const std::vector & Readable() const; std::vector & Writeable(); std::vector & WriteableEmpty(const int reserve = 16); }; //--------------------------------------------------------------------------- class String::SetCharProxy { public: SetCharProxy(String * str,const int i) : m_str(str), m_index(i) { } operator char () const { return m_str->GetChar(m_index); } void operator = (const char c) { m_str->SetChar( m_index, c ); } void operator = (const String::SetCharProxy & rhs) { const char c = rhs; *this = c; } private: String * m_str; int m_index; }; //--------------------------------------------------------------------------- bool operator ==( const char * const pStr, const String &str ); bool operator !=( const char * const pStr, const String &str ); bool operator < ( const char * const pStr, const String &str ); // non-member Cat functions inline const String operator +(const String & s1,const String & s2) { return String(String::eConcat,s1.CStr(),s2.CStr()); } inline const String operator +(const String & s1,const char * s2) { return String(String::eConcat,s1.CStr(),s2); } inline const String operator +(const char * s1,const String & s2) { return String(String::eConcat,s1,s2.CStr()); } inline char String::operator []( const int i ) const { return GetChar(i); } inline String::SetCharProxy String::operator [] (const int i) { return SetCharProxy(this,i); } inline char String::operator []( const char * ptr ) const { return GetChar( Index(ptr) ); } inline String::SetCharProxy String::operator []( const char * ptr ) { return SetCharProxy(this, Index(ptr) ); } /* inline bool LessI(const String &s1,const String &s2) { return stricmp(s1.CStr(),s2.CStr()) < 0; } inline bool EqualsI(const String &s1,const String &s2) { return strisame(s1.CStr(),s2.CStr()); } struct LessIFunc // : public binary_function { bool operator() (const String &s1,const String &s2) const { return LessI(s1,s2); } }; */ String StringPrintf(const char *fmt, ...); /* #define SPI_SAFEDECL String StringPrintf #define SPI_CALLRAW return rawStringPrintf #define SPI_PREARG #define SPI_CALLARG fmt #define SPI_BADRETURN return String("invalid"); #include "safeprintf.inc" #undef SPI_SAFEDECL #undef SPI_CALLRAW #undef SPI_PREARG #undef SPI_CALLARG #undef SPI_BADRETURN */ //========================================================================================================= // helper - set mode for wchar conversion to chars : extern void autoPrintfSetWCharAnsi(bool ansi); // else console extern String autoPrintfWChar(const wchar_t * ws); extern void MakeAutoPrintfINL(); //========================================================================================================= template inline const String ToString( T1 arg1 ); // base template is unimplemented - this gives you a compile time error if you try to ToString something unhandled /* { return String("UNKNOWN TYPE"); } */ //template <> inline const String ToString( char * arg1 ) { return String(arg1); } //template <> inline const String ToString( wchar_t * arg1 ) { return autoPrintfWChar(arg1); } //template <> inline const String ToString( const String rhs ) { return rhs; } // @@ TODO : these ToStrings are a lot slower & fatter than necessary //template <> inline const String ToString(const int i) { char temp[20]; itoa(i,temp,10); return String(temp); } //template <> inline const String ToString( __int64 i ) { return StringPrintf("%" FMT_I64 "d",i); } //template <> inline const String ToString( unsigned int i ) { return StringPrintf("%u",i); } //template <> inline const String ToString( unsigned __int64 i ) { return StringPrintf("%" FMT_I64 "u",i); } //template <> inline const String ToString( float f ) { return StringPrintf("%f",f); } //template <> inline const String ToString( double f ) { return StringPrintf("%f",f); } //template <> inline const String ToString( void * p ) { return StringPrintf("%p",p); } //=========================================================================== /* inline ESafePrintfType safeprintf_type( const String rhs ) { return safeprintf_cbstring; } */ //=========================================================================== // autoArgConvert changes types into printf-able type // if arg is a basic type it is passed through untouched // otherwise ToString() is called on it template inline String autoArgConvert( T arg ) { return ToString(arg); } //template <> inline int autoArgConvert(const int arg) { return arg; } //template <> inline char autoArgConvert(const char arg) { return arg; } //template <> inline short autoArgConvert(const short arg) { return arg; } //template <> inline long autoArgConvert(const long arg) { return arg; } //template <> inline __int64 autoArgConvert(const __int64 arg) { return arg; } //template <> inline unsigned int autoArgConvert(const unsigned int arg) { return arg; } //template <> inline unsigned char autoArgConvert(const unsigned char arg) { return arg; } //template <> inline unsigned short autoArgConvert(const unsigned short arg) { return arg; } //template <> inline unsigned long autoArgConvert(const unsigned long arg) { return arg; } //template <> inline const unsigned __int64 autoArgConvert(const unsigned __int64 arg) { return arg; } //template <> inline const float autoArgConvert(const float arg) { return arg; } //template <> inline const double autoArgConvert(const double arg) { return arg; } //template <> inline const char * autoArgConvert(const char * arg) { return arg; } //template <> inline const wchar_t * autoArgConvert(const wchar_t * arg) { return arg; } //template <> inline char * autoArgConvert(char * arg) { return arg; } //template <> inline wchar_t * autoArgConvert(wchar_t * arg) { return arg; } //template <> inline int * autoArgConvert(int * arg) { return arg; } //template <> inline void * autoArgConvert(void * arg) { return arg; } //=========================================================================== // autoprintf_StringToChar : // converts String to char * // passes through everything else template inline T autoprintf_StringToChar (const T & rhs) { return rhs; } //template <> inline const char * autoprintf_StringToChar (const String & rhs) { return rhs.CStr(); } //=========================================================================== // autoToStringFunc is the big worker function extern String autoToStringFunc(int nArgs, ... ); //=========================================================================== // this defines autoToString : //autoprintf.inl autogen on Aug 23 2010 12:14:31 to 20 max args template < typename T1 > inline String autoToStringSub( T1 arg1) { return autoToStringFunc( 1, safeprintf_type(arg1), arg1, 0 ); } template < typename T1, typename T2 > inline String autoToStringSub( T1 arg1, T2 arg2) { return autoToStringFunc( 2, safeprintf_type(arg1), safeprintf_type(arg2), arg1, arg2, 0 ); } template < typename T1, typename T2, typename T3 > inline String autoToStringSub( T1 arg1, T2 arg2, T3 arg3) { return autoToStringFunc( 3, safeprintf_type(arg1), safeprintf_type(arg2), safeprintf_type(arg3), arg1, arg2, arg3, 0 ); } template < typename T1, typename T2, typename T3, typename T4 > inline String autoToStringSub( T1 arg1, T2 arg2, T3 arg3, T4 arg4) { return autoToStringFunc( 4, safeprintf_type(arg1), safeprintf_type(arg2), safeprintf_type(arg3), safeprintf_type(arg4), arg1, arg2, arg3, arg4, 0 ); } template < typename T1, typename T2, typename T3, typename T4, typename T5 > inline String autoToStringSub( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { return autoToStringFunc( 5, safeprintf_type(arg1), safeprintf_type(arg2), safeprintf_type(arg3), safeprintf_type(arg4), safeprintf_type(arg5), arg1, arg2, arg3, arg4, arg5, 0 ); } template < typename T1, typename T2, typename T3, typename T4, typename T5, typename T6 > inline String autoToStringSub( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { return autoToStringFunc( 6, safeprintf_type(arg1), safeprintf_type(arg2), safeprintf_type(arg3), safeprintf_type(arg4), safeprintf_type(arg5), safeprintf_type(arg6), arg1, arg2, arg3, arg4, arg5, arg6, 0 ); } template < typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7 > inline String autoToStringSub( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { return autoToStringFunc( 7, safeprintf_type(arg1), safeprintf_type(arg2), safeprintf_type(arg3), safeprintf_type(arg4), safeprintf_type(arg5), safeprintf_type(arg6), safeprintf_type(arg7), arg1, arg2, arg3, arg4, arg5, arg6, arg7, 0 ); } template < typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8 > inline String autoToStringSub( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { return autoToStringFunc( 8, safeprintf_type(arg1), safeprintf_type(arg2), safeprintf_type(arg3), safeprintf_type(arg4), safeprintf_type(arg5), safeprintf_type(arg6), safeprintf_type(arg7), safeprintf_type(arg8), arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, 0 ); } template < typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9 > inline String autoToStringSub( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { return autoToStringFunc( 9, safeprintf_type(arg1), safeprintf_type(arg2), safeprintf_type(arg3), safeprintf_type(arg4), safeprintf_type(arg5), safeprintf_type(arg6), safeprintf_type(arg7), safeprintf_type(arg8), safeprintf_type(arg9), arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, 0 ); } template < typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10 > inline String autoToStringSub( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { return autoToStringFunc( 10, safeprintf_type(arg1), safeprintf_type(arg2), safeprintf_type(arg3), safeprintf_type(arg4), safeprintf_type(arg5), safeprintf_type(arg6), safeprintf_type(arg7), safeprintf_type(arg8), safeprintf_type(arg9), safeprintf_type(arg10), arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, 0 ); } template < typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11 > inline String autoToStringSub( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { return autoToStringFunc( 11, safeprintf_type(arg1), safeprintf_type(arg2), safeprintf_type(arg3), safeprintf_type(arg4), safeprintf_type(arg5), safeprintf_type(arg6), safeprintf_type(arg7), safeprintf_type(arg8), safeprintf_type(arg9), safeprintf_type(arg10), safeprintf_type(arg11), arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, 0 ); } template < typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12 > inline String autoToStringSub( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { return autoToStringFunc( 12, safeprintf_type(arg1), safeprintf_type(arg2), safeprintf_type(arg3), safeprintf_type(arg4), safeprintf_type(arg5), safeprintf_type(arg6), safeprintf_type(arg7), safeprintf_type(arg8), safeprintf_type(arg9), safeprintf_type(arg10), safeprintf_type(arg11), safeprintf_type(arg12), arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, 0 ); } template < typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename T13 > inline String autoToStringSub( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { return autoToStringFunc( 13, safeprintf_type(arg1), safeprintf_type(arg2), safeprintf_type(arg3), safeprintf_type(arg4), safeprintf_type(arg5), safeprintf_type(arg6), safeprintf_type(arg7), safeprintf_type(arg8), safeprintf_type(arg9), safeprintf_type(arg10), safeprintf_type(arg11), safeprintf_type(arg12), safeprintf_type(arg13), arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, 0 ); } template < typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename T13, typename T14 > inline String autoToStringSub( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { return autoToStringFunc( 14, safeprintf_type(arg1), safeprintf_type(arg2), safeprintf_type(arg3), safeprintf_type(arg4), safeprintf_type(arg5), safeprintf_type(arg6), safeprintf_type(arg7), safeprintf_type(arg8), safeprintf_type(arg9), safeprintf_type(arg10), safeprintf_type(arg11), safeprintf_type(arg12), safeprintf_type(arg13), safeprintf_type(arg14), arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, 0 ); } template < typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename T13, typename T14, typename T15 > inline String autoToStringSub( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { return autoToStringFunc( 15, safeprintf_type(arg1), safeprintf_type(arg2), safeprintf_type(arg3), safeprintf_type(arg4), safeprintf_type(arg5), safeprintf_type(arg6), safeprintf_type(arg7), safeprintf_type(arg8), safeprintf_type(arg9), safeprintf_type(arg10), safeprintf_type(arg11), safeprintf_type(arg12), safeprintf_type(arg13), safeprintf_type(arg14), safeprintf_type(arg15), arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, 0 ); } template < typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename T13, typename T14, typename T15, typename T16 > inline String autoToStringSub( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) { return autoToStringFunc( 16, safeprintf_type(arg1), safeprintf_type(arg2), safeprintf_type(arg3), safeprintf_type(arg4), safeprintf_type(arg5), safeprintf_type(arg6), safeprintf_type(arg7), safeprintf_type(arg8), safeprintf_type(arg9), safeprintf_type(arg10), safeprintf_type(arg11), safeprintf_type(arg12), safeprintf_type(arg13), safeprintf_type(arg14), safeprintf_type(arg15), safeprintf_type(arg16), arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, 0 ); } template < typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename T13, typename T14, typename T15, typename T16, typename T17 > inline String autoToStringSub( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16, T17 arg17) { return autoToStringFunc( 17, safeprintf_type(arg1), safeprintf_type(arg2), safeprintf_type(arg3), safeprintf_type(arg4), safeprintf_type(arg5), safeprintf_type(arg6), safeprintf_type(arg7), safeprintf_type(arg8), safeprintf_type(arg9), safeprintf_type(arg10), safeprintf_type(arg11), safeprintf_type(arg12), safeprintf_type(arg13), safeprintf_type(arg14), safeprintf_type(arg15), safeprintf_type(arg16), safeprintf_type(arg17), arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, 0 ); } template < typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename T13, typename T14, typename T15, typename T16, typename T17, typename T18 > inline String autoToStringSub( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16, T17 arg17, T18 arg18) { return autoToStringFunc( 18, safeprintf_type(arg1), safeprintf_type(arg2), safeprintf_type(arg3), safeprintf_type(arg4), safeprintf_type(arg5), safeprintf_type(arg6), safeprintf_type(arg7), safeprintf_type(arg8), safeprintf_type(arg9), safeprintf_type(arg10), safeprintf_type(arg11), safeprintf_type(arg12), safeprintf_type(arg13), safeprintf_type(arg14), safeprintf_type(arg15), safeprintf_type(arg16), safeprintf_type(arg17), safeprintf_type(arg18), arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, 0 ); } template < typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename T13, typename T14, typename T15, typename T16, typename T17, typename T18, typename T19 > inline String autoToStringSub( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16, T17 arg17, T18 arg18, T19 arg19) { return autoToStringFunc( 19, safeprintf_type(arg1), safeprintf_type(arg2), safeprintf_type(arg3), safeprintf_type(arg4), safeprintf_type(arg5), safeprintf_type(arg6), safeprintf_type(arg7), safeprintf_type(arg8), safeprintf_type(arg9), safeprintf_type(arg10), safeprintf_type(arg11), safeprintf_type(arg12), safeprintf_type(arg13), safeprintf_type(arg14), safeprintf_type(arg15), safeprintf_type(arg16), safeprintf_type(arg17), safeprintf_type(arg18), safeprintf_type(arg19), arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19, 0 ); } template < typename T1 > inline String autoToString( T1 arg1) { return autoToStringSub( autoprintf_StringToChar( autoArgConvert(arg1) )); } template < typename T1, typename T2 > inline String autoToString( T1 arg1, T2 arg2) { return autoToStringSub( autoprintf_StringToChar( autoArgConvert(arg1) ), autoprintf_StringToChar( autoArgConvert(arg2) )); } template < typename T1, typename T2, typename T3 > inline String autoToString( T1 arg1, T2 arg2, T3 arg3) { return autoToStringSub( autoprintf_StringToChar( autoArgConvert(arg1) ), autoprintf_StringToChar( autoArgConvert(arg2) ), autoprintf_StringToChar( autoArgConvert(arg3) )); } template < typename T1, typename T2, typename T3, typename T4 > inline String autoToString( T1 arg1, T2 arg2, T3 arg3, T4 arg4) { return autoToStringSub( autoprintf_StringToChar( autoArgConvert(arg1) ), autoprintf_StringToChar( autoArgConvert(arg2) ), autoprintf_StringToChar( autoArgConvert(arg3) ), autoprintf_StringToChar( autoArgConvert(arg4) )); } template < typename T1, typename T2, typename T3, typename T4, typename T5 > inline String autoToString( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { return autoToStringSub( autoprintf_StringToChar( autoArgConvert(arg1) ), autoprintf_StringToChar( autoArgConvert(arg2) ), autoprintf_StringToChar( autoArgConvert(arg3) ), autoprintf_StringToChar( autoArgConvert(arg4) ), autoprintf_StringToChar( autoArgConvert(arg5) )); } template < typename T1, typename T2, typename T3, typename T4, typename T5, typename T6 > inline String autoToString( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { return autoToStringSub( autoprintf_StringToChar( autoArgConvert(arg1) ), autoprintf_StringToChar( autoArgConvert(arg2) ), autoprintf_StringToChar( autoArgConvert(arg3) ), autoprintf_StringToChar( autoArgConvert(arg4) ), autoprintf_StringToChar( autoArgConvert(arg5) ), autoprintf_StringToChar( autoArgConvert(arg6) )); } template < typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7 > inline String autoToString( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { return autoToStringSub( autoprintf_StringToChar( autoArgConvert(arg1) ), autoprintf_StringToChar( autoArgConvert(arg2) ), autoprintf_StringToChar( autoArgConvert(arg3) ), autoprintf_StringToChar( autoArgConvert(arg4) ), autoprintf_StringToChar( autoArgConvert(arg5) ), autoprintf_StringToChar( autoArgConvert(arg6) ), autoprintf_StringToChar( autoArgConvert(arg7) )); } template < typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8 > inline String autoToString( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { return autoToStringSub( autoprintf_StringToChar( autoArgConvert(arg1) ), autoprintf_StringToChar( autoArgConvert(arg2) ), autoprintf_StringToChar( autoArgConvert(arg3) ), autoprintf_StringToChar( autoArgConvert(arg4) ), autoprintf_StringToChar( autoArgConvert(arg5) ), autoprintf_StringToChar( autoArgConvert(arg6) ), autoprintf_StringToChar( autoArgConvert(arg7) ), autoprintf_StringToChar( autoArgConvert(arg8) )); } template < typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9 > inline String autoToString( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { return autoToStringSub( autoprintf_StringToChar( autoArgConvert(arg1) ), autoprintf_StringToChar( autoArgConvert(arg2) ), autoprintf_StringToChar( autoArgConvert(arg3) ), autoprintf_StringToChar( autoArgConvert(arg4) ), autoprintf_StringToChar( autoArgConvert(arg5) ), autoprintf_StringToChar( autoArgConvert(arg6) ), autoprintf_StringToChar( autoArgConvert(arg7) ), autoprintf_StringToChar( autoArgConvert(arg8) ), autoprintf_StringToChar( autoArgConvert(arg9) )); } template < typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10 > inline String autoToString( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { return autoToStringSub( autoprintf_StringToChar( autoArgConvert(arg1) ), autoprintf_StringToChar( autoArgConvert(arg2) ), autoprintf_StringToChar( autoArgConvert(arg3) ), autoprintf_StringToChar( autoArgConvert(arg4) ), autoprintf_StringToChar( autoArgConvert(arg5) ), autoprintf_StringToChar( autoArgConvert(arg6) ), autoprintf_StringToChar( autoArgConvert(arg7) ), autoprintf_StringToChar( autoArgConvert(arg8) ), autoprintf_StringToChar( autoArgConvert(arg9) ), autoprintf_StringToChar( autoArgConvert(arg10) )); } template < typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11 > inline String autoToString( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { return autoToStringSub( autoprintf_StringToChar( autoArgConvert(arg1) ), autoprintf_StringToChar( autoArgConvert(arg2) ), autoprintf_StringToChar( autoArgConvert(arg3) ), autoprintf_StringToChar( autoArgConvert(arg4) ), autoprintf_StringToChar( autoArgConvert(arg5) ), autoprintf_StringToChar( autoArgConvert(arg6) ), autoprintf_StringToChar( autoArgConvert(arg7) ), autoprintf_StringToChar( autoArgConvert(arg8) ), autoprintf_StringToChar( autoArgConvert(arg9) ), autoprintf_StringToChar( autoArgConvert(arg10) ), autoprintf_StringToChar( autoArgConvert(arg11) )); } template < typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12 > inline String autoToString( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { return autoToStringSub( autoprintf_StringToChar( autoArgConvert(arg1) ), autoprintf_StringToChar( autoArgConvert(arg2) ), autoprintf_StringToChar( autoArgConvert(arg3) ), autoprintf_StringToChar( autoArgConvert(arg4) ), autoprintf_StringToChar( autoArgConvert(arg5) ), autoprintf_StringToChar( autoArgConvert(arg6) ), autoprintf_StringToChar( autoArgConvert(arg7) ), autoprintf_StringToChar( autoArgConvert(arg8) ), autoprintf_StringToChar( autoArgConvert(arg9) ), autoprintf_StringToChar( autoArgConvert(arg10) ), autoprintf_StringToChar( autoArgConvert(arg11) ), autoprintf_StringToChar( autoArgConvert(arg12) )); } template < typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename T13 > inline String autoToString( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { return autoToStringSub( autoprintf_StringToChar( autoArgConvert(arg1) ), autoprintf_StringToChar( autoArgConvert(arg2) ), autoprintf_StringToChar( autoArgConvert(arg3) ), autoprintf_StringToChar( autoArgConvert(arg4) ), autoprintf_StringToChar( autoArgConvert(arg5) ), autoprintf_StringToChar( autoArgConvert(arg6) ), autoprintf_StringToChar( autoArgConvert(arg7) ), autoprintf_StringToChar( autoArgConvert(arg8) ), autoprintf_StringToChar( autoArgConvert(arg9) ), autoprintf_StringToChar( autoArgConvert(arg10) ), autoprintf_StringToChar( autoArgConvert(arg11) ), autoprintf_StringToChar( autoArgConvert(arg12) ), autoprintf_StringToChar( autoArgConvert(arg13) )); } template < typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename T13, typename T14 > inline String autoToString( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { return autoToStringSub( autoprintf_StringToChar( autoArgConvert(arg1) ), autoprintf_StringToChar( autoArgConvert(arg2) ), autoprintf_StringToChar( autoArgConvert(arg3) ), autoprintf_StringToChar( autoArgConvert(arg4) ), autoprintf_StringToChar( autoArgConvert(arg5) ), autoprintf_StringToChar( autoArgConvert(arg6) ), autoprintf_StringToChar( autoArgConvert(arg7) ), autoprintf_StringToChar( autoArgConvert(arg8) ), autoprintf_StringToChar( autoArgConvert(arg9) ), autoprintf_StringToChar( autoArgConvert(arg10) ), autoprintf_StringToChar( autoArgConvert(arg11) ), autoprintf_StringToChar( autoArgConvert(arg12) ), autoprintf_StringToChar( autoArgConvert(arg13) ), autoprintf_StringToChar( autoArgConvert(arg14) )); } template < typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename T13, typename T14, typename T15 > inline String autoToString( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { return autoToStringSub( autoprintf_StringToChar( autoArgConvert(arg1) ), autoprintf_StringToChar( autoArgConvert(arg2) ), autoprintf_StringToChar( autoArgConvert(arg3) ), autoprintf_StringToChar( autoArgConvert(arg4) ), autoprintf_StringToChar( autoArgConvert(arg5) ), autoprintf_StringToChar( autoArgConvert(arg6) ), autoprintf_StringToChar( autoArgConvert(arg7) ), autoprintf_StringToChar( autoArgConvert(arg8) ), autoprintf_StringToChar( autoArgConvert(arg9) ), autoprintf_StringToChar( autoArgConvert(arg10) ), autoprintf_StringToChar( autoArgConvert(arg11) ), autoprintf_StringToChar( autoArgConvert(arg12) ), autoprintf_StringToChar( autoArgConvert(arg13) ), autoprintf_StringToChar( autoArgConvert(arg14) ), autoprintf_StringToChar( autoArgConvert(arg15) )); } template < typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename T13, typename T14, typename T15, typename T16 > inline String autoToString( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) { return autoToStringSub( autoprintf_StringToChar( autoArgConvert(arg1) ), autoprintf_StringToChar( autoArgConvert(arg2) ), autoprintf_StringToChar( autoArgConvert(arg3) ), autoprintf_StringToChar( autoArgConvert(arg4) ), autoprintf_StringToChar( autoArgConvert(arg5) ), autoprintf_StringToChar( autoArgConvert(arg6) ), autoprintf_StringToChar( autoArgConvert(arg7) ), autoprintf_StringToChar( autoArgConvert(arg8) ), autoprintf_StringToChar( autoArgConvert(arg9) ), autoprintf_StringToChar( autoArgConvert(arg10) ), autoprintf_StringToChar( autoArgConvert(arg11) ), autoprintf_StringToChar( autoArgConvert(arg12) ), autoprintf_StringToChar( autoArgConvert(arg13) ), autoprintf_StringToChar( autoArgConvert(arg14) ), autoprintf_StringToChar( autoArgConvert(arg15) ), autoprintf_StringToChar( autoArgConvert(arg16) )); } template < typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename T13, typename T14, typename T15, typename T16, typename T17 > inline String autoToString( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16, T17 arg17) { return autoToStringSub( autoprintf_StringToChar( autoArgConvert(arg1) ), autoprintf_StringToChar( autoArgConvert(arg2) ), autoprintf_StringToChar( autoArgConvert(arg3) ), autoprintf_StringToChar( autoArgConvert(arg4) ), autoprintf_StringToChar( autoArgConvert(arg5) ), autoprintf_StringToChar( autoArgConvert(arg6) ), autoprintf_StringToChar( autoArgConvert(arg7) ), autoprintf_StringToChar( autoArgConvert(arg8) ), autoprintf_StringToChar( autoArgConvert(arg9) ), autoprintf_StringToChar( autoArgConvert(arg10) ), autoprintf_StringToChar( autoArgConvert(arg11) ), autoprintf_StringToChar( autoArgConvert(arg12) ), autoprintf_StringToChar( autoArgConvert(arg13) ), autoprintf_StringToChar( autoArgConvert(arg14) ), autoprintf_StringToChar( autoArgConvert(arg15) ), autoprintf_StringToChar( autoArgConvert(arg16) ), autoprintf_StringToChar( autoArgConvert(arg17) )); } template < typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename T13, typename T14, typename T15, typename T16, typename T17, typename T18 > inline String autoToString( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16, T17 arg17, T18 arg18) { return autoToStringSub( autoprintf_StringToChar( autoArgConvert(arg1) ), autoprintf_StringToChar( autoArgConvert(arg2) ), autoprintf_StringToChar( autoArgConvert(arg3) ), autoprintf_StringToChar( autoArgConvert(arg4) ), autoprintf_StringToChar( autoArgConvert(arg5) ), autoprintf_StringToChar( autoArgConvert(arg6) ), autoprintf_StringToChar( autoArgConvert(arg7) ), autoprintf_StringToChar( autoArgConvert(arg8) ), autoprintf_StringToChar( autoArgConvert(arg9) ), autoprintf_StringToChar( autoArgConvert(arg10) ), autoprintf_StringToChar( autoArgConvert(arg11) ), autoprintf_StringToChar( autoArgConvert(arg12) ), autoprintf_StringToChar( autoArgConvert(arg13) ), autoprintf_StringToChar( autoArgConvert(arg14) ), autoprintf_StringToChar( autoArgConvert(arg15) ), autoprintf_StringToChar( autoArgConvert(arg16) ), autoprintf_StringToChar( autoArgConvert(arg17) ), autoprintf_StringToChar( autoArgConvert(arg18) )); } template < typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename T13, typename T14, typename T15, typename T16, typename T17, typename T18, typename T19 > inline String autoToString( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16, T17 arg17, T18 arg18, T19 arg19) { return autoToStringSub( autoprintf_StringToChar( autoArgConvert(arg1) ), autoprintf_StringToChar( autoArgConvert(arg2) ), autoprintf_StringToChar( autoArgConvert(arg3) ), autoprintf_StringToChar( autoArgConvert(arg4) ), autoprintf_StringToChar( autoArgConvert(arg5) ), autoprintf_StringToChar( autoArgConvert(arg6) ), autoprintf_StringToChar( autoArgConvert(arg7) ), autoprintf_StringToChar( autoArgConvert(arg8) ), autoprintf_StringToChar( autoArgConvert(arg9) ), autoprintf_StringToChar( autoArgConvert(arg10) ), autoprintf_StringToChar( autoArgConvert(arg11) ), autoprintf_StringToChar( autoArgConvert(arg12) ), autoprintf_StringToChar( autoArgConvert(arg13) ), autoprintf_StringToChar( autoArgConvert(arg14) ), autoprintf_StringToChar( autoArgConvert(arg15) ), autoprintf_StringToChar( autoArgConvert(arg16) ), autoprintf_StringToChar( autoArgConvert(arg17) ), autoprintf_StringToChar( autoArgConvert(arg18) ), autoprintf_StringToChar( autoArgConvert(arg19) )); } //=========================================================================== // adapters to convert autoToString to class autoprintf_PrintString { public: void operator << (const String & rhs) { fputs(rhs.CStr(),stdout); } }; //APF_NS_END }; // namespace apf //=========================================================================== /*************************************************************** some stuff in apf namespace that you might want to call : extern void safeprintf_setoptions(bool noisy,bool checkintsize,bool checkintasfloat,bool checkintunsigned); extern void autoPrintfSetWCharAnsi(bool ansi); // else console *************************************************/ // Global namespace : #define autoprintf apf::autoprintf_PrintString() << apf::autoToString // autoprintfsub.inc can be included to make anything // into autoprintf // here we provide : // autosprintf // autosnprintf // autofprintf #define APF_CALLER autosprintf #define APF_CALLER_PREARG char * toString, #define APF_CALL_SUB(s) strcpy( toString, s.CStr() ) #include "apf.inc" #undef APF_CALLER #undef APF_CALLER_PREARG #undef APF_CALL_SUB #define APF_CALLER autosnprintf #define APF_CALLER_PREARG char * toString, int toStringSize, #define APF_CALL_SUB(s) apf::strlcpy( toString, s.CStr() , toStringSize) #include "apf.inc" #undef APF_CALLER #undef APF_CALLER_PREARG #undef APF_CALL_SUB #define APF_CALLER autofprintf #define APF_CALLER_PREARG FILE * toFile, #define APF_CALL_SUB(s) fputs( s.CStr() , toFile ) #include "apf.inc" #undef APF_CALLER #undef APF_CALLER_PREARG #undef APF_CALL_SUB //===========================================================================