format: write c_str as %s by default, support c_str as %p

This commit is contained in:
Danny Robson 2016-07-28 14:14:59 +10:00
parent b4640d64d8
commit a40e09ed97
2 changed files with 10 additions and 1 deletions

View File

@ -603,6 +603,12 @@ namespace util { namespace format { namespace detail {
OutputT
write (OutputT os, const specifier spec, const char *t)
{
// we need to forward to the pointer write function rather than the
// other way around to reduce ambiguity and the potential for
// recursion.
if (spec.k == specifier::kind::POINTER)
return write (os, spec, reinterpret_cast<const void*> (t));
if (spec.k != specifier::kind::STRING)
throw conversion_error ("invalid specifier kind for string argumetn");
@ -672,7 +678,7 @@ namespace util { namespace format { namespace detail {
//-------------------------------------------------------------------------
template <typename T, typename OutputT>
std::enable_if_t<
std::is_pointer<T>::value,
std::is_pointer<T>::value && !std::is_same<std::remove_pointer_t<T>, char>::value,
OutputT
>
write (OutputT &os, const specifier &spec, const T t)

View File

@ -112,6 +112,8 @@ main (void)
CHECK_RENDER ("%c", "A", 'A');
CHECK_RENDER ("%s", "foo", "foo");
CHECK_RENDER ("%s", "foo", std::string ("foo"));
CHECK_RENDER ("%s", "foo", const_cast<char*> ("foo"));
CHECK_RENDER ("%.s", "", "foo");
CHECK_RENDER ("%.0s", "", "foo");
CHECK_RENDER ("%.2s", "fo", "foo");
@ -122,6 +124,7 @@ main (void)
CHECK_RENDER ("%p", "0x1234567", (void*)0x01234567);
CHECK_RENDER ("%p", "0x1234567", (int*)0x01234567);
CHECK_RENDER ("%p", "0x1234567", (char*)0x01234567);
CHECK_RENDER ("%p", "(nil)", nullptr);
CHECK_RENDER ("%p", "(nil)", NULL);