1 // $Header$ 2 // 3 // Copyright (C) 2000 - 2004, by 4 // 5 // Carlo Wood, Run on IRC <carlo@alinoe.com> 6 // RSA-1024 0x624ACAD5 1997-01-26 Sign & Encrypt 7 // Fingerprint16 = 32 EC A7 B6 AC DB 65 A6 F6 F6 55 DD 1C DC FF 61 8 // 9 // This file may be distributed under the terms of the Q Public License 10 // version 1.0 as appearing in the file LICENSE.QPL included in the 11 // packaging of this file. 12 // 13 14 /** \file libcwd/cwprint.h 15 * 16 * \brief Definition of the utilities cwprint and cwprint_using. 17 * 18 * This header file provides the declaration and definition of two debug utility functions, 19 * intended to print objects to an ostream without using the \c operator<< inserter for 20 * that class, if any. 21 * 22 * \sa libcwd::cwprint 23 * \n libcwd::cwprint_using 24 */ 25 26 #ifndef LIBCWD_CWPRINT_H 27 #define LIBCWD_CWPRINT_H 28 29 namespace libcwd { 30 31 //=================================================================================================== 32 // cwprint 33 // 34 35 template<class PRINTABLE_OBJECT> 36 class cwprint_tct { 37 private: 38 PRINTABLE_OBJECT const& M_printable_object; 39 public: cwprint_tct(PRINTABLE_OBJECT const & printable_object)40 cwprint_tct(PRINTABLE_OBJECT const& printable_object) : M_printable_object(printable_object) { } 41 42 friend 43 inline // Must be defined inside the class declaration in order to avoid a compiler warning. 44 std::ostream& 45 operator<<(std::ostream& os, cwprint_tct<PRINTABLE_OBJECT> const& __cwprint) 46 { 47 __cwprint.M_printable_object.print_on(os); 48 return os; 49 } 50 }; 51 52 /** 53 * \interface libcwd::cwprint cwprint.h libcwd/cwprint.h 54 * \ingroup group_special 55 * 56 * \brief Print an object to a %debug stream without needing an operator<<. 57 * 58 * This utility can be used to print an object to a %debug stream without using 59 * the normal \c operator<< of that object (if any exists at all). 60 * The purpose is to allow the printing of objects to %debug streams in a \e different 61 * way then when you'd normally print them to say <CODE>std::cout</CODE>. 62 * 63 * The \a printable_object (see example below) must have the signature: 64 * 65 * \code 66 * class Class { 67 * ... 68 * public: 69 * void print_on(std::ostream& os) const; 70 * }; 71 * \endcode 72 * 73 * \sa cwprint_using 74 * 75 * <b>Example:</b> 76 * 77 * \code 78 * Dout( dc::channel, cwprint(printable_object) ); 79 * \endcode 80 * 81 * this will write \a printable_object to the %debug stream by 82 * calling the method \c print_on. 83 */ 84 85 template<class T> 86 inline 87 cwprint_tct<T> cwprint(T const & printable_object)88 cwprint(T const& printable_object) 89 { 90 return cwprint_tct<T>(printable_object); 91 } 92 93 //=================================================================================================== 94 // cwprint_using 95 // 96 97 template<class PRINTABLE_OBJECT> 98 class cwprint_using_tct { 99 typedef void (PRINTABLE_OBJECT::* print_on_method_t)(std::ostream&) const; 100 private: 101 PRINTABLE_OBJECT const& M_printable_object; 102 print_on_method_t M_print_on_method; 103 public: cwprint_using_tct(PRINTABLE_OBJECT const & printable_object,print_on_method_t print_on_method)104 cwprint_using_tct(PRINTABLE_OBJECT const& printable_object, print_on_method_t print_on_method) : 105 M_printable_object(printable_object), M_print_on_method(print_on_method) { } 106 107 friend 108 inline // Must be defined inside the class declaration in order to avoid a compiler warning. 109 std::ostream& 110 operator<<(std::ostream& os, cwprint_using_tct<PRINTABLE_OBJECT> __cwprint_using) 111 { 112 (__cwprint_using.M_printable_object.*__cwprint_using.M_print_on_method)(os); 113 return os; 114 } 115 }; 116 117 /** 118 * \interface libcwd::cwprint_using cwprint.h libcwd/cwprint.h 119 * \ingroup group_special 120 * 121 * \brief Print an object to an ostream using an arbitrary method of that object. 122 * 123 * This utility can be used to print an object to a %debug stream without using 124 * the normal \c operator<< of that object (if any exists at all). 125 * The purpose is to allow the printing of objects to %debug streams in a \e different 126 * way then when you'd normally print them to say <CODE>std::cout</CODE>. 127 * 128 * The \a object (see example below) must have the signature: 129 * 130 * \code 131 * class Class { 132 * ... 133 * public: 134 * void arbitrary_method_name(std::ostream& os) const; 135 * }; 136 * \endcode 137 * 138 * \sa cwprint 139 * 140 * <b>Example:</b> 141 * 142 * \code 143 * Dout( dc::channel, cwprint_using(object, &Class::arbitrary_method_name) ); 144 * \endcode 145 * 146 * this will write \a object to the %debug stream by 147 * calling the method \a arbitrary_method_name. 148 */ 149 150 // The use of T_OR_BASE_OF_T as extra parameter is a compiler bug around. 151 // Without it you'd run into bug 152 // http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=38 153 // when `print_on_method' is a method of the base class of T. 154 155 template<class T, class T_OR_BASE_OF_T> 156 inline 157 cwprint_using_tct<T_OR_BASE_OF_T> cwprint_using(T const & printable_object,void (T_OR_BASE_OF_T::* print_on_method)(std::ostream &)const)158 cwprint_using(T const& printable_object, void (T_OR_BASE_OF_T::*print_on_method)(std::ostream&) const) 159 { 160 T_OR_BASE_OF_T const& base(printable_object); 161 return cwprint_using_tct<T_OR_BASE_OF_T>(base, print_on_method); 162 } 163 164 } // namespace libcwd 165 166 #endif // LIBCWD_CWPRINT_H 167