Home | History | Annotate | Download | only in wtf
      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