16template <
typename Type>
17class IsStreamInsertable
20 template <
typename CandidateType>
21 static auto test (
int) ->
decltype (
22 std::declval<std::ostream&>() << std::declval<
const CandidateType&>(),
27 static std::false_type test (...);
30 static const bool value =
decltype (test<Type> (42))::value;
34template <
typename Type>
35std::string pointerToString (
const Type* value)
40 std::ostringstream stream;
41 stream <<
"<pointer to 0x" << std::hex <<
reinterpret_cast<std::uintptr_t> (value) <<
'>';
46template <
typename Type>
47std::string objectAddressToString (
const Type& value)
49 std::ostringstream stream;
50 stream <<
"<object at 0x" << std::hex <<
reinterpret_cast<std::uintptr_t> (&value) <<
'>';
55inline std::string toString (
const std::string& value)
57 return '"' + value +
'"';
61inline std::string toString (
const char* value)
66 return '"' + std::string (value) +
'"';
70inline std::string toString (
bool value)
72 return value ==
true ?
"true" :
"false";
77template <
typename Type>
78std::string toString (Type* value)
80 return pointerToString (value);
85template <
typename Type>
86typename std::enable_if<IsStreamInsertable<Type>::value, std::string>::type
87toString (
const Type& value)
89 std::ostringstream stream;
96template <
typename Type>
97typename std::enable_if<! IsStreamInsertable<Type>::value, std::string>::type
98toString (
const Type& value)
100 return objectAddressToString (value);