1 /* 2 * Copyright (C) 2012 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #ifndef PrintStream_h 27 #define PrintStream_h 28 29 #include <stdarg.h> 30 #include "wtf/FastAllocBase.h" 31 #include "wtf/Noncopyable.h" 32 #include "wtf/StdLibExtras.h" 33 34 namespace WTF { 35 36 class CString; 37 class String; 38 39 class PrintStream { 40 WTF_MAKE_FAST_ALLOCATED; WTF_MAKE_NONCOPYABLE(PrintStream); 41 public: 42 PrintStream(); 43 virtual ~PrintStream(); 44 45 void printf(const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3); 46 virtual void vprintf(const char* format, va_list) WTF_ATTRIBUTE_PRINTF(2, 0) = 0; 47 48 // Typically a no-op for many subclasses of PrintStream, this is a hint that 49 // the implementation should flush its buffers if it had not done so already. 50 virtual void flush(); 51 52 template<typename T> 53 void print(const T& value) 54 { 55 printInternal(*this, value); 56 } 57 58 template<typename T1, typename T2> 59 void print(const T1& value1, const T2& value2) 60 { 61 print(value1); 62 print(value2); 63 } 64 65 template<typename T1, typename T2, typename T3> 66 void print(const T1& value1, const T2& value2, const T3& value3) 67 { 68 print(value1); 69 print(value2); 70 print(value3); 71 } 72 73 template<typename T1, typename T2, typename T3, typename T4> 74 void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4) 75 { 76 print(value1); 77 print(value2); 78 print(value3); 79 print(value4); 80 } 81 82 template<typename T1, typename T2, typename T3, typename T4, typename T5> 83 void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4, const T5& value5) 84 { 85 print(value1); 86 print(value2); 87 print(value3); 88 print(value4); 89 print(value5); 90 } 91 92 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> 93 void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4, const T5& value5, const T6& value6) 94 { 95 print(value1); 96 print(value2); 97 print(value3); 98 print(value4); 99 print(value5); 100 print(value6); 101 } 102 103 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7> 104 void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4, const T5& value5, const T6& value6, const T7& value7) 105 { 106 print(value1); 107 print(value2); 108 print(value3); 109 print(value4); 110 print(value5); 111 print(value6); 112 print(value7); 113 } 114 115 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> 116 void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4, const T5& value5, const T6& value6, const T7& value7, const T8& value8) 117 { 118 print(value1); 119 print(value2); 120 print(value3); 121 print(value4); 122 print(value5); 123 print(value6); 124 print(value7); 125 print(value8); 126 } 127 128 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9> 129 void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4, const T5& value5, const T6& value6, const T7& value7, const T8& value8, const T9& value9) 130 { 131 print(value1); 132 print(value2); 133 print(value3); 134 print(value4); 135 print(value5); 136 print(value6); 137 print(value7); 138 print(value8); 139 print(value9); 140 } 141 142 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10> 143 void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4, const T5& value5, const T6& value6, const T7& value7, const T8& value8, const T9& value9, const T10& value10) 144 { 145 print(value1); 146 print(value2); 147 print(value3); 148 print(value4); 149 print(value5); 150 print(value6); 151 print(value7); 152 print(value8); 153 print(value9); 154 print(value10); 155 } 156 157 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11> 158 void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4, const T5& value5, const T6& value6, const T7& value7, const T8& value8, const T9& value9, const T10& value10, const T11& value11) 159 { 160 print(value1); 161 print(value2); 162 print(value3); 163 print(value4); 164 print(value5); 165 print(value6); 166 print(value7); 167 print(value8); 168 print(value9); 169 print(value10); 170 print(value11); 171 } 172 173 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> 174 void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4, const T5& value5, const T6& value6, const T7& value7, const T8& value8, const T9& value9, const T10& value10, const T11& value11, const T12& value12) 175 { 176 print(value1); 177 print(value2); 178 print(value3); 179 print(value4); 180 print(value5); 181 print(value6); 182 print(value7); 183 print(value8); 184 print(value9); 185 print(value10); 186 print(value11); 187 print(value12); 188 } 189 190 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> 191 void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4, const T5& value5, const T6& value6, const T7& value7, const T8& value8, const T9& value9, const T10& value10, const T11& value11, const T12& value12, const T13& value13) 192 { 193 print(value1); 194 print(value2); 195 print(value3); 196 print(value4); 197 print(value5); 198 print(value6); 199 print(value7); 200 print(value8); 201 print(value9); 202 print(value10); 203 print(value11); 204 print(value12); 205 print(value13); 206 } 207 }; 208 209 void printInternal(PrintStream&, const char*); 210 void printInternal(PrintStream&, const CString&); 211 void printInternal(PrintStream&, const String&); 212 inline void printInternal(PrintStream& out, char* value) { printInternal(out, static_cast<const char*>(value)); } 213 inline void printInternal(PrintStream& out, CString& value) { printInternal(out, static_cast<const CString&>(value)); } 214 inline void printInternal(PrintStream& out, String& value) { printInternal(out, static_cast<const String&>(value)); } 215 void printInternal(PrintStream&, bool); 216 void printInternal(PrintStream&, int); 217 void printInternal(PrintStream&, unsigned); 218 void printInternal(PrintStream&, long); 219 void printInternal(PrintStream&, unsigned long); 220 void printInternal(PrintStream&, long long); 221 void printInternal(PrintStream&, unsigned long long); 222 void printInternal(PrintStream&, float); 223 void printInternal(PrintStream&, double); 224 225 template<typename T> 226 void printInternal(PrintStream& out, const T& value) 227 { 228 value.dump(out); 229 } 230 231 #define MAKE_PRINT_ADAPTOR(Name, Type, function) \ 232 class Name { \ 233 public: \ 234 Name(const Type& value) \ 235 : m_value(value) \ 236 { \ 237 } \ 238 void dump(PrintStream& out) const \ 239 { \ 240 function(out, m_value); \ 241 } \ 242 private: \ 243 Type m_value; \ 244 } 245 246 #define MAKE_PRINT_METHOD_ADAPTOR(Name, Type, method) \ 247 class Name { \ 248 public: \ 249 Name(const Type& value) \ 250 : m_value(value) \ 251 { \ 252 } \ 253 void dump(PrintStream& out) const \ 254 { \ 255 m_value.method(out); \ 256 } \ 257 private: \ 258 const Type& m_value; \ 259 } 260 261 #define MAKE_PRINT_METHOD(Type, dumpMethod, method) \ 262 MAKE_PRINT_METHOD_ADAPTOR(DumperFor_##method, Type, dumpMethod); \ 263 DumperFor_##method method() const { return DumperFor_##method(*this); } 264 265 // Use an adaptor-based dumper for characters to avoid situations where 266 // you've "compressed" an integer to a character and it ends up printing 267 // as ASCII when you wanted it to print as a number. 268 void dumpCharacter(PrintStream&, char); 269 MAKE_PRINT_ADAPTOR(CharacterDump, char, dumpCharacter); 270 271 template<typename T> 272 class PointerDump { 273 public: 274 PointerDump(const T* ptr) 275 : m_ptr(ptr) 276 { 277 } 278 279 void dump(PrintStream& out) const 280 { 281 if (m_ptr) 282 printInternal(out, *m_ptr); 283 else 284 out.print("(null)"); 285 } 286 private: 287 const T* m_ptr; 288 }; 289 290 template<typename T> 291 PointerDump<T> pointerDump(const T* ptr) { return PointerDump<T>(ptr); } 292 293 } // namespace WTF 294 295 using WTF::CharacterDump; 296 using WTF::PointerDump; 297 using WTF::PrintStream; 298 using WTF::pointerDump; 299 300 #endif // PrintStream_h 301 302