Rationalize closure call heuristics and profiling
[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/FastAllocBase.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
41 class PrintStream {
42     WTF_MAKE_FAST_ALLOCATED; WTF_MAKE_NONCOPYABLE(PrintStream);
43 public:
44     PrintStream();
45     virtual ~PrintStream();
46
47     void printf(const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3);
48     virtual void vprintf(const char* format, va_list) WTF_ATTRIBUTE_PRINTF(2, 0) = 0;
49
50     // Typically a no-op for many subclasses of PrintStream, this is a hint that
51     // the implementation should flush its buffers if it had not done so already.
52     virtual void flush();
53     
54     template<typename T>
55     void print(const T& value)
56     {
57         printInternal(*this, value);
58     }
59     
60     template<typename T1, typename T2>
61     void print(const T1& value1, const T2& value2)
62     {
63         print(value1);
64         print(value2);
65     }
66     
67     template<typename T1, typename T2, typename T3>
68     void print(const T1& value1, const T2& value2, const T3& value3)
69     {
70         print(value1);
71         print(value2);
72         print(value3);
73     }
74     
75     template<typename T1, typename T2, typename T3, typename T4>
76     void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
77     {
78         print(value1);
79         print(value2);
80         print(value3);
81         print(value4);
82     }
83     
84     template<typename T1, typename T2, typename T3, typename T4, typename T5>
85     void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4, const T5& value5)
86     {
87         print(value1);
88         print(value2);
89         print(value3);
90         print(value4);
91         print(value5);
92     }
93     
94     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
95     void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4, const T5& value5, const T6& value6)
96     {
97         print(value1);
98         print(value2);
99         print(value3);
100         print(value4);
101         print(value5);
102         print(value6);
103     }
104     
105     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
106     void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4, const T5& value5, const T6& value6, const T7& value7)
107     {
108         print(value1);
109         print(value2);
110         print(value3);
111         print(value4);
112         print(value5);
113         print(value6);
114         print(value7);
115     }
116     
117     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
118     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)
119     {
120         print(value1);
121         print(value2);
122         print(value3);
123         print(value4);
124         print(value5);
125         print(value6);
126         print(value7);
127         print(value8);
128     }
129     
130     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
131     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)
132     {
133         print(value1);
134         print(value2);
135         print(value3);
136         print(value4);
137         print(value5);
138         print(value6);
139         print(value7);
140         print(value8);
141         print(value9);
142     }
143     
144     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
145     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)
146     {
147         print(value1);
148         print(value2);
149         print(value3);
150         print(value4);
151         print(value5);
152         print(value6);
153         print(value7);
154         print(value8);
155         print(value9);
156         print(value10);
157     }
158     
159     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11>
160     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)
161     {
162         print(value1);
163         print(value2);
164         print(value3);
165         print(value4);
166         print(value5);
167         print(value6);
168         print(value7);
169         print(value8);
170         print(value9);
171         print(value10);
172         print(value11);
173     }
174     
175     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>
176     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)
177     {
178         print(value1);
179         print(value2);
180         print(value3);
181         print(value4);
182         print(value5);
183         print(value6);
184         print(value7);
185         print(value8);
186         print(value9);
187         print(value10);
188         print(value11);
189         print(value12);
190     }
191     
192     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>
193     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)
194     {
195         print(value1);
196         print(value2);
197         print(value3);
198         print(value4);
199         print(value5);
200         print(value6);
201         print(value7);
202         print(value8);
203         print(value9);
204         print(value10);
205         print(value11);
206         print(value12);
207         print(value13);
208     }
209 };
210
211 void printInternal(PrintStream&, const char*);
212 void printInternal(PrintStream&, const CString&);
213 void printInternal(PrintStream&, const String&);
214 inline void printInternal(PrintStream& out, char* value) { printInternal(out, static_cast<const char*>(value)); }
215 inline void printInternal(PrintStream& out, CString& value) { printInternal(out, static_cast<const CString&>(value)); }
216 inline void printInternal(PrintStream& out, String& value) { printInternal(out, static_cast<const String&>(value)); }
217 void printInternal(PrintStream&, bool);
218 void printInternal(PrintStream&, int);
219 void printInternal(PrintStream&, unsigned);
220 void printInternal(PrintStream&, long);
221 void printInternal(PrintStream&, unsigned long);
222 void printInternal(PrintStream&, long long);
223 void printInternal(PrintStream&, unsigned long long);
224 void printInternal(PrintStream&, float);
225 void printInternal(PrintStream&, double);
226 void printInternal(PrintStream&, RawPointer);
227
228 template<typename T>
229 void printInternal(PrintStream& out, const T& value)
230 {
231     value.dump(out);
232 }
233
234 #define MAKE_PRINT_ADAPTOR(Name, Type, function) \
235     class Name {                                 \
236     public:                                      \
237         Name(const Type& value)                  \
238             : m_value(value)                     \
239         {                                        \
240         }                                        \
241         void dump(PrintStream& out) const        \
242         {                                        \
243             function(out, m_value);              \
244         }                                        \
245     private:                                     \
246         Type m_value;                            \
247     }
248
249 #define MAKE_PRINT_METHOD_ADAPTOR(Name, Type, method) \
250     class Name {                                 \
251     public:                                      \
252         Name(const Type& value)                  \
253             : m_value(value)                     \
254         {                                        \
255         }                                        \
256         void dump(PrintStream& out) const        \
257         {                                        \
258             m_value.method(out);                 \
259         }                                        \
260     private:                                     \
261         const Type& m_value;                     \
262     }
263
264 #define MAKE_PRINT_METHOD(Type, dumpMethod, method) \
265     MAKE_PRINT_METHOD_ADAPTOR(DumperFor_##method, Type, dumpMethod);    \
266     DumperFor_##method method() const { return DumperFor_##method(*this); }
267
268 // Use an adaptor-based dumper for characters to avoid situations where
269 // you've "compressed" an integer to a character and it ends up printing
270 // as ASCII when you wanted it to print as a number.
271 void dumpCharacter(PrintStream&, char);
272 MAKE_PRINT_ADAPTOR(CharacterDump, char, dumpCharacter);
273
274 template<typename T>
275 class PointerDump {
276 public:
277     PointerDump(const T* ptr)
278         : m_ptr(ptr)
279     {
280     }
281     
282     void dump(PrintStream& out) const
283     {
284         if (m_ptr)
285             printInternal(out, *m_ptr);
286         else
287             out.print("(null)");
288     }
289 private:
290     const T* m_ptr;
291 };
292
293 template<typename T>
294 PointerDump<T> pointerDump(const T* ptr) { return PointerDump<T>(ptr); }
295
296 } // namespace WTF
297
298 using WTF::CharacterDump;
299 using WTF::PointerDump;
300 using WTF::PrintStream;
301 using WTF::pointerDump;
302
303 #endif // PrintStream_h
304