1 /*
2 * Created by Phil on 23/4/2014.
3 * Copyright 2014 Two Blue Cubes Ltd. All rights reserved.
4 *
5 * Distributed under the Boost Software License, Version 1.0. (See accompanying
6 * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 */
8 #ifndef TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED
9 #define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED
10
11 #include "catch_tostring.h"
12 #include "catch_interfaces_config.h"
13
14 namespace Catch {
15
16 namespace Detail {
17
18 const std::string unprintableString = "{?}";
19
20 namespace {
21 const int hexThreshold = 255;
22
23 struct Endianness {
24 enum Arch { Big, Little };
25
whichCatch::Detail::__anona54083a30111::Endianness26 static Arch which() {
27 union _{
28 int asInt;
29 char asChar[sizeof (int)];
30 } u;
31
32 u.asInt = 1;
33 return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
34 }
35 };
36 }
37
rawMemoryToString(const void * object,std::size_t size)38 std::string rawMemoryToString( const void *object, std::size_t size )
39 {
40 // Reverse order for little endian architectures
41 int i = 0, end = static_cast<int>( size ), inc = 1;
42 if( Endianness::which() == Endianness::Little ) {
43 i = end-1;
44 end = inc = -1;
45 }
46
47 unsigned char const *bytes = static_cast<unsigned char const *>(object);
48 std::ostringstream os;
49 os << "0x" << std::setfill('0') << std::hex;
50 for( ; i != end; i += inc )
51 os << std::setw(2) << static_cast<unsigned>(bytes[i]);
52 return os.str();
53 }
54 }
55
toString(std::string const & value)56 std::string toString( std::string const& value ) {
57 std::string s = value;
58 if( getCurrentContext().getConfig()->showInvisibles() ) {
59 for(size_t i = 0; i < s.size(); ++i ) {
60 std::string subs;
61 switch( s[i] ) {
62 case '\n': subs = "\\n"; break;
63 case '\t': subs = "\\t"; break;
64 default: break;
65 }
66 if( !subs.empty() ) {
67 s = s.substr( 0, i ) + subs + s.substr( i+1 );
68 ++i;
69 }
70 }
71 }
72 return '"' + s + '"';
73 }
toString(std::wstring const & value)74 std::string toString( std::wstring const& value ) {
75
76 std::string s;
77 s.reserve( value.size() );
78 for(size_t i = 0; i < value.size(); ++i )
79 s += value[i] <= 0xff ? static_cast<char>( value[i] ) : '?';
80 return Catch::toString( s );
81 }
82
toString(const char * const value)83 std::string toString( const char* const value ) {
84 return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" );
85 }
86
toString(char * const value)87 std::string toString( char* const value ) {
88 return Catch::toString( static_cast<const char*>( value ) );
89 }
90
toString(const wchar_t * const value)91 std::string toString( const wchar_t* const value )
92 {
93 return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" );
94 }
95
toString(wchar_t * const value)96 std::string toString( wchar_t* const value )
97 {
98 return Catch::toString( static_cast<const wchar_t*>( value ) );
99 }
100
toString(int value)101 std::string toString( int value ) {
102 std::ostringstream oss;
103 oss << value;
104 if( value > Detail::hexThreshold )
105 oss << " (0x" << std::hex << value << ')';
106 return oss.str();
107 }
108
toString(unsigned long value)109 std::string toString( unsigned long value ) {
110 std::ostringstream oss;
111 oss << value;
112 if( value > Detail::hexThreshold )
113 oss << " (0x" << std::hex << value << ')';
114 return oss.str();
115 }
116
toString(unsigned int value)117 std::string toString( unsigned int value ) {
118 return Catch::toString( static_cast<unsigned long>( value ) );
119 }
120
121 template<typename T>
fpToString(T value,int precision)122 std::string fpToString( T value, int precision ) {
123 std::ostringstream oss;
124 oss << std::setprecision( precision )
125 << std::fixed
126 << value;
127 std::string d = oss.str();
128 std::size_t i = d.find_last_not_of( '0' );
129 if( i != std::string::npos && i != d.size()-1 ) {
130 if( d[i] == '.' )
131 i++;
132 d = d.substr( 0, i+1 );
133 }
134 return d;
135 }
136
toString(const double value)137 std::string toString( const double value ) {
138 return fpToString( value, 10 );
139 }
toString(const float value)140 std::string toString( const float value ) {
141 return fpToString( value, 5 ) + 'f';
142 }
143
toString(bool value)144 std::string toString( bool value ) {
145 return value ? "true" : "false";
146 }
147
toString(char value)148 std::string toString( char value ) {
149 if ( value == '\r' )
150 return "'\\r'";
151 if ( value == '\f' )
152 return "'\\f'";
153 if ( value == '\n' )
154 return "'\\n'";
155 if ( value == '\t' )
156 return "'\\t'";
157 if ( '\0' <= value && value < ' ' )
158 return toString( static_cast<unsigned int>( value ) );
159 char chstr[] = "' '";
160 chstr[1] = value;
161 return chstr;
162 }
163
toString(signed char value)164 std::string toString( signed char value ) {
165 return toString( static_cast<char>( value ) );
166 }
167
toString(unsigned char value)168 std::string toString( unsigned char value ) {
169 return toString( static_cast<char>( value ) );
170 }
171
172 #ifdef CATCH_CONFIG_CPP11_LONG_LONG
toString(long long value)173 std::string toString( long long value ) {
174 std::ostringstream oss;
175 oss << value;
176 if( value > Detail::hexThreshold )
177 oss << " (0x" << std::hex << value << ')';
178 return oss.str();
179 }
toString(unsigned long long value)180 std::string toString( unsigned long long value ) {
181 std::ostringstream oss;
182 oss << value;
183 if( value > Detail::hexThreshold )
184 oss << " (0x" << std::hex << value << ')';
185 return oss.str();
186 }
187 #endif
188
189 #ifdef CATCH_CONFIG_CPP11_NULLPTR
toString(std::nullptr_t)190 std::string toString( std::nullptr_t ) {
191 return "nullptr";
192 }
193 #endif
194
195 #ifdef __OBJC__
toString(NSString const * const & nsstring)196 std::string toString( NSString const * const& nsstring ) {
197 if( !nsstring )
198 return "nil";
199 return "@" + toString([nsstring UTF8String]);
200 }
toString(NSString * CATCH_ARC_STRONG & nsstring)201 std::string toString( NSString * CATCH_ARC_STRONG & nsstring ) {
202 if( !nsstring )
203 return "nil";
204 return "@" + toString([nsstring UTF8String]);
205 }
toString(NSObject * const & nsObject)206 std::string toString( NSObject* const& nsObject ) {
207 return toString( [nsObject description] );
208 }
209 #endif
210
211 } // end namespace Catch
212
213 #endif // TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED
214