| 310 | /// conversions. |
| 311 | template<typename T> |
| 312 | inline void formatValue(std::ostream& out, const char* /*fmtBegin*/, |
| 313 | const char* fmtEnd, int ntrunc, const T& value) |
| 314 | { |
| 315 | #ifndef TINYFORMAT_ALLOW_WCHAR_STRINGS |
| 316 | // Since we don't support printing of wchar_t using "%ls", make it fail at |
| 317 | // compile time in preference to printing as a void* at runtime. |
| 318 | typedef typename detail::is_wchar<T>::tinyformat_wchar_is_not_supported DummyType; |
| 319 | (void) DummyType(); // avoid unused type warning with gcc-4.8 |
| 320 | #endif |
| 321 | // The mess here is to support the %c and %p conversions: if these |
| 322 | // conversions are active we try to convert the type to a char or const |
| 323 | // void* respectively and format that instead of the value itself. For the |
| 324 | // %p conversion it's important to avoid dereferencing the pointer, which |
| 325 | // could otherwise lead to a crash when printing a dangling (const char*). |
| 326 | const bool canConvertToChar = detail::is_convertible<T,char>::value; |
| 327 | const bool canConvertToVoidPtr = detail::is_convertible<T, const void*>::value; |
| 328 | if(canConvertToChar && *(fmtEnd-1) == 'c') |
| 329 | detail::formatValueAsType<T, char>::invoke(out, value); |
| 330 | else if(canConvertToVoidPtr && *(fmtEnd-1) == 'p') |
| 331 | detail::formatValueAsType<T, const void*>::invoke(out, value); |
| 332 | #ifdef TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND |
| 333 | else if(detail::formatZeroIntegerWorkaround<T>::invoke(out, value)) /**/; |
| 334 | #endif |
| 335 | else if(ntrunc >= 0) |
| 336 | { |
| 337 | // Take care not to overread C strings in truncating conversions like |
| 338 | // "%.4s" where at most 4 characters may be read. |
| 339 | detail::formatTruncated(out, value, ntrunc); |
| 340 | } |
| 341 | else |
| 342 | out << value; |
| 343 | } |
| 344 | |
| 345 | |
| 346 | // Overloaded version for char types to support printing as an integer |
nothing calls this directly
no test coverage detected