Get rid of FastAllocBase.h
[WebKit-https.git] / Source / WTF / wtf / PrintStream.h
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/FastMalloc.h>
31 #include <wtf/Noncopyable.h>
32 #include <wtf/Platform.h>
33 #include <wtf/RawPointer.h>
34 #include <wtf/StdLibExtras.h>
35
36 namespace WTF {
37
38 class CString;
39 class String;
40 class StringImpl;
41
42 class PrintStream {
43     WTF_MAKE_FAST_ALLOCATED; WTF_MAKE_NONCOPYABLE(PrintStream);
44 public:
45     PrintStream();
46     virtual ~PrintStream();
47
48     WTF_EXPORT_PRIVATE void printf(const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3);
49     virtual void vprintf(const char* format, va_list) WTF_ATTRIBUTE_PRINTF(2, 0) = 0;
50
51     // Typically a no-op for many subclasses of PrintStream, this is a hint that
52     // the implementation should flush its buffers if it had not done so already.
53     virtual void flush();
54     
55     template<typename T>
56     void print(const T& value)
57     {
58         printInternal(*this, value);
59     }
60     
61     template<typename T1, typename T2>
62     void print(const T1& value1, const T2& value2)
63     {
64         print(value1);
65         print(value2);
66     }
67     
68     template<typename T1, typename T2, typename T3>
69     void print(const T1& value1, const T2& value2, const T3& value3)
70     {
71         print(value1);
72         print(value2);
73         print(value3);
74     }
75     
76     template<typename T1, typename T2, typename T3, typename T4>
77     void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
78     {
79         print(value1);
80         print(value2);
81         print(value3);
82         print(value4);
83     }
84     
85     template<typename T1, typename T2, typename T3, typename T4, typename T5>
86     void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4, const T5& value5)
87     {
88         print(value1);
89         print(value2);
90         print(value3);
91         print(value4);
92         print(value5);
93     }
94     
95     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
96     void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4, const T5& value5, const T6& value6)
97     {
98         print(value1);
99         print(value2);
100         print(value3);
101         print(value4);
102         print(value5);
103         print(value6);
104     }
105     
106     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
107     void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4, const T5& value5, const T6& value6, const T7& value7)
108     {
109         print(value1);
110         print(value2);
111         print(value3);
112         print(value4);
113         print(value5);
114         print(value6);
115         print(value7);
116     }
117     
118     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
119     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)
120     {
121         print(value1);
122         print(value2);
123         print(value3);
124         print(value4);
125         print(value5);
126         print(value6);
127         print(value7);
128         print(value8);
129     }
130     
131     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
132     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)
133     {
134         print(value1);
135         print(value2);
136         print(value3);
137         print(value4);
138         print(value5);
139         print(value6);
140         print(value7);
141         print(value8);
142         print(value9);
143     }
144     
145     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
146     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)
147     {
148         print(value1);
149         print(value2);
150         print(value3);
151         print(value4);
152         print(value5);
153         print(value6);
154         print(value7);
155         print(value8);
156         print(value9);
157         print(value10);
158     }
159     
160     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11>
161     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)
162     {
163         print(value1);
164         print(value2);
165         print(value3);
166         print(value4);
167         print(value5);
168         print(value6);
169         print(value7);
170         print(value8);
171         print(value9);
172         print(value10);
173         print(value11);
174     }
175     
176     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>
177     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)
178     {
179         print(value1);
180         print(value2);
181         print(value3);
182         print(value4);
183         print(value5);
184         print(value6);
185         print(value7);
186         print(value8);
187         print(value9);
188         print(value10);
189         print(value11);
190         print(value12);
191     }
192     
193     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>
194     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)
195     {
196         print(value1);
197         print(value2);
198         print(value3);
199         print(value4);
200         print(value5);
201         print(value6);
202         print(value7);
203         print(value8);
204         print(value9);
205         print(value10);
206         print(value11);
207         print(value12);
208         print(value13);
209     }
210     
211     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, typename T14>
212     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, const T14& value14)
213     {
214         print(value1);
215         print(value2);
216         print(value3);
217         print(value4);
218         print(value5);
219         print(value6);
220         print(value7);
221         print(value8);
222         print(value9);
223         print(value10);
224         print(value11);
225         print(value12);
226         print(value13);
227         print(value14);
228     }
229     
230     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, typename T14, typename T15>
231     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, const T14& value14, const T15& value15)
232     {
233         print(value1);
234         print(value2);
235         print(value3);
236         print(value4);
237         print(value5);
238         print(value6);
239         print(value7);
240         print(value8);
241         print(value9);
242         print(value10);
243         print(value11);
244         print(value12);
245         print(value13);
246         print(value14);
247         print(value15);
248     }
249 };
250
251 WTF_EXPORT_PRIVATE void printInternal(PrintStream&, const char*);
252 WTF_EXPORT_PRIVATE void printInternal(PrintStream&, const CString&);
253 WTF_EXPORT_PRIVATE void printInternal(PrintStream&, const String&);
254 WTF_EXPORT_PRIVATE void printInternal(PrintStream&, const StringImpl*);
255 inline void printInternal(PrintStream& out, char* value) { printInternal(out, static_cast<const char*>(value)); }
256 inline void printInternal(PrintStream& out, CString& value) { printInternal(out, static_cast<const CString&>(value)); }
257 inline void printInternal(PrintStream& out, String& value) { printInternal(out, static_cast<const String&>(value)); }
258 inline void printInternal(PrintStream& out, StringImpl* value) { printInternal(out, static_cast<const StringImpl*>(value)); }
259 WTF_EXPORT_PRIVATE void printInternal(PrintStream&, bool);
260 WTF_EXPORT_PRIVATE void printInternal(PrintStream&, int);
261 WTF_EXPORT_PRIVATE void printInternal(PrintStream&, unsigned);
262 WTF_EXPORT_PRIVATE void printInternal(PrintStream&, long);
263 WTF_EXPORT_PRIVATE void printInternal(PrintStream&, unsigned long);
264 WTF_EXPORT_PRIVATE void printInternal(PrintStream&, long long);
265 WTF_EXPORT_PRIVATE void printInternal(PrintStream&, unsigned long long);
266 WTF_EXPORT_PRIVATE void printInternal(PrintStream&, float);
267 WTF_EXPORT_PRIVATE void printInternal(PrintStream&, double);
268 WTF_EXPORT_PRIVATE void printInternal(PrintStream&, RawPointer);
269
270 template<typename T>
271 void printInternal(PrintStream& out, const T& value)
272 {
273     value.dump(out);
274 }
275
276 #define MAKE_PRINT_ADAPTOR(Name, Type, function) \
277     class Name {                                 \
278     public:                                      \
279         Name(const Type& value)                  \
280             : m_value(value)                     \
281         {                                        \
282         }                                        \
283         void dump(PrintStream& out) const        \
284         {                                        \
285             function(out, m_value);              \
286         }                                        \
287     private:                                     \
288         Type m_value;                            \
289     }
290
291 #define MAKE_PRINT_METHOD_ADAPTOR(Name, Type, method) \
292     class Name {                                 \
293     public:                                      \
294         Name(const Type& value)                  \
295             : m_value(value)                     \
296         {                                        \
297         }                                        \
298         void dump(PrintStream& out) const        \
299         {                                        \
300             m_value.method(out);                 \
301         }                                        \
302     private:                                     \
303         const Type& m_value;                     \
304     }
305
306 #define MAKE_PRINT_METHOD(Type, dumpMethod, method) \
307     MAKE_PRINT_METHOD_ADAPTOR(DumperFor_##method, Type, dumpMethod);    \
308     DumperFor_##method method() const { return DumperFor_##method(*this); }
309
310 // Use an adaptor-based dumper for characters to avoid situations where
311 // you've "compressed" an integer to a character and it ends up printing
312 // as ASCII when you wanted it to print as a number.
313 WTF_EXPORT_PRIVATE void dumpCharacter(PrintStream&, char);
314 MAKE_PRINT_ADAPTOR(CharacterDump, char, dumpCharacter);
315
316 template<typename T>
317 class PointerDump {
318 public:
319     PointerDump(const T* ptr)
320         : m_ptr(ptr)
321     {
322     }
323     
324     void dump(PrintStream& out) const
325     {
326         if (m_ptr)
327             printInternal(out, *m_ptr);
328         else
329             out.print("(null)");
330     }
331 private:
332     const T* m_ptr;
333 };
334
335 template<typename T>
336 PointerDump<T> pointerDump(const T* ptr) { return PointerDump<T>(ptr); }
337
338 template<typename T, typename U>
339 class ValueInContext {
340 public:
341     ValueInContext(const T& value, U* context)
342         : m_value(&value)
343         , m_context(context)
344     {
345     }
346     
347     void dump(PrintStream& out) const
348     {
349         m_value->dumpInContext(out, m_context);
350     }
351
352 private:
353     const T* m_value;
354     U* m_context;
355 };
356
357 template<typename T, typename U>
358 ValueInContext<T, U> inContext(const T& value, U* context)
359 {
360     return ValueInContext<T, U>(value, context);
361 }
362
363 } // namespace WTF
364
365 using WTF::CharacterDump;
366 using WTF::PointerDump;
367 using WTF::PrintStream;
368 using WTF::inContext;
369 using WTF::pointerDump;
370
371 #endif // PrintStream_h
372